0

在学习 Javascript 时,我尝试重新声明一个函数的 apply 属性。到目前为止没有问题。

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

现在,我试图让 apply 做更多的事情并调用“旧”应用(如日志记录)。

var old = foo.apply;
foo.apply = function() {
   alert("A");
   return old(null);
}
alert(foo.apply(null));

我明白了

TypeError: Function.prototype.apply 在 [object Window] 上被调用,这是一个对象而不是函数


我试过

foo.apply = function() {
   alert("A");
   return arguments.callee[Function.prototype.apply](null);
}
alert(foo.apply(null));

我明白了

TypeError: 对象函数 () { alert("A"); 的属性 'function apply() { [native code] }' 返回 arguments.calleeFunction.prototype.apply;} 不是函数


有什么真正的方法可以帮助我尝试什么?还是由于 Function.prototype.apply 是本机代码而受到一些限制?

4

1 回答 1

3

是的。apply期望在函数上应用(是的,完全是自身),而您使用它的方式(通过old())使其this成为全局对象(window)。所以你可以这样做:

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()
}

另请查看 thecallapply"methods" 的文档(尽管我们old不是将其用作方法,而是用作纯函数)。

于 2013-02-25T15:17:49.810 回答