JavaScript/jQuery中括号内的代码块是什么意思?

14

可能是重复问题:
(function($) {})(jQuery)的意思是什么?

我看到了很多使用以下语法的jQuery代码,但我不太明白它的含义。它出现在关于代码组织的问题上的这个答案这个答案中。两者都涉及命名空间,所以我猜这就是它的作用。

var foo = (function () {
    var someVar;

    function someFunc() {
        return true;
    }
})();

这是用于命名空间的吗?它是如何工作的?有时候最后一组括号中会有一个名称(命名空间?),有时候没有。这两者之间有什么区别?

1
同时,https://dev59.com/O2855IYBdhLWcg3wGQbY#4531124 - Nikita Rybak
1
这不是一个完全的重复,因为它提出了更一般的情况,而不是特定的jQuery案例——这是与此类似的情况。 - Orbling
1
@Orbling 是的,但两个问题的答案都不是特定于jQuery的。 - Nikita Rybak
2
@Nikita Rybak:没错,但我认为我们关闭问题是因为有重复的问题,而不是因为可以在不同的标题下找到有效答案。 - Orbling
2
是的,就我个人而言,当我发现一个问题有重复的答案时,我会在下面的答案部分发布该答案的链接,而不是投票关闭。重复的答案并不等同于重复的问题。问题仍应该存在,以便可以进行搜索。 - slebetman
显示剩余3条评论
2个回答

15
() 包裹函数的作用是将匿名函数声明转换为函数表达式,然后可以使用跟随表达式的 () 进行立即调用。
在这种情况下,外部的 () 实际上并不是必要的,因为 var foo = 会将其转换为表达式。此外,由于函数调用没有返回任何内容,foo 的值将是 undefined
它可用于创建新的变量作用域,因为在javascript中只有使用函数才能实现这一点。(JavaScript没有块级作用域。)
因此,someVar 变量对外部作用域不可见。在某些情况下,以受控的方式使其可访问可能是有意义的。为此,可以传递一个引用 someVar 的函数,并将其从该作用域传出。然后,在函数调用退出后,它的执行上下文仍然保持不变,someVar 将在您传递的函数提供的任何方式中可用。
这被称为创建一个 闭包(closure)
例如,您可以将一个值传递到调用中,并将其分配给 someVar。然后,您可以通过将函数返回到 foo 变量来使用该函数。如果您返回的函数引用了 someVar,那么您可以使用该函数来获取其值。
var foo = (function ( str ) {
    var someVar = str;
/*
    function someFunc() {
        return true;
    }
*/
    return function() {
        alert( someVar );
    };
})( 'somevalue' );

foo(); // alerts 'somevalue'

从上面可以看出,现在由foo引用的函数仍然可以访问someVar

假设您将其更改为返回到foo的函数可以接受一个参数,该参数将更新myVar的值。

var foo = (function ( str ) {
    var someVar = str;
/*
    function someFunc() {
        return true;
    }
*/
    return function( n ) {
        if( n ) {
            someVar = n;
        } else {
            alert( someVar );
        }
    };
})( 'somevalue' );

foo(); // alerts 'somevalue'

foo( 'newvalue' ); // give it a new value

foo(); // alerts 'newvalue'

现在你可以看到,foo 函数确实访问了那个变量,因为它能够改变其值,并引用之前设置的新值。


7
括号将匿名函数包裹起来,使其成为一个变量,可以通过在其后添加参数直接调用。
(function(param) {
    // do stuff
})(param);

结尾的那一部分不是命名空间,而只是一个参数。你可能已经在jQuery中看到过这种用法:
(function($) {
    $('.something').addClass('.other');
})(jQuery);

这样做的作用是将jQuery对象传递给函数,使得在匿名函数的范围内,$变量成为jQuery对象。人们喜欢使用简写的$,但这可能会与其他库发生冲突。这种技术通过传递完全限定的jQuery对象并在该函数的范围内重写$变量来消除冲突的可能性,因此可以使用快捷方式。


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