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 にさらに何かを実行させ、「古い」apply (logging など) を呼び出そうとしました。

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

私は得る

TypeError: Function.prototype.apply が [オブジェクト ウィンドウ] で呼び出されました。これは関数ではなくオブジェクトです。


私は試した

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

私は得る

TypeError: オブジェクト function () { alert("A"); のプロパティ 'function apply() { [ネイティブ コード] }' return 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()
}

callおよびapply「メソッド」のドキュメントも参照してください(ただしold、メソッドとしてではなく、純粋な関数として使用しています)。

于 2013-02-25T15:17:49.810 に答える