9.6.2 - 'this' or 'super' in a static method
On 8/17/07, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
9.6.2 It is an error for the 'this' or 'super' expression to appear in the body of a static method.
- Is this error mentioned a compile-time error?
Compile-time. In general, any error that can be detected at compile-time is a compile-time error.
- Why does 'this' in a static method generate an error? (it shouldn't refer to the class?)
'this' always refers to an instance. Inside a class, it would be confusing if 'this' refers sometimes to the instance and sometimes to the class, depending on one attribute of the containing method.
Cormac, could the Self Proposal be extended here to allow 'Self' (or my preference, 'this type') to refer to the class in this context?
Peter
In ES3, i use this in context of a function instance.
A = function A () {
} A.instances = { }; A.getById = function getById( id ) { return ( this.instances.hasOwnProperty( id ) && this.instances[ id ] ) || ( this.instances[ id ] = new this( id ) ); };
static this?
On Aug 20, 2007, at 2:14 PM, Garrett Smith wrote:
In ES3, i use this in context of a function instance.
A = function A () {
} A.instances = { }; A.getById = function getById( id ) { return ( this.instances.hasOwnProperty( id ) && this.instances [ id ] ) || ( this.instances[ id ] = new this( id ) ); };
static this?
Yes, it's natural to expect |this| in a "class static method" to be
the class object. I've mentioned this to Jeff and we talked about the
trade-offs with respect to outlawing |this|. The binding of |this| in
your example does depend on how A.getById is called, and will be
wrong if the method is extracted and called via another base object.
But, one could argue that's a bug to fix with real class statics, not
a reason to think |this| might be considered ambiguous.
My experience with mere mortals (e.g. me) is that over time classes
accumulate methods, and often no one bothers to take time to group
static methods together in the source. This makes it easy to
errantly put "this" inside a static method without realizing the
implications. Java's compile-time catch of that problem is nice.
I see the value of referring to the class within a static method
(other than by using the class name itself). I also think it may be
advisable to use an identifier other than "this". Otherwise it's too
easy to miss the fact that a method is static.
Another way to state this: most programmers new to JS struggle with
figuring out what "this" refers to in a given context. Adding yet
another situation in which "this" could be this or that seems a bit
risky.
Yeah, that's Jeff's position. It certainly is true that this-binding
is non-trivial because dynamic in ES1-3. In ES4 for any function in a
class, it's fixed. The current proposal outlaws it in static methods
(not sure where this is written down, but like Fox Mulder, I want to
believe), and specifies this-binds-to-object-from-which-method-was-
extracted-or-called for instance methods.
We could let this alone, and say "use the class name" for static
methods, for sure. Or we could add "this class". Comments?
Surveying my code base I found 27 'static function's, 3 of which use
'this' to refer to the class, and one of which should not be static
(use 'this' to refer to the instance and the programmer erroneously
declared the function static). So, I have some appreciation for it
being an error to use 'this' in a static function, but I also want to
be able to refer to the class in a static function, without having to
use the class name.
I'm using 'static function' to mean a function which is a property of
a constructor in our es3 code base. I would make these static
functions in es4. The use cases would probably be more like:
static var = function (...) {... need to refer to the class
here ...};
so, using the class name is not an option. I want a generic function
that can refer to the class that it is a static property of. Will
that be possible?
On 8/21/07, P T Withington <ptw at pobox.com> wrote:
Surveying my code base I found 27 'static function's, 3 of which use 'this' to refer to the class, and one of which should not be static (use 'this' to refer to the instance and the programmer erroneously declared the function static). So, I have some appreciation for it being an error to use 'this' in a static function, but I also want to be able to refer to the class in a static function, without having to use the class name.
I'm using 'static function' to mean a function which is a property of a constructor in our es3 code base. I would make these static functions in es4. The use cases would probably be more like:
static var = function (...) {... need to refer to the class here ...};
so, using the class name is not an option.
Why not, given that the function body is statically enclosed in the class?
That said, by analogy with "this function" the "fix" is probably "this class" (not "this type" as suggested earlier, since we're just talking about classes and there are other kinds of types.)
I want a generic function that can refer to the class that it is a static property of. Will that be possible?
But it's not really generic, is it? It's statically inside a class the way you've written it above. I'm guessing you mean "generic" from a code generator's point of view, and you'd like to avoid parameterizing the generator of that function with the class name.
(On the other hand, if you're suggesting something like this:
class A { public static var v; } A.v = function () { ... this class ... }
then I think probably not.)
On 2007-08-21, at 11:04 EDT, Lars T Hansen wrote:
[...]
I want a generic function that can refer to the class that it is a static property of. Will that be possible?
But it's not really generic, is it? It's statically inside a class the way you've written it above. I'm guessing you mean "generic" from a code generator's point of view, and you'd like to avoid parameterizing the generator of that function with the class name.
(On the other hand, if you're suggesting something like this:
class A { public static var v; } A.v = function () { ... this class ... }
then I think probably not.)
The es3 code is:
function A () ...; A.zot = function zot () { ... this ... }
function B () ...; B.prototype = new A(); B.zot = A.zot;
hence this
is A in A.zot and B in B.zot.
I was thinking the equivalent es4 would be:
class A { static function zot () { ... this class ... }; }
class B extends A { static var zot = A.zot; }
so I would need this class
to be B
in B.zot
. Per your
'probably not', I guess that isn't going to work. Is there a better
way? Or do I have to duplicate the code for zot in each subclass?
On 8/21/07, P T Withington <ptw at pobox.com> wrote:
The es3 code is:
function A () ...; A.zot = function zot () { ... this ... }
function B () ...; B.prototype = new A(); B.zot = A.zot;
hence
this
is A in A.zot and B in B.zot.
Right...
I was thinking the equivalent es4 would be:
class A { static function zot () { ... this class ... }; }
class B extends A { static var zot = A.zot; }
Hm... more like
function the_zot() { ... this ... }
class A { static const zot = the_zot; }
class B extends A { static const zot = A.zot; // or the_zot, obviously }
I think.
so I would need
this class
to beB
inB.zot
. Per your 'probably not', I guess that isn't going to work. Is there a better way? Or do I have to duplicate the code for zot in each subclass?
Using your code I think so. After all, A.zot() is closed in the environment of its class, you can pass it around but that doesn't make it B's method whether B extends A or not.
Using my code, "this" references A and B as necessary, but the function is no longer a method.
Now I see what you mean. You would like "this class" to be dynamically scoped like "this". Yet when we were talking earlier about "this function" and "this generator", they are both statically scoped entities -- unlike "this". And that's how I've been thinking about "this class" -- as static. The motivation for "this function" was to be able to reference the function enclosing the reference not by name, but by some mechanism resilient to name change, and similar for "this generator". So I figure, why not the class.
Taking this further, would not "this" in your class-static method capture exactly what you want to capture (except that it's illegal right now and probably used by mistake about 25% of the time?)
Well, that takes us full circle...
On 2007-09-03, at 07:41 EDT, Lars T Hansen wrote:
Now I see what you mean. You would like "this class" to be dynamically scoped like "this". Yet when we were talking earlier about "this function" and "this generator", they are both statically scoped entities -- unlike "this". And that's how I've been thinking about "this class" -- as static. The motivation for "this function" was to be able to reference the function enclosing the reference not by name, but by some mechanism resilient to name change, and similar for "this generator". So I figure, why not the class.
Taking this further, would not "this" in your class-static method capture exactly what you want to capture (except that it's illegal right now and probably used by mistake about 25% of the time?)
Well, that takes us full circle...
Indeed. What I wanted was a way in a class method to say 'yes, I
mean this
, and it is not a mistake'. this class
seemed like a
pretty good idea for that. But not if it is going to be static.
Your solution is not quite what I had expected to do, but it will
work, so I guess this is not a pressing need.
9.6.2 It is an error for the 'this' or 'super' expression to appear in the body of a static method.