2012-06-25 46 views
16

In this commit有变化,我无法解释理解“这个”关键词

deferred.done.apply(deferred, arguments).fail.apply(deferred, arguments); 

成为

deferred.done(arguments).fail(arguments); 

AFAIK,当你调用一个函数像obj.func()一些对象的成员,在函数内部this绑定到obj,所以通过只能绑定thisobj将没有用处。相反,根据评论,这是必要的,因为前面的一些$.Callbacks.add实施。

我怀疑是不是jQuery的,但关于JavaScript语言本身:当你调用一个函数像obj.func(),怎么能是这里面func()this关键字未绑定obj

+1

那个提交改变与你的问题有什么关系? '.apply'用于将'n'个参数传递给另一个函数,而不是其上下文强制能力。 – Esailija

+0

@Esailija,我想你明白了! – Raffaele

+0

@Christoph我认为他明白了。 apply()不用于强制上下文,因为* this *已经*正确放置*(并且这回答了我的问题) – Raffaele

回答

5

我怀疑是不是jQuery的,但关于JavaScript语言本身 :当你调用像obj.func)函数(,怎么能是 内FUNC()this关键字并不必然OBJ?

好了,这是唯一可行的办法是,如果obj.func引用一个bound功能,那么它不会不管你怎么称呼它。在这种情况下,无论您如何调用该功能,无论您做的是obj.func(),func(),func.call({}),func.apply({})都无所谓。不过,我不确定提交是如何与此相关的。

要澄清,我回答解释为引用的问题:

给予相同的调用签名:obj.func(),怎么可能是thisobj呼叫被调用的函数里面?

+0

很好的答案。我想知道你是否猜对了,或者你知道$ .Callbacks.add不能处理以数组形式传递的参数:) – Raffaele

+0

@Raffaele事实上,两者都不是。只是'.apply(something,arguments)'是将参数传递给调用函数的唯一方式。那么,我想你可以用'eval'做一些事情,但这并不算数:D – Esailija

+0

这甚至更大:)所以关键是你在结构中识别了**参数**关键字* .apply(smth,arguments )*并立即将其链接到调用链接。通常要解决棘手的问题,需要深入了解主题(经验)和*横向思维* :) – Raffaele

2

即通过从另一对象引用功能,像这样

obj2.func = obj.func; 
obj2.func(); // 'this' now refers to obj2 

var func2 = obj.func; 
func2(); // 'this' now refers to the global window object 

或通过调用。适用()或.CALL()结合this到任意对象才是可能的。

+0

这是正确的,但不回答我的问题:)我想知道的差异,关于**这**边界之间,* ab(args)*和* abapply(b,args)*请参阅@ wnwall回答 – Raffaele

+0

我*做了*回答你的问题:“当你调用像obj.func()这样的函数时,怎么可能在func()里面这个关键字没有绑定到obj?” :-)你说的是你的问题不在顶端文章中:也许你应该更新它! –

+0

我不这么认为:P事实上,你的例子从来没有将* func *作为* obj *的成员调用:它碰巧调用同一个函数对象,但是作为另一个对象的属性(* obj2 *或*窗口*)。所以* this *的值是可以预测和预期的。相反,我询问引擎何时执行* a.b()*在* b()*,* this中有任何机会!= a *。 – Raffaele

1

函数总是通过一个接收器调用,在函数内调用this,该函数在调用时给出。

当你写

obj.someFunc = function() {... 

你不是说someFunc必须为接收器的obj,你只是说OBJ有一个叫做someFunc其值是一个函数性质。

如果你

var aFunc = obj.someFunc; 

喜欢在很多地方做(回调例如引用)和

aFunc(); 

接收器(this)后,在这种情况下的窗口。

这是因为javascript中的函数与Java等语言相反是“一等”对象,特别意味着您可以将它们作为值传递,并且不会绑定到唯一的预先指定的接收方。

+0

请参阅@Esailija和答案。你说的是正确的,但它没有解决这个问题,因为我明确地将源代码和函数联系起来,确实如同obj.func() – Raffaele

+0

感谢您对Esailija答案的评论。你完全正确。 –

1

我用速记版本是this在JavaScript中总是指的当前执行的函数是一个方法的对象 - 除了在当该方法是一个回调,当this指对象的特殊情况,其回调被绑定(例如一个按钮)。

编辑:请注意,全局函数就像window对象的方法。

This QuirksMode page帮助我,当我了解它。

5

虽然其他答案处理您对this关键字的问题,但它们不回答您为什么使用apply的问题。这里是踢球者:apply没有被用来设置该例子中的this关键字。相反,它被用来通过arguments作为donefail函数的参数。

拿这个例子:

var x = { 
    a: function(a1, a2, a3) { 
     console.log(a1, a2, a3); 
    } 
} 

function callA() { 
    x.a.apply(x, arguments); 
    x.a(arguments); 
} 

callA('red', 'blue', 'green'); 

如果执行此代码,您应该看到x.a.apply(x, arguments);x.a(arguments);之间的差异。在第一个中,a1,a2a3分别是“红色”,“蓝色”和“绿色”的颜色。在第二个中,a1是类似数组的对象[ "red", "blue", "green" ]a2a3undefined

同样,在您发布的示例中,正在使用apply正确传递arguments对象,而不是设置this关键字。

+0

+1,对不起,这不能被接受,但Esailija的第一(加上他提到了绑定对象)。不过,我真的很感谢清晰度,并希望你的代码示例可以帮助其他人了解真正的问题,就像你做的那样:) – Raffaele