..if 语句中未声明的变量不会引发错误
Undeclared variables in an ..if statement doesn't throw an error
我刚刚注意到 Javascript 中有一些奇怪的行为。为了编写简短的代码,我想到了以下函数:
if(a = 'A|B|C'.split('|'), a.length > 1){
// I have access to a, but it was never declared as a variable?
} else {
// some code
}
// I still have access to 'a' over here?
我预计代码会抛出一些关于 a
未被声明的错误,但显然,它将 'A|B|C'.split('|')
的值分配给它,并且使用逗号,我可以使用 a
作为一个普通的声明变量。
此外,该变量存在于 if
语句之外,我可以在下面的代码中访问它。
另一件事,显式设置变量:
if(let a = 'A|B|C'.split('|'), a.length > 1)
抛出错误。这与 for, for ..in
循环不同,您必须在使用变量之前声明变量。
谁能解释一下这是怎么回事?
事实上a
当你只是给它赋值时就被声明为一个全局变量。它将系统地声明为全局 window
对象的一部分。
如果你看一下 the MDN var
reference 你会发现:
Assigning a value to an undeclared variable implicitly creates it as a global variable (it becomes a property of the global object) when the assignment is executed.
这就是为什么您共享的代码可以完美运行,并且不会引发任何错误。
一般情况下,JS不会对未声明但已赋值的变量抛出错误。
Assigning a value to an undeclared variable implicitly creates it as a global variable (it becomes a property of the global object) when the assignment is executed.
如果您想遇到此类错误,请在函数顶部使用 "use strict";
行以严格模式添加脚本。
"use strict"; Defines that JavaScript code should be executed in "strict mode". With strict mode, you can not, for example, use undeclared variables.
这是您提供的代码,没有抛出错误:
if(a = 'A|B|C'.split('|'), a.length > 1){
// I have access to a, but it was never declared as a variable?
} else {
// some code
}
console.log(a);
这是我刚刚在顶部添加严格指令的代码,它开始抛出错误。
"use strict";
if(a = 'A|B|C'.split('|'), a.length > 1){
// I have access to a, but it was never declared as a variable?
} else {
// some code
}
这里发生了很多事情。将尝试解释它们中的每一个。
首先,在下一行中有多个用逗号分隔的表达式。在 JS 中,每个表达式都是从左到右计算的,最后一个表达式被返回。所以基本上这将按如下方式工作
if(a = 'A|B|C'.split('|'), a.length > 1){ // evaluate 'A|B|C'.split('|') and assign the value to a variable 'a' if it exists. Otherwise create a new global variable 'a' and assign the value.
将转换为
if(a,a.length > 1) // a gets assigned a value which
// here is an array consisting of 3 elements.["A","B","C"].
将转换为
if(["A","B","C"], ["A","B","C"].length > 1)
将转换为
if(true) // comma separated expression always
// returns the last expression's value which here would be true since a.length is 3
因此你总是会得到 if 块代码 运行。
你说的第二个问题是因为不能在if块里面写语句。使用 var/let 基本上是一个声明。请记住,您可以在 if 条件中编写表达式。
我刚刚注意到 Javascript 中有一些奇怪的行为。为了编写简短的代码,我想到了以下函数:
if(a = 'A|B|C'.split('|'), a.length > 1){
// I have access to a, but it was never declared as a variable?
} else {
// some code
}
// I still have access to 'a' over here?
我预计代码会抛出一些关于 a
未被声明的错误,但显然,它将 'A|B|C'.split('|')
的值分配给它,并且使用逗号,我可以使用 a
作为一个普通的声明变量。
此外,该变量存在于 if
语句之外,我可以在下面的代码中访问它。
另一件事,显式设置变量:
if(let a = 'A|B|C'.split('|'), a.length > 1)
抛出错误。这与 for, for ..in
循环不同,您必须在使用变量之前声明变量。
谁能解释一下这是怎么回事?
事实上a
当你只是给它赋值时就被声明为一个全局变量。它将系统地声明为全局 window
对象的一部分。
如果你看一下 the MDN var
reference 你会发现:
Assigning a value to an undeclared variable implicitly creates it as a global variable (it becomes a property of the global object) when the assignment is executed.
这就是为什么您共享的代码可以完美运行,并且不会引发任何错误。
一般情况下,JS不会对未声明但已赋值的变量抛出错误。
Assigning a value to an undeclared variable implicitly creates it as a global variable (it becomes a property of the global object) when the assignment is executed.
如果您想遇到此类错误,请在函数顶部使用 "use strict";
行以严格模式添加脚本。
"use strict"; Defines that JavaScript code should be executed in "strict mode". With strict mode, you can not, for example, use undeclared variables.
这是您提供的代码,没有抛出错误:
if(a = 'A|B|C'.split('|'), a.length > 1){
// I have access to a, but it was never declared as a variable?
} else {
// some code
}
console.log(a);
这是我刚刚在顶部添加严格指令的代码,它开始抛出错误。
"use strict";
if(a = 'A|B|C'.split('|'), a.length > 1){
// I have access to a, but it was never declared as a variable?
} else {
// some code
}
这里发生了很多事情。将尝试解释它们中的每一个。
首先,在下一行中有多个用逗号分隔的表达式。在 JS 中,每个表达式都是从左到右计算的,最后一个表达式被返回。所以基本上这将按如下方式工作
if(a = 'A|B|C'.split('|'), a.length > 1){ // evaluate 'A|B|C'.split('|') and assign the value to a variable 'a' if it exists. Otherwise create a new global variable 'a' and assign the value.
将转换为
if(a,a.length > 1) // a gets assigned a value which
// here is an array consisting of 3 elements.["A","B","C"].
将转换为
if(["A","B","C"], ["A","B","C"].length > 1)
将转换为
if(true) // comma separated expression always
// returns the last expression's value which here would be true since a.length is 3
因此你总是会得到 if 块代码 运行。
你说的第二个问题是因为不能在if块里面写语句。使用 var/let 基本上是一个声明。请记住,您可以在 if 条件中编写表达式。