我非常熟悉使用jQuery自行执行函数。
(function($) { /* do stuff */ })(jQuery);
今天我正在阅读backbone.js源代码并注意到他们这样做了:
(function() { /* do stuff */ }).call(this);
这实现了同样的目标吗?以下两行代码会做同样的事情吗?
(function($) { /* do stuff */ })(jQuery);
(function($) { /* do stuff */ }).call(jQuery);
答案 0 :(得分:12)
第一种形式是传入参数,而第二种形式是设置执行函数内部的“this”。他们是不同的。
(function(x){ console.log(this,x); })( jQuery );
//--> [window object]
//--> [jQuery object]
(function(x){ console.log(this,x); }).call( jQuery );
//--> [jQuery object]
//--> undefined
(function(x){ console.log(this,x); }).call( jQuery, jQuery );
//--> [jQuery object]
//--> [jQuery object]
有关详细信息,请参阅Function.prototype.call
和Function.prototype.apply
。
以下是您可能希望使用call
技术的情况:
v = 'oh noes!'
var o = {
v : 42,
f : function(){
console.log(this.v);
(function(){ console.log(this.v) })();
}
};
o.f();
// --> 42
// --> 'oh noes!'
如果不通过this
设置call()
的值,则在Global(窗口)的范围内调用自调用函数,而不是当前对象。
答案 1 :(得分:3)
在他们的案例中:
(function() { /* do stuff */ }).call(this);
...他们确保使用this
的特定值调用函数(例如,函数中的this
将与this
之外的(function($) { /* do stuff */ })(jQuery);
相同功能)。
在你的情况下:
this
函数中的 ... this
将是全局对象,因为你调用它而不做任何设置this
的事情,因此window
默认为全局对象( this
,关于浏览者。)
在JavaScript中,obj.foo(); // Or `obj["foo"]();
完全由函数的调用方式设置。主要有两种方式:
通过将函数作为从对象属性中检索它的表达式的一部分来调用,例如
foo
在这种情况下,在this
的来电中,obj
会引用var obj = {name: "Fred"};
function foo(salutation, punctuation) {
alert(salutation + " " + this.name + punctuation);
}
foo.call(obj, "Hi", "!"); // alerts "Hi Fred!"
foo.apply(obj, ["Hi", "!"]); // Also alerts "Hi Fred!"
。
call
apply
和call
之间的唯一区别是如何指定要传递给您正在调用的函数的参数:使用this
,您只需将它们列为{后面的离散参数{1}}你想要的价值;使用apply
,您可以将它们作为数组提供。
答案 2 :(得分:1)
第一个传递jQuery作为参数$。第二个使jQuery成为函数内的'this'变量。
答案 3 :(得分:-2)
.call
将函数放在闭包范围内。
所以如果你这样做了:
(function($) { /* do stuff */ }).call(jQuery);
$
将为undefined