我刚刚注意到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
循环不同,后者必须在使用变量之前声明它们。
有人可以解释它的有效性吗?
答案 0 :(得分:3)
实际上,a
只是在您为其分配值时就声明为全局变量。系统会将其声明为全局window
对象的一部分。
如果您查看 the MDN var
reference ,您会看到:
在执行分配时,将值分配给未声明的变量会隐式将其创建为全局变量(它成为全局对象的属性)。
这就是为什么您共享的代码运行正常,并且不会引发任何错误的原因。
答案 1 :(得分:1)
通常,JS不会对未声明的变量抛出错误,但会为其分配值。
在执行分配时,将值分配给未声明的变量会隐式将其创建为全局变量(它成为全局对象的属性)。
如果您想获取此类错误,请使用函数顶部的"use strict";
行以严格模式添加脚本。
“使用严格”;定义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
}
console.log(a);
这是我仅在顶部添加strict指令的代码,它开始引发错误。
"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
}
答案 2 :(得分:1)
这里发生了很多事情。将尝试解释它们中的每一个。
首先,在下面的行中,您有多个用逗号分隔的表达式。在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基本上是一个声明。请记住,如果条件允许,您可以在内部编写表达式。