In JavaScript, if you put some kind of expression on the left side of an assignment expression, the engine will throw a ReferenceError. For example,
// 'this' on the left side
this = window; // ReferenceError: Invalid left-hand side in assignment
or
// 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
or
var a;
a = 1; // 1
(a) = 2; // 2
(1, a) = 3; // ReferenceError: Invalid left-hand side in assignment
My questions are:
Does JavaScript also have the concept of l-value and r-value as C?
Why function call expression can not appear on the left-hand of an assignment expression? In the above example, since
a === fn()
, what's the difference betweena = 5
andfn() = 5
. I know that ES5 spec mandates this, but why is it designed like that?
In JavaScript, if you put some kind of expression on the left side of an assignment expression, the engine will throw a ReferenceError. For example,
// 'this' on the left side
this = window; // ReferenceError: Invalid left-hand side in assignment
or
// 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
or
var a;
a = 1; // 1
(a) = 2; // 2
(1, a) = 3; // ReferenceError: Invalid left-hand side in assignment
My questions are:
Does JavaScript also have the concept of l-value and r-value as C?
Why function call expression can not appear on the left-hand of an assignment expression? In the above example, since
a === fn()
, what's the difference betweena = 5
andfn() = 5
. I know that ES5 spec mandates this, but why is it designed like that?
-
fn()
is an expression and not a variable reference, and you can't assign anything to that. – Ja͢ck Commented Jun 11, 2015 at 1:57 -
But the evaluation order is from left to right, if
fn()
is evaluated first, it will returna
, sincefn() === a
. Anda
is a variable and can store values. – leslie.zhang Commented Jun 11, 2015 at 2:01 - 5 it returns the value of a, not a reference to the variable a – Patrick Evans Commented Jun 11, 2015 at 2:04
-
a === fn()
doesn't mean they are the same memory location, and if it were, it would have COW semantics ... so, assignment to an expression is meaningless. – Ja͢ck Commented Jun 11, 2015 at 2:28 - Hi @Patrick Evans, would you elaborate with an answer? – leslie.zhang Commented Jun 11, 2015 at 3:13
3 Answers
Reset to default 3According to the specification of assignments, the following expressions are not valid as the target for an assignment:
this
Literal
ArrayLiteral
ObjectLiteral
FunctionExpression
ClassExpression
GeneratorExpression
RegularExpressionLiteral
TemplateLiteral
For example, the following assignments are invalid too:
this = "bar"; // this
"foo" = "bar"; // Literal
/foo/ = "bar"; // RegularExpressionLiteral
["foo"] = "bar"; // ArrayLiteral
The fact that f()
can evaluate to a reference, in case you assign an object to a
before calling function, doesn't change the fact that f()
is an expression (same as for example 1+a
). And assignment can only be applied to a variable. MDN
Likewise, in the JavaScript language's world-view, "this
is (necessarily ...) sacrosanct."
The purpose, and therefore the present value, of the this
variable, is necessarily-protected from arbitrary modification by programs.
Likewise, "you simply cannot say that 'a function,' whatever it is, 'is equal to '5'." (Quite obviously, one of these is a "function," and the other is "an integer constant," and so, "never the twain shall meet.")
The JavaScript interpreter, like every other language-interpreter on this planet, was designed and built using the same language-implementation strategies (and tools ...) employed by every other language that has ever been invented.