Javascript包装匿名函数内的代码

时间:2013-10-26 18:51:15

标签: javascript jquery

我需要帮助理解jQuery插件创作的这种模式。有人可以为我解释一下这段简单的代码吗?

(function($) { /* Code here */ })(jQuery);

我知道这是为了避免与使用相同$字符的不同插件冲突,但不知何故无法理解它是如何工作的。参数$与已解析的jQuery对象有什么关系?

5 个答案:

答案 0 :(得分:52)

让我们打破这个:

(function($) { /* Code here */ })(jQuery);

首先,构造:

(function() {})();

创建一个立即执行的函数表达式(通常称为IIFE)。这是一个立即执行而不是现在定义的函数,但稍后调用。它本质上是一个匿名(未命名)函数,它被定义然后立即执行。

然后,将jQuery传递给它:

(function() {})(jQuery);

将jQuery作为第一个参数传递给该立即执行的函数。然后,将第一个参数命名为$,将函数内部的符号定义为与传递的第一个参数相对应。

(function($) {})(jQuery);

以扩展形式显示如下:

(function($) {
    // you can use $ here to refer to jQuery
})(jQuery);

对于jQuery插件作者来说,有一件好事:

  1. IIFE创建了一个本地函数上下文,因此您可以拥有插件的“全局”变量,但实际上不是全局变量,因此不会污染或与实际的全局变量名称空间冲突。

  2. 您可以使用$为jQuery编程,无论主程序是否实际具有为jQuery定义的内容,因为您已在函数中本地定义了$

    < / LI>

答案 1 :(得分:9)

你所拥有的是这样的简写:

function anonymous_function($) {
    // Code here
};
anonymous_function(jQuery);

如您所见,它允许$符号用作对函数内jQuery对象的引用。

答案 2 :(得分:2)

JavaScript中的函数可以be either a statement or an expression。使用函数表达式时,可以像传递任何其他值一样传递它:

> console.log(function() { 1 + 1; });
> (function() {}) && doExpensiveWork();
// etc.

您可以使用函数表达式执行的操作之一是立即调用它。在这种情况下,该函数称为an immediately invoked function expression (or IIFE for short)

> (function() { console.log("IIFE running"); })();
IIFE running

这与创建函数并分两步调用它相同:

> var notAnIIFE = function() { console.log("running"); };
> notAnIIFE();
running

函数表达式当然可以带参数:

> var someFunction = function(x, y) { return x + y; };
> var seven = someFunction(3, 4);
> seven
7

因此,也可以使用参数调用IIFE

> var seven = (function(x, y) { return x + y; })(3, 4);
> seven
7

如果是这样的调用:

(function($) { /* do work with $ */ })(jQuery);

绑定到名称jQuery的值将作为参数$传递到函数表达式中。这与执行以下操作类似:

var initializePlugin = function($) {
    /* do work with $ */
};
initializePlugin(jQuery);

但它在父命名空间中没有留下任何痕迹(而在我们的第二个例子中,在我们完成设置插件后,我们的initializePlugin名称被遗忘了。)

答案 3 :(得分:1)

javascript中的函数创建了一个范围,它不仅仅是关于$变量,而是关于函数本地的变量。并且考虑到$参数,它将成为函数的本地参数并且可以安全使用,参考jQuery

答案 4 :(得分:1)

+1 jfriend00的答案。

但是在页面中包含jQuery会覆盖全局符号jQuery和$(请参阅jQuery.js line 9579),这可能会导致与定义全局$的其他库发生冲突。

所以更进一步,以阻止全球美元冲突:

(function($) {
    // you can use $ here to refer to jQuery
})(jQuery.noConflict());

如下所示:

<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script>
(function($) {
   console.log('want $ to be jQuery here so want true: ' + ($ === jQuery));
})(jQuery.noConflict());
console.log('do not want $ to be jQuery here so want false: ' + ($ === jQuery));
</script>