gpt4 book ai didi

javascript - 为什么在函数内创建同名变量时函数参数没有被覆盖?

转载 作者:行者123 更新时间:2023-12-03 03:01:41 26 4
gpt4 key购买 nike

var a = 'why is this not undefined?';
function checkScope(a) {
var a;
console.log(a);
}
checkScope(a);

Javascript 是函数式作用域语言,对吧?当我在函数内部声明一个与函数参数同名的新变量时,为什么新定义的变量仍然保存与参数相同的数据?

我认为它应该是未定义的?

最佳答案

var a; 实际上是一个变量声明语句。定义函数时,其中声明的所有变量都会在代码执行之前进行处理,因此您甚至可以在运行时执行实际声明行之前使用这些变量。这称为var hoisting 。因此,无论声明多少次变量,该变量实际上只声明一次。

就您而言,您已将 a 定义为函数的参数之一,其作用域为当前函数。然后你声明一个同名的变量。由于 a 已在函数中声明为参数之一,因此 var a; 声明将被忽略。

这就是为什么您会在控制台中看到why is this not undefined?

假设您有 var a = 1;,而不是 var a;,在这种情况下,变量已被声明,但赋值表达式将在运行时进行评估,并且值1将被分配给a。因此,console.log 将打印 1

<小时/>

ECMA Script 5.1 规范的 10.5 Declaration Binding Instantiation 部分对此行为进行了解释。 ,

  1. If code is function code, then

    a. Let func be the function whose [[Call]] internal method initiated execution of code. Let names be the value of func’s [[FormalParameters]] internal property.

    b. Let argCount be the number of elements in args.

    c. Let n be the number 0.

    d. For each String argName in names, in list order do

          i. Let n be the current value of n plus 1.

          ii. If n is greater than argCount, let v be undefined otherwise let v be the value of the n’th element of args.

          iii. Let argAlreadyDeclared be the result of calling env’s HasBinding concrete method passing argName as the argument.

          iv. If argAlreadyDeclared is false, call env’s CreateMutableBinding concrete method passing argName as the argument.

          v. Call env’s SetMutableBinding concrete method passing argName, v, and strict as the arguments.

...

  1. For each VariableDeclaration and VariableDeclarationNoIn d in code, in source text order do

    a. Let dn be the Identifier in d.

    b. Let varAlreadyDeclared be the result of calling env’s HasBinding concrete method passing dn as the argument.

    c. If varAlreadyDeclared is false, then

          i. Call env’s CreateMutableBinding concrete method passing dn and configurableBindings as the arguments.

          ii. Call env’s SetMutableBinding concrete method passing dn, undefined, and strict as the arguments.

正如我们在规范中看到的,函数中声明的参数和变量实际上都是在与定义它们的函数对应的执行环境中定义的。因此,如果参数和变量具有相同的名称,则该变量实际上只定义一次,并且第二次声明将被忽略。

关于javascript - 为什么在函数内创建同名变量时函数参数没有被覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27963214/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com