[英]Declaring a Javascript variable twice in same scope - Is it an issue?
以下代码会导致任何问题吗?:
var a = 1;
var a = 2;
我的理解是 javascript 变量是在作用域的开始处声明的。 例如:
var foo = 'a';
foo = 'b';
var bar = 'c';
处理为:
var foo;
var bar;
foo = 'a';
foo = 'b';
bar = 'c';
因此,我的初始代码片段会变成:
var a;
a = 1;
a = 2;
或者它会变成:
var a;
var a;
a = 1;
a = 2;
我知道在同一范围内两次声明一个 javascript 变量并不是一个好习惯,但我对这样做的影响更感兴趣。
正如您所说,通过两次以上相同的 var,JavaScript 将该声明移动到范围的顶部,然后您的代码将变成这样:
var a;
a = 1;
a = 2;
因此,它不会给我们任何错误。
同样的行为发生在for
循环中(它们的标头中没有局部作用域),所以下面的代码非常常见:
for (var i = 0; i < n; i++) {
// ...
}
for (var i = 0; i < m; i++) {
// ...
}
这就是为什么像Douglas Crockford这样的 JavaScript 专家建议程序员手动将这些声明移到作用域的顶部:
var i; // declare here
for (i = 0; i < n; i++) { // initialize here...
// ...
}
for (i = 0; i < m; i++) { // ... and here
// ...
}
两次声明同一个变量与声明一次一样好。 以下声明不会带来任何影响。
var a, a;
在下面的情况下,您只是覆盖了变量 foo。 如果您在本地和全局范围内定义了 foo,这将产生影响。 JS 会先在局部范围内搜索 foo ,如果没有找到就会在全局范围内查找。
var foo;
var bar;
foo = 'a';
foo = 'b';
bar = 'c';
让我们尝试转录ECMAScript® 2021 语言规范所说的内容。
首先,根据JavaScript:Understanding the Weird Parts有运行代码的两个阶段:创建阶段和执行阶段。 从概念上讲,这就像代码被处理两次(不执行,处理)。
对于var a = 5;
声明这正在发生:
现在ECMAScript® 2021 语言规范的14.3.2 变量语句部分说明了这一点
var语句声明了作用域为正在运行的执行上下文的VariableEnvironment的变量。 Var 变量在包含环境记录的实例化时创建,并在创建时初始化为未定义。 在任何VariableEnvironment的范围内,一个公共BindingIdentifier可能出现在多个VariableDeclaration 中,但这些声明共同定义了一个变量。 由带有Initializer的VariableDeclaration定义的变量在执行 VariableDeclaration 时被分配其 Initializer 的AssignmentExpression值,而不是在创建变量时。
让我们一行一行地检查它。
在任何VariableEnvironment的范围内,一个公共的BindingIdentifier可能出现在多个VariableDeclaration 中
在这种情况下BindingIdentifier只是一个标识符。 声明意味着这些语法是正式允许的。
var a;
var a;
var a = 1;
var a = 2;
var a, a;
var a = 1, a = 2;
但是这些声明共同定义了一个变量
直接说是同一个变量,只分配了一块内存。
从概念上讲,您可能会认为,如果在创建阶段带有identifier
变量( a是我们的例子)已经创建,它的创建将被跳过(前面的语句已经分配了内存并将未定义的设置放入其中)。
由VariableDeclaration与初始化程序中定义的变量被分配在执行VariableDeclaration其初始化器的AssignmentExpression的值,而不是当在创建可变
只是进一步强调此语句的赋值(发生在执行阶段)和变量创建(发生在创建阶段)之间的区别
var a = 5;
现在让我们总结一下我们所知道的。 规范正式支持此语法。 这意味着只创建一个变量(一个内存位置来保存值)
var a = 1;
var a = 2;
它与吊装无关。 吊装仍在照常进行。
console.log(a) // this is undefined
var a = 1;
var a = 2;
分配将在执行阶段逐行进行,更改相同内存位置的值。
console.log(a) // undefined
var a = 1;
console.log(a) // 1
var a = 2;
console.log(a) // 2
由于 javascript 的变量提升功能,这样的重复变量声明不会导致任何问题。 所以在你的 DOM 中,无论你在哪里声明了变量但分配(或)未分配,它们将在编译期间放置在顶部。
Example:
var foo='hai!';
bar='welcome!';
var bar;
您可能期望上面的代码片段应该抛出“未识别”错误,但 javascript 仍然通过将 bar 变量的声明放在顶部来管理它。 因此,即使在变量声明之前,它的值也可以分配,而不是其他语言。
希望这能在一定程度上帮助你
如果您两次初始化同一个变量,控制台上将不会出现错误,但如果您正在处理某个应用程序(例如猜我的数字)并希望将所有元素重置为初始状态。 所有元素都将被设置为初始状态,但被初始化两次的变量将仅坚持其修改后的值。 例如,如果初始分数是 20,然后修改为某个数字 15,现在按下重置按钮以将值设置为初始值,但不会。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.