On Mar 27, 2011, at 11:13 AM, David Herman wrote:
> To be fair, your suggestion is more moderate than de Bruijn, although it's
> not clear whether you're proposing the ability to refer to shadowed bindings
> of *all* variables or just |this|. If it's the former, I'm *strongly*
> opposed. If it's the latter, well, I guess I'm still pretty opposed, just
> maybe less strongly. :)
Dave, I think that applying this solution to the this-scoping issue may be a
really good idea
Claus, thanks from bringing a new (old) idea into the discussion.
I agree with Dave about all the fragility issues he mentioned for the general
case. Also, I just don't see the general problem (if it is even a "problem")
as one that is important enough to try to "fix" in the language since it is
probably rare and it can be avoided by careful naming.
However, the specific case of 'this' is a different matter. 'this' is
implicitly rebound in every function scope and the JavaScript programmer has no
direct control over the naming and shadowing. The result is that they have to
know and use the self renaming pattern.
This issue shows up enough in defining objects via object literal methods and
in methods that call higher order functions that it is something that may well
be worth addressing in the language. Particularly as we discuss adding
additional declarative forms to Harmony that included nested method
definitions. The outer 'this' problem is limited enough that we can avoid
things like dynamic scoping complications in the solution. Also it is limited
enough that I don't believe that the solution imposes refactoring
complications.
Here is a sketch of a proposal:
^this is added as a new lexical token of the language. When spoken it is
pronounced as "outer this" . In the expression grammar ^this is a primary
expression.
It is a syntax error for ^this to appear outside of a function body. It may
not occur at the top level of a program.
When evaluated, the value of ^this is the this binding of the function that
immediately lexically encloses the function body that contains the ^this. It
is a early syntax error if there is no such function. For example:
//at the top level
var self = ^this; //syntax error, at the top level
function foo() {
^this.bar(); //syntax error, no enclosing function
}
The two primary use cases for ^this are exemplified by the following two
examples:
MyObj.prototype.addClickHandingForElement(elem) {
elem.addEventListener('click', function (e) {^this.handleClick(this,e)});
}
MyObj.prototype.wrap = function () {
// create a wrapper object that limits access to the properties of one of my
objects
return {
name: this.id, //fix name of wrapper at creation (uses this of wrap
call
get foo () {return ^this.foo}, //outer this is this of wrap call
set bar(val) {^this.bar = val} //outer this is this of wrap call
}
Note that only one level outer this access is supported, ^^this would be a
syntax error. In the rare cases where somebody really needs deeper access to
shadowed this binding then they can fall back to the self pattern.
I see minimal refactoring hazards here as the outer scope reference is limited
to one level, is explicitly marked at the usage site, and only applies to this.
Possible reservations:
This use of ^ probably would preclude its use as a short form of the 'return'
keyword (for those people who aren't in favor of adding implicit returns).
It looks odd to old Smalltalk programmers.
Overall, I really like ^this as a narrow solution to a specific real usage
problem. I'm interested in reactions and unless somebody thinks of something
that seriously torpedoes it I will probably write it up as a strawman.
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss