While learning Javascript, I tried to re-declare the apply property of a function. Thus far no problem.
function foo() { return 1; }
alert(foo()); // 1
alert(foo.apply(null)); // 1
foo.apply = function () { return 2; }
alert(foo()); // 1
alert(foo.apply(null)); // 2
Now, I tried to make apply do something more and call the "old" apply (like logging).
var old = foo.apply;
foo.apply = function() {
alert("A");
return old(null);
}
alert(foo.apply(null));
I get
TypeError: Function.prototype.apply was called on [object Window], which is a object and not a function
I tried
foo.apply = function() {
alert("A");
return arguments.callee[Function.prototype.apply](null);
}
alert(foo.apply(null));
I get
TypeError: Property 'function apply() { [native code] }' of object function () { alert("A"); return arguments.calleeFunction.prototype.apply; } is not a function
Is there any real way to accomplice what I try? Or is it some restriction due to Function.prototype.apply being native code?
Yes. apply
expects to be applyed (yes, with exactly itself) on a function, while the way you used it (by old()
) makes its this
value the global object (window
). So you can do this:
var old = foo.apply; // === Function.prototype.apply
foo.apply = function() {
// "this" is the function foo
alert("A");
return old.apply(this, arguments); // applying the (old) apply function on foo
// or better without any arguments:
return old.call(this); // like this(); which is foo()
}
alert(foo.apply(null));
// and the call solution with an argument:
foo.apply = function(context) {
return old.call(this, context);
// like this.call(context);
// which is foo.call(context)
// which is like context.foo()
}
Also check out the docs for the call
and apply
"methods" (though we've use old
not as a method, but as a pure function).