55

为什么常规赋值语句(比如, x = 5)返回赋值(5在这种情况下),而赋值与变量声明(var x = 5)结合返回undefined

我通过在 Chrome 浏览器的 Javascript 控制台中执行这些语句获得了返回值:

> var x = 5;
undefined
> y = 5;
5
4

5 回答 5

48

这就是语言的设计方式。它与大多数语言一致。

有一个变量声明返回任何东西undefined都是没有意义的,因为你永远不能var在表达式上下文中使用关键字。

当您想一次将许多变量设置为相同的值时,将赋值expression不是 astatement很有用:

x = y = z = 2;

它也可以这样使用:

x = 2*(y = z); // Set y = z, and x = 2*z

然而,这不是最可读的代码,它可能会更好地写成:

y = z;
x = 2*z;
于 2013-04-16T01:28:02.537 回答
10

那是因为var x = 5;是变量语句,而不是表达式。

该语句的行为在 ECMAScript 语言参考的第 12.2 节中描述。

  1. 评估变量声明列表。
  2. 返回(正常、空、空)。

这基本上是一个void返回值。

于 2013-04-16T01:44:23.350 回答
5

赋值运算符(即等号) (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 需要表达式的地方,正如这篇文章的其他答案所示。

于 2013-04-16T02:58:37.027 回答
3

当您编写var x = 5;它时,它声明x并将其值初始化为 5。

这是 a VariableStatement,它什么也不返回,

但是x=5是一个expression将 5 分配给 x。由于没有,JavaScript在普通代码中x隐式创建一个全局变量x

于 2013-04-16T01:26:10.357 回答
0

由于评论和其他一些答案,我编辑了我的答案。

赋值运算符不返回任何内容...在下面的示例中,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() {}

于 2013-04-16T01:28:10.490 回答