Closed
Bug 306920
Opened 19 years ago
Closed 19 years ago
Using a setter breaks ECMA assignment semantics
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
RESOLVED
WORKSFORME
People
(Reporter: ldavismead, Unassigned)
References
()
Details
(Keywords: testcase)
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) Gecko/20050901 SeaMonkey/1.1a
Aunty ECMA sez (262 3/e):
(quote)
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)
(end quote)
When using a setter, the result of the assignment expression (the one we're
evaluating, not the one on the RHS) is evaluated as the return value of the
setter rather than the value computed for the RHS.
Reproducible: Always
Steps to Reproduce:
1. Click on the javascript:url testcase.
Actual Results:
Alerts "foo" (the value returned from the setter).
Expected Results:
Should alert "bar" (the value of the RHS).
Also appears in Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5)
Gecko/20041107 Firefox/1.0
I really just wanted to point this out if you didn't know about it, since it's a
little surprising if you're not expecting it. Most setters don't return values
(that I know of), so those accustomed to assignment expressions evaluating to
the RHS might be surprised when they evaluate to undefined if the LHS has a
setter they don't know about (it evaluates to the return value of the setter,
which would be undefined for the unsuspecting setter implementor). I know
getters and setters are super-secret undocumented stuff, so I've no problems if
this gets WONTFIXed. I will point out that the current behaviour allows a
useful "neat trick," which might very well explain why it works the way it does,
you sneaky developer-persons, you.
function stringWrapper(s)
{
this.__defineGetter__("s", function()
{
return s;
});
this.__defineSetter__("s", function(value)
{
var oldVal = s;
s = value;
return oldVal;
});
}
var foo = new stringWrapper("foo");
var bar = new stringWrapper("bar");
/* Swap foo's and bar's strings in a very sneaky way. Note
that the getters aren't actually called anywhere in this
statement. */
foo.s = bar.s = foo.s;
foo = new stringWrapper("foo");
bar = new stringWrapper("bar");
var baz = new stringWrapper("baz");
var quux = new stringWrapper("quux");
/* "Rotate" the strings. Again no getters are called. After
this line executes:
foo.s == "bar"
bar.s == "baz"
baz.s == "quux"
quux.s == "foo" */
foo = bar = baz = quux = foo;| Reporter | ||
Comment 1•19 years ago
|
||
Well, ****. The last sneaky example should have been foo.s = bar.s = baz.s = quux.s = foo.s obviously.
Keywords: testcase
Comment 2•19 years ago
|
||
This works as intended, and it does not "break" ECMA so much as extend it (allowed for new syntax by ECMA-262 Edition 3 Section 16). /be
Status: UNCONFIRMED → RESOLVED
Closed: 19 years ago
Resolution: --- → WORKSFORME
You need to log in
before you can comment on or make changes to this bug.
Description
•