为什么常规赋值语句(比如, x = 5
)返回赋值(5
在这种情况下),而赋值与变量声明(var x = 5
)结合返回undefined
?
我通过在 Chrome 浏览器的 Javascript 控制台中执行这些语句获得了返回值:
> var x = 5;
undefined
> y = 5;
5
为什么常规赋值语句(比如, x = 5
)返回赋值(5
在这种情况下),而赋值与变量声明(var x = 5
)结合返回undefined
?
我通过在 Chrome 浏览器的 Javascript 控制台中执行这些语句获得了返回值:
> var x = 5;
undefined
> y = 5;
5
这就是语言的设计方式。它与大多数语言一致。
有一个变量声明返回任何东西undefined
都是没有意义的,因为你永远不能var
在表达式上下文中使用关键字。
当您想一次将许多变量设置为相同的值时,将赋值expression
不是 astatement
很有用:
x = y = z = 2;
它也可以这样使用:
x = 2*(y = z); // Set y = z, and x = 2*z
然而,这不是最可读的代码,它可能会更好地写成:
y = z;
x = 2*z;
那是因为var x = 5;
是变量语句,而不是表达式。
该语句的行为在 ECMAScript 语言参考的第 12.2 节中描述。
- 评估变量声明列表。
- 返回(正常、空、空)。
这基本上是一个void
返回值。
赋值运算符(即等号) (1) 将右侧操作数(即变量、属性或函数的值或值)分配给左侧操作数(即变量或属性) 然后 (2) 在计算表达式的其余部分之前,赋值表达式(例如,y = 10)成为一个简单的操作数,其值与其右侧操作数(例如,10)相同。这类似于在计算表达式时将被调用的函数替换为其返回值(尽管函数调用在操作顺序中排在第一位,而赋值操作在第十四位):
var x, y, z = 1;
x = z + (y = 2); // x === 3
function returnTwo () {
return 2;
}
x = z + returnTwo(); // x === 3
请注意,现在不仅 x 等于 3,而且整个表达式的计算结果为 3。
关键字的目的var
是将变量绑定到当前作用域。使用关键字声明的变量var
绑定到声明它们的范围。关键字将var
最左边的变量(或属性)分配为对评估表达式值的引用:
var fun = function () {
var x = 1;
var y = x + 1;
return y;
}
// The x and y variables are bound to the scope of the fun function.
将var
关键字与表达式一起使用称为声明。声明是不评估为值的操作,甚至未定义(即使您的控制台正在打印未定义)。此外,声明不能出现在 JavaScript 需要表达式的地方,正如这篇文章的其他答案所示。
当您编写var x = 5;
它时,它声明x
并将其值初始化为 5。
这是 a VariableStatement
,它什么也不返回,
但是x=5
是一个expression
将 5 分配给 x。由于没有,JavaScript在普通代码中x
隐式创建一个全局变量x
由于评论和其他一些答案,我编辑了我的答案。
赋值运算符不返回任何内容...在下面的示例中,JS 解析器所做的第一件事是将 5 分配给 y。第二件事是将y分配给x,依此类推。赋值不是return
(它不是一个函数,在 JS 中它没有 C++ 语法来重载运算符的行为)。return
比分配更复杂。return
构造不仅返回一个值,而且关闭当前上下文导致它被销毁。如果没有其他孩子使用它,它也会关闭任何父上下文(关闭模式)。所以请不要告诉我(在评论中)赋值运算符返回任何值。JS 的赋值运算符只是一种语言结构。
这种语言结构在链中很有用(这就是每个人都在谈论返回的原因):
a = x = y = 5;
解析器在全局范围内自动声明任何未声明的变量。如果显式声明变量,则不能同时在链中使用它,如下所示:
a = var x = y = 5;
正确使用上述代码将是:
var x = y = 5;
a = x;
当然你可以使用方括号,让你的代码更清晰,但这并不意味着代码表现得像一个函数。
此外,您的示例仅适用于 JS 控制台,它不返回而是打印语句或表达式的结果。这意味着JS控制台将声明变量的结果视为undefined
(创建函数时相同:)function a() {}
。