arguments.callee in Harmony

Fabian Jakobs fabian.jakobs at 1und1.de
Fri Sep 25 04:14:32 PDT 2009


Hi,

we have exactly the same problem in qooxdoo <http://www.qooxdoo.org>. We use 

arguments.callee.base.call(this, ...);

in the same way. Using named functions isn't a solution for us because it
would break IE compatibility. In this example

ClassB = ClassA.extend({

   foo: function foo() {
     foo.base.apply(this, arguments); // calls super!
     // other code
   }

});


"foo" would leak into the global namespace due to implementation bugs in
JScript <http://yura.thinkweb2.com/named-function-expressions/>. Right now I
don't see a good solution for this in strict mode.

Best Fabian


Charles Jolley wrote:
> 
> Hi everyone,
> 
> First an introduction: I am the lead developer of SproutCore
> (http://www.sproutcore.com 
> ), an open source framework for building client-side applications in  
> HTML5.  SproutCore is used in several large projects including Apple's  
> MobileMe and iwork.com, OtherInbox, and some other large projects that  
> are not yet public.
> 
> Point is, we write very large applications in JavaScript and HTML5.   
> I've been following ES5/Harmony closely.  By and large I am very  
> excited about the features to be added.  One critical feature (imo)  
> that is missing, however, is "arguments.callee" - at least some way to  
> identify the current function that is executing.
> 
> I spoke with Brenden Eich and Yehuda Katz about this on Friday and  
> talked to Doug Crockford about it today and they suggested I email  
> this list to make my case so here it is:
> 
> USE CASE
> 
> Currently SproutCore implements a class-like system on top of  
> JavaScript.  That is, you can have "classes" with "subclasses" and you  
> can instantiate both.  SproutCore is not strictly classical, and JS is  
> not class-based of course, but I think this is a pattern that many  
> developers commonly want to implement and use in JS.
> 
> The problem comes with implementing methods that "override" methods in  
> superclasses.  Take the following example [extend() is the SproutCore  
> function that creates a new "subclass"]:
> 
> ClassA = SC.Object.extend({
> 
>    foo: function() {
>      // do something
>    }
> 
> });
> 
> ClassB = ClassA.extend({
> 
>    // NOTE: overrides foo in classA!
>    foo: function() {
>      // call ClassA.foo();
>      // do something else
>    }
> 
> });
> 
> --
> 
> Now the question is, how can ClassB.foo() call ClassA.foo() in a  
> generic fashion?
> 
> I could force developers to hard code this knowledge  (i.e. when  
> implementing ClassB.foo() you have to explicitly call ClassA.foo.apply 
> (this)) but this is prone to developer error and also makes the code  
> not easily transportable from one method to another; violating the  
> sort of "copy-and-paste" ethos that is part of JavaScript.
> 
> I've been told that I could name the functions.  e.g.:
> 
> ClassB = ClassA.extend({
>    foo:  function foo() {
>      // ..code
>    }
> });
> 
> Somehow that should solve my problem, though I can't really work out  
> how.  But regardless, asking developers to name each method twice in  
> the declaration is also error prone and fragile.
> 
> --
> 
> The way I solve this currently is to implement extend() so that when  
> it copies an overloaded method, it sets a property ("base") on the  
> Function to point to the Function it is overloading.  In the example  
> above, for example, this means that ClassB.foo.base === ClassA.foo.
> 
> This way I can write a generic call to "super" like so:
> 
> ClassB = ClassA.extend({
> 
>    foo: function() {
>      arguments.callee.base.apply(this, arguments); // calls super!
>      // other code
>    }
> 
> });
> 
> --
> 
> I realize this is not the most elegant looking code, but currently its  
> the only way I can figure out to implement the "super" pattern in a  
> generic way in JS.
> 
> SOLUTIONS?
> 
> With ES5, arguments.callee is gone.
> 
> One suggestion Brenden had was to perhaps include a "thisFunction" or  
> some such property that returns the current function instance you are  
> in.  This seems useful to me for a bunch of other meta-programming  
> patterns as well but would certainly work here.
> 
> Another solution suggested by Douglas would be to provide a way for a  
> function to get its current "name" AND for ECMAScript to follow a  
> convention that anonymous functions when declared as part of an object  
> literal take on the name they are assigned to by default.
> 
> Either of these would work for this pattern; there are probably other  
> solutions as well.
> 
> I don't really care what ends up in the final implementation only that  
> there is some way to generically implement the ultra-common class- 
> based-with-method-overloading pattern in ECMAScript >= 5 without  
> jumping through some crazy hoops.
> 
> --
> 
> So that's my best argument on this.  Any suggestions of alternative  
> implementations that will work in ECMAScript 5?  If this is a  
> limitation of the new language, what I can do to agitate for something  
> to be added?
> 
> Thanks,
> -Charles
> 
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 
> 

-- 
View this message in context: http://www.nabble.com/arguments.callee-in-Harmony-tp25603357p25610255.html
Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at Nabble.com.



More information about the es-discuss mailing list