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
> [email protected]
> 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.
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss