I saw the example below explained on this site and thought both answers would be 20 and not the 10 that is returned. He wrote that both the comma and assignment returns a value,
You should understand how the internal Reference Type works.
Note: This is not a language data type, is an internal mechanism to handle references.
A reference is composed of two elements, the base object and a property name.
In your example, the foo.bar
reference looks like this.
// pseudo-code
foo.bar = {
baseObject: foo,
propertyName: 'bar'
}
Both, the comma operator and a simple assignment, rely on getting the value of the property name, that causes the base object to be lost, since a single value is returned (this is made through the internal GetValue operation).
This is how the internal GetValue
operation works:
// pseudo-code
GetValue(V) :
if (Type(V) != Reference) return V;
baseObject = GetBase(V); // in your example foo
if (baseObject === null) throw ReferenceError;
return baseObject.[[Get]](GetPropertyName(V));
// equivalent to baseObject[v.PropertyName];
As you see, a value is returned, so the original reference is lost.
Edit: The key to understand why (foo.bar = foo.bar)();
is not equivalent to foo.bar();
relies in the Simple Assignment Operator, let's see the algorithm:
11.13.1 Simple Assignment (`=`) The production `AssignmentExpression` : `LeftHandSideExpression` = `AssignmentExpression` is evaluated as follows: 1. Evaluate LeftHandSideExpression. 2. Evaluate AssignmentExpression. 3.Call GetValue(Result(2)). 4.Call PutValue(Result(1), Result(3)). 5.Return Result(3).
Basically when you make (foo.bar = foo.bar)
the actual assignment (Step 4.) has no effect because PutValue
will only get the value of the reference and will place it back, with the same base object.
The key is that the assignment operator returns (Step 5) the value obtained in the Step 3 and as I said before in the GetValue
pseudo-code, this internal method returns a value which doesn't really have a base object.