赋值返回的值

Posted

技术标签:

【中文标题】赋值返回的值【英文标题】:Value returned by the assignment 【发布时间】:2013-04-08 06:42:48 【问题描述】:

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

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

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

【问题讨论】:

Difference between using var and not using var in JavaScript 的可能副本。看看kangax的答案。 “var x = 1 在当前作用域(又名执行上下文)中声明变量x....另一方面,x = 1 只是一个属性赋值。它首先尝试针对作用域链解析x。如果它在该范围链中的任何位置找到它,它就会执行赋值;如果它没有找到 x,那么它只会在全局对象上创建 x 属性。" 那个有趣..我从来没有注意到这个! 我认为x = 5 是一个能够返回值的表达式,而var x = 5 是一个不能返回值的语句。最明显的是,您不能内联声明变量,即console.log(var x = 5)。你从哪里得到undefined 的返回值? 通过什么例子让您认为 x=5 实际上“返回”? @AbbyChauYuHoi 我也不同意return 关键字,但由于某种原因我的回答被否决了。我不明白这些人...... 【参考方案1】:

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

让变量声明返回除undefined 以外的任何内容是没有意义的,因为您永远不能在表达式上下文中使用var 关键字。

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

x = y = z = 2;

也可以这样使用:

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

但这不是最易读的代码,最好写成:

y = z;
x = 2*z;

【讨论】:

如果 Javascript 将变量声明视为表达式(可在其他表达式中使用等),会出现什么问题? @user10165 他们会定义更多的规则,例如,在表达式中的什么时候变量是可用的。它的用例也不多,因为没有它你可以做任何事情。【参考方案2】:

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

Section 12.2 of the ECMAScript Language Reference 中描述了此语句的行为。

    评估 VariableDeclarationList。 返回(正常、空、空)。

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

【讨论】:

@user10165 这基本上是语言的设计方式,看看你如何在一个语句中拥有多个声明,我可以想象他们为什么这样做void :)【参考方案3】:

赋值运算符(即等号) (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 关键字是一个特殊的运算符,它将语句的返回值写入内存" 那么如果没有var 那么语句的返回值不会写入内存?跨度> 是的,我最好调整一下。 感谢您的帮助。有时,当我处理 JavaScript 时,关于 Java 工作方式的随机想法会在我脑海中蔓延,最终我不得不把自己的脑袋拍了好几下。 是的,如果我们只有一种语言会简单得多! 好点。好吧,得跑了——我玩~飞镖游戏迟到了~!! :-)【参考方案4】:

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

这是一个VariableStatement,它什么也不返回,

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

【讨论】:

另一个 x = 5 是多少? 是赋值操作。 我相信没有其他限定的x = 5 等价于window.x = 5,或者任何全局对象。 问为什么变量声明加上一个(可选的)赋值被Javascript归类为statement而不是expression有意义吗?【参考方案5】:

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

赋值运算符不返回任何内容...在下面的示例中,JS 解析器所做的第一件事是将 5 分配给 y。第二件事是将y分配给x,依此类推。赋值不是return(它不是一个函数,在 JS 中它没有 C++ 语法来重载运算符的行为)。 return 比赋值更复杂。 return 构造不仅返回一个值,而且正在关闭当前上下文,导致它被销毁。如果没有其他孩子使用它,它也会关闭任何父上下文(关闭模式)。所以请不要告诉我(在 cmets 中)赋值运算符返回任何值。 JS 中的赋值运算符只是一种语言结构。

这种语言结构在链中很有用(这就是每个人都在谈论返回的原因):

a = x = y = 5;

解析器在全局范围内自动声明任何未声明的变量。如果显式声明变量,则不能同时在链中使用它,如下所示:

a = var x = y = 5;

正确使用上述代码:

var x = y = 5;
a = x;

当然你可以使用方括号,让你的代码更清晰,但这并不意味着代码表现得像一个函数。

此外,您的示例仅适用于 JS 控制台,它不会返回而是打印语句或表达式的结果。就是说JS控制台把声明变量的结果当成undefined(创建函数时一样:function a() )。

【讨论】:

您必须使用括号,因为赋值运算符在运算顺序中是第 14 个(倒数第二个)。arguments.callee.info/2008/11/03/… 但是,说表达式返回值是完全不正确的。表达式计算为一个值。你绝对是 100% 正确的。 谢谢。如果 javascript 控制台没有将语句的结果视为undefined,那么对于新手来说可能不会那么混乱(因为语言中没有任何地方这么说)。相反,它应该在语句之后根本不打印任何内容,并且在表达式之后打印表达式的值。 Carlos,您可能会喜欢我修改后的答案。我认为这个术语现在很流行。

以上是关于赋值返回的值的主要内容,如果未能解决你的问题,请参考以下文章

C语言问题 赋值表达式返回值是啥?比如j=0这个表达式的返回值是啥?

excel中给单元格赋值,判断后返回另外一个值,覆盖原来的值。

return的值是一个赋值表达式时,返回的是右边的值

如何将Ext.Ajax.request请求 返回的值赋值给全局变量

mysql 对返回的值是null进行判断和重新赋值

JS ES6的变量的结构赋值