我最初在Paul Irish的博客上遇到过关于'鸭子拳击'模式的问题。我得到一般的前提......将ref保存到现有函数,然后用条件分支替换现有函数,如果满足条件则调用新函数,否则替换旧版本。我的问题是,当我们调用_old函数时,为什么我们必须使用'apply'和'this'作为第一个参数?我理解申请是如何运作的,但我正在寻找一些有关为何必要的澄清。
(function($){
// store original reference to the method
var _old = $.fn.method;
$.fn.method = function(arg1,arg2){
if ( ... condition ... ) {
return ....
} else { // do the default
return _old.apply(this,arguments);
}
};
})(jQuery);
答案 0 :(得分:8)
考虑这个例子
var obj = {
foo: "bar",
baz: function () {
return this.foo;
}
};
o = obj.baz;
obj.baz(); // "bar"
o(); // undefined
如果使用obj.baz调用方法,则点后面的对象是函数的上下文(此将引用此对象)。 如果将方法存储在变量中,则会丢失有关上下文的信息。在这种情况下,上下文将设置为全局对象。
var obj = {
baz: function () {
return this;
}
};
o = obj.baz;
obj.baz() === obj; // true
o() === obj; // false
o() === window; // true
适当的背景可能对.method按预期工作很重要。
答案 1 :(得分:1)
你传递this
,因为apply()
需要第一个参数是this
在调用旧函数时应该是什么。
apply()
,因此您可以轻松地将arguments
移交给旧函数的参数。
因此,在决定传递的内容为this
时,您已选择传递this
在该上下文中的内容。
答案 2 :(得分:1)
如果你在没有apply
的情况下调用原始函数,那么你让JavaScript决定绑定this
的内容,这可能与你遇到的情况有所不同。 t monkeypatched / duckpunched原始代码。
使用apply
,您可以确保this
使用正确的值,例如用于调用包装函数的那个。