Closed
Bug 469609
Opened 16 years ago
Closed 9 years ago
meaning of "this" in lambda expression enclosed by method is unexpected
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
RESOLVED
WONTFIX
People
(Reporter: myk, Unassigned)
Details
The following code, in which a lambda expression references "this", evaluates to 3, as expected: var foo = { a: 1, b: function(c) this.a + c }; foo.b(2); This code, however, which also contains a lambda that references "this", evaluates to NaN: var foo = { a: 1, b: function(c) { var d = function() this.a + c; return d(c); } }; foo.b(2); I expected "this" in the second example to refer to the enclosing method's "this" so that the second example would also evaluate to 3. I can work around the problem in that example fairly easily: var foo = { a: 1, b: function(c) { var d = function() this.a + c; return d.call(this, c); } }; foo.b(2); However, that doesn't work in this example, which is similar to the real-world use case in which I first noticed the issue: var foo = { a: 1, b: function(ary) { return ary.filter(function(obj) obj.a == this.a); } } foo.b([objects...]); To make that example work, I have to do: var foo = { a: 1, b: function(ary) { let a = this.a; return ary.filter(function(item) item.a == a); } } foo.b([objects...]); That seems clunky (just as it is when assigning "this" to a local variable to access it from an event handler closure). I suppose my expectations are shaped by the lack of explicit block delimiters in the lambda, while the current behavior is the result of Spidermonkey treating it as a regular function with implicit block delimiters and function invocation semantics. Unless there's some advantage to the current behavior, though, it'd be useful to treat the lambda specially, giving it the enclosing method's scope (modulo those that the lambda's parameters mask) so that "this" in the lambda would refer to the enclosing method's "this".
Comment 1•16 years ago
|
||
It would be nice if 'this' were a lexically scoped variable when unbound (when not forced to a certain object binding). But ES3 tried too hard to censor the activation object and ended up making a global object leak instead. Hard to fix compatibly, outside of a "strict mode". Even crazier, objcap folks have argued against lexical 'this', even though they're otherwise in favor of lexical scope. See https://mail.mozilla.org/pipermail/es-discuss/2008-August/007317.html My opinion is that the example there comes with a "caveat lexical 'this' emptor" label, and works as designed (in the dream-world where unbound 'this' is lexically scoped). /be
Reporter | ||
Comment 2•16 years ago
|
||
(In reply to comment #1) > My opinion is that the example there comes with a "caveat lexical 'this' > emptor" label, and works as designed (in the dream-world where unbound 'this' > is lexically scoped). Fair enough. And I just remembered I can work around the issue for array extras like 'filter' by explicitly passing the 'this' object into them, i.e. |ary.filter(function(obj) obj.a == this.a, this)|, which is simple enough.
Assignee | ||
Updated•10 years ago
|
Assignee: general → nobody
Comment 3•9 years ago
|
||
ES2015 added Arrow functions [1] for this use case. Also expression closures are going to be removed (bug 1083458). Therefore resolving as Won't Fix. [1] https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → WONTFIX
You need to log in
before you can comment on or make changes to this bug.
Description
•