JavaScript 有左值和右值的概念吗?

Posted

技术标签:

【中文标题】JavaScript 有左值和右值的概念吗?【英文标题】:Does JavaScript have the concept of l-value and r-value? 【发布时间】:2015-08-26 12:41:37 【问题描述】:

javascript 中,如果您将某种表达式放在赋值表达式的左侧,引擎将抛出 ReferenceError。例如,

// 'this' on the left side
this = window; // ReferenceError: Invalid left-hand side in assignment

// function call expression on the left side
var a;
var fn = function() return a;
a === fn(); // true
a = 1; // 1
fn() = 5; // ReferenceError: Invalid left-hand side in assignment

var a;
a = 1; // 1
(a) = 2; // 2
(1, a) = 3; // ReferenceError: Invalid left-hand side in assignment

我的问题是:

    JavaScript 是否也像 C 一样具有左值和右值的概念?

    为什么函数调用表达式不能出现在赋值表达式的左侧?在上面的例子中,由于a === fn()a = 5fn() = 5有什么区别。我知道 ES5 规范要求这样做,但为什么要这样设计?

【问题讨论】:

fn() 是一个表达式而不是一个变量引用,你不能给它赋值。 但是计算顺序是从左到右,如果先计算fn(),会返回a,因为fn() === a。而a是一个变量,可以存储值。 它返回 a 的值,而不是对变量 a 的引用 a === fn() 并不意味着它们是相同的内存位置,如果是,它将具有 COW 语义......因此,分配给表达式是没有意义的。 嗨@Patrick Evans,您能详细说明一下吗? 【参考方案1】:

f() 可以评估为引用的事实,如果您在调用函数之前将对象分配给a,并不会改变f() 是一个表达式的事实(例如,与1+a 相同) )。并且赋值只能应用于变量。 MDN

【讨论】:

嗨@Kirill,感谢您的回答。 And assignment can only be applied to a variable.我不认为这是准确的。除了变量之外,您绝对可以将赋值应用于对象属性和数组元素。 @leslie.zhang 务实地说,对象属性和数组元素可以看作是变量引用,因此可以用于赋值。【参考方案2】:

同样,在 JavaScript 语言的世界观中,“this(必然...)神圣不可侵犯的。”

this 变量的用途以及因此的当前值,必然受到保护,不会被程序任意修改。

同样,“你只是不能说'一个函数',不管它是什么,'等于'5'。” (很明显,其中一个是“函数”,另一个是“整数常量”,因此,“两者永远不会相遇。”)

JavaScript 解释器与地球上的所有其他语言解释器一样,是使用与其他所有语言相同的语言实现策略(和工具...)设计和构建的被发明出来了。

【讨论】:

【参考方案3】:

根据specification of assignments,以下表达式不能作为赋值的目标:

this
Literal
ArrayLiteral
ObjectLiteral
FunctionExpression
ClassExpression
GeneratorExpression
RegularExpressionLiteral
TemplateLiteral

例如,下面的赋值也是无效的:

this    = "bar"; // this
"foo"   = "bar"; // Literal
/foo/   = "bar"; // RegularExpressionLiteral
["foo"] = "bar"; // ArrayLiteral

【讨论】:

以上是关于JavaScript 有左值和右值的概念吗?的主要内容,如果未能解决你的问题,请参考以下文章

左值和右值的区别

具有适用于左值和右值的引用参数的 C++ 函数

左值和右值

C++内功修炼干货,进大厂必须会的C++左值与右值,最适合小白看的文章!

左值引用和右值引用

右值引用,移动语义,完美转发