..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 条件中编写表达式。