Comment #8 on issue 278 by [email protected]: Can't change a
function's "name" property
http://code.google.com/p/v8/issues/detail?id=278
Many modern javascript patterns would benefit from the name property
being "WriteOnce" or even being treated as a regular property.
Here's an example where it'd be helpful to be able to set the name property
(assuming the name is what drives what shows up in the stack traces).
This encapsulate function takes a function and puts it in a new function.
These new functions will always have the same name... Not cool.
//START
function encapsulate(func) {
return function encapsulatedFunction(){
func.apply(this,arguments);
}
}
function yayEmit() {
EMITTER.emit("YAY!");
}
encapsulate(yayEmit)();
//END
Stack trace:
ReferenceError: EMITTER is not defined
at yayEmit (eval at <anonymous> (unknown source))
at encapsulatedFunction (eval at <anonymous> (unknown source))
I'd like not to have "encapsulatedFunction" or something similar show up in
my stack traces. That's hardly helpful, and would be downright confusing if
there were multiple levels of encapsulation. It'd be better if I could do
this:
//START
function encapsulate(func) {
var encapsulatedFunction = function(){
func.apply(this,arguments);
};
encapsulatedFunction.name = "encapsulated_" + func.name;
return encapsulatedFunction;
}
//END
That way the stack trace would read something like this:
ReferenceError: EMITTER is not defined
at yayEmit (eval at <anonymous> (unknown source))
at encapsulated_yayEmit (eval at <anonymous> (unknown source))
Let's take a look at another example where a writable name would be useful!
This little functional inheritance function.
//START
function extender(superConstructor, thisConstructor) {
return function Extension(){
superConstructor.apply(this,arguments);
thisConstructor.apply(this,arguments);
};
}
function Animal () {
this.alive = "true";
}
function Dog () {
this.type = "dog";
}
var myDog = new (extender(Animal,Dog))();
myDog; // ► Extension
myDog.constructor.name; // "Extension"
//END
myDog is now considered an instance of Extension. That's not cool... I'd
rather see "Dog" or "Dog_extends_Animal".
This should totally work:
//START
function extender(superConstructor, thisConstructor, name) {
var extension = function(){
superConstructor.apply(this,arguments);
thisConstructor.apply(this,arguments);
};
extension.name = name || thisConstructor.name;
// or for something a bit more descriptive: extension.name =
thisConstructor.name + "_extends_" + superConstructor.name;
return extension;
}
//END
Perhaps a nice middle-ground solution would be what Isaac Schlueter
suggested ("name" as a WriteOnce property). I'd imagine only anonymous
functions would be eligible for "renaming", and non-anonymous function's
initial naming would count as their single-allowed [Function].name write.
I'd like to read the thoughts of the devs on this one if at all possible.
It's 2012 now... I should be able to accomplish this without eval.
- Mike Brew
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev