jQuery $(function() {}) vs (function () {})($)

16

我理解下面的代码是 $( document ).ready() 的简写:

$(function() {
    console.log( "ready!" );
});

我也知道什么是匿名JS函数,但当它被jQuery使用时,jQuery是否会有特殊的操作?比如:

(function() {
    console.log( "ready!" );
})($);

后者只是使用了jQuery的常规匿名JS函数吗(即它不会被视为$(document).ready()的简写,因此会立即执行)?

我觉得这一定以前已经有人问过了,但如果有的话我找不到。


2
顺带一提,我倾向于(强烈)使用jQuery(function($){//...此处保证$是jQuery});-“无冲突安全”的文档就绪。 - random_user_name
3
(function() { console.log( "ready!" ); })($) 接受 $ 参数但未对其进行任何操作。 - Dominique Fortin
2
在第二种情况下,您将jQuery实例传递给匿名函数(不知道为什么)。它将立即执行。 - degr
后者确实只是一个匿名函数。我甚至不确定它是否起到了作用。但你可以真正找到的是 ( function( $ ) {/* your code*/ })(jQuery),这可以确保 $ 是 jQuery(此标识符有时会被覆盖为某个不同的库)。 - VLAZ
@cale_b 谢谢。我知道什么是IIFE,所以不需要解释。我只是想确认jQuery没有做什么神奇的事情,以某种方式对待它。 - Chuck Le Butt
3个回答

13

正如您提到的那样,前者确实是$(document).ready()的简写形式。 至于后者,则只是一个立即调用函数表达式

(function ($) {
    console.log('ready');
})(jQuery);

这个函数只是一个匿名函数,接收一个名为$的参数。该函数将立即调用某个值(在本例中为jQuery)作为该参数。

IIFE也可以用于在包含多个JavaScript文件的Web应用程序中隔离范围避免全局变量。在这种情况下,可以使用无参数IIFE:

(function () {
    // x is only accessible within this IIFE
    var x;
    // do something...
})();

想了解更多关于立即执行函数表达式的信息,请参见此问题:What is the purpose of a self executing function in javascript?


这是更准确的答案,特定于jQuery。使用“无冲突安全”模型可以获得额外的加分,这将确保jQuery可以与其他使用$函数名称的库一起运行。 - random_user_name
1
很好的回答,但我更熟悉“立即调用函数表达式”这个术语,而不是“自调用匿名函数”。有区别吗?@cale_b? - Chuck Le Butt
1
@ChuckLeButt 你说得对,我也把另一个术语加到答案里了。 - Lior Erez

9

第一个确实是$(document).ready()的简写,如此处所指出。

但第二个是立即调用的函数表达式(IIFE),它是一个匿名函数,声明后立即调用。

事实上,正确的语法你的示例中缺少参数)是:

(function($) {
    //my $ object is local now
})(jQuery);

在这种情况下,您正在调用带有参数的匿名函数。
这种模式(IIFE)的主要优点是:隔离您的代码(您可以创建尽可能多的变量,并且它将受限于您的匿名函数作用域,除非您返回某些内容)。这种模式经常用于定义“私有”“公共”方法。像这样:
var myModule = (function() {

    function privateFunction() { console.log("I can't be accessed from outside :("; }

    var privateVar = "me too :(";

    function publicFunction() { console.log("Hey! I'm here!"; }

    /* expose what you want */
    return {
        publicFunction: publicFunction
    }

})();

myModule.publicFunction(); //Hey! I'm here!
myModule.privateFunction(); //undefined;

您也可以称之为模块模式

在第二个例子中,您使用一个参数调用了最近创建的匿名函数,并且您的匿名函数接收该参数。这是一种依赖注入的方式。

通过这种方式,您将全局变量作为本地变量在函数内部进行操作。请注意,在第一个例子中,我们传递了一个jQuery对象,并在函数内部将其作为$进行操作。虽然有些脚本可能会重新分配全局美元符号,特别是如果您无法完全控制应用程序,则更难覆盖jQuery对象。因此,您始终会传递jQuery对象并将其作为$进行操作。

最后,让我列出一些从这里传递参数到IIFE的其他优点:

  • 更快:JavaScript 先查找本地作用域(再向上爬)。这可能会稍微提高性能。

  • 有助于缩小文件大小:缩小器现在可以将您的作用域内的变量重命名为一个字母,从而减少代码大小。


3

后者是一个普通的匿名JS函数,使用jQuery(即不是$(document).ready()的简写形式),因此将立即执行。

是的,没错,它就是一个普通的IIFE函数,接受$全局变量作为参数。

(function(dollarSignArgument) {
    console.log( "not really ready!" );
})($)

它将立即执行


这样想就对了。谢谢! - Chuck Le Butt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接