脚本开头的“(function() {”是什么意思?(仅适用于GreaseMonkey?)

3

我对JavaScript还比较陌生,正在自学中。目前我正在创建和调整GreaseMonkey脚本。我注意到大多数简单的脚本(即那些不需要命名函数的脚本)直接进入主代码,但有些脚本则像这样设置:

(function() {  
    //main code here  
})();

这种编码方式有什么意义?我已经注释了顶部和底部,但脚本仍然完全相同。
这只是一种编码标准,还是实际上有一个功能?正如我的标题所问的那样,这是特定于GreaseMonkey的东西,还是我应该始终这样做的东西?

但这个回答比其他回答更多地回答了问题。你选择的答案并没有回答你的问题,它回答了你没有提出的其他问题。在这里的人们也可以轻易地提出与你问题无关的话题。SO的目的是提出具体问题并得到具体答案。你选择的答案似乎有些冗长。 另外,这是一个分数较低的人做得很好的例子。这不应该影响你给予答案的对象。选择答案时不应该有任何偏见,应该是客观的决定。 - undefined
我可以决定给任何人我想要给的东西,而且我可以因为你明显地试图操纵别人给你更高的分数而对你进行负评。既然你认为催促他人点赞是可以接受的,我有理由相信你的得分是人为提高的。 - undefined
你可以决定,就像其他人可以决定给予负评一样。我没有要求任何评分,我只是建议你选择的答案不仅不完整,而且还是错误的 - 我没有提到我的答案。你应该要么提出一个更好的问题,要么选择最适合回答你问题的答案 - 而不是你认为你从中学到最多东西的答案。我要补充的是,你选择的答案与闭包无关,你的问题也无关 - 简直就是错的。你可以随意骚扰我,但是不要期待我将来会帮助你。祝你好运。 - undefined
4个回答

9
这种技术有效地创建了一个私有命名空间,仅限于此脚本访问。例如,以下代码:
(function() {
    var a = 5;
})();

这种方式对全局命名空间没有影响(a变量被闭包捕获,所以window.a不会受到影响)。这是一种非常好的方法,可以避免许多脚本互相干扰全局变量,使它们完全不是全局的。我在编写任何JavaScript时都经常使用这种技术,而不仅仅是Greasemonkey脚本,并强烈建议将其作为编写库的最佳实践。

如果您想将某些函数公开给其他JavaScript代码,而不是完全隔离您的脚本,可以像这样操作:

var MyNamespace = (function () {
    var that = {};

    that.square = function(x) {
        return x*x;
    };

    return that;
})();

然后您可以在另一个脚本中输入MyNamespace.square(5),这将返回25。


你给了我实用性,而不仅仅是解释。谢谢。 - undefined
@slushy 这取决于情况 -- 如果变量仍然需要存在,比如作为全局函数中封闭的变量,那么它们将继续存在并占用内存。如果它们实际上是临时变量,那么你是对的(但这并不总是情况)。 - undefined

3

这是一个自执行的匿名函数。

通常用于改变作用域,所有在此声明的变量和函数将在匿名函数的作用域中而不是全局(window)作用域中。


很遗憾,这个回答帮助最少。虽然我理解你的意思,但只是因为我刚好今天刚读到了关于作用域的内容。 - undefined

2
代码有两个作用:
  1. 它将对象/变量保持在匿名函数范围内。这很重要,因为您可能有几个脚本文件都可能共享相同的变量名称。如果他们这样做了,他们就可能替换变量值并真正破坏您的应用程序。

  2. 行末的 () 调用了声明的函数。换句话说,您在第一组括号中创建的匿名函数可以自动调用。除非将其分配给变量,否则没有其他方法来调用它。这避免了在内存中创建变量,并仅在运行时调用函数。


你的第二个问题非常有帮助。你的第一个问题已经被其他人回答过了,但这是一个很好的总结。 - undefined
好吧,我不能给你点踩(这个系统真是够了),但我可以指出你在评论中的言辞不当,并告诉你我再也不想听到你的回答。如果你希望这个地方客观公正,那就不要展示你乞求回答积分的个性。我现在有理由相信你的声誉被夸大了,尤其是你可以对待新用户而不受到点踩。总之,不要四处乞求点赞。即使是某些试图离开这个愚蠢地方的人,因为他们把我的两个电子邮件联系起来。 - undefined
如果我意识到他们是以使用OpenID为借口来窃取信息,我绝对不会来这里的。这就是OpenID的本质。庆幸的是,他们只有我的备用电子邮件地址。是的,我正在努力让自己被踩。我不想在一个认为你所做的是可以接受的社区中被赞同。 - undefined
@trlkly 你的信息非常错误。我从未向任何人乞求过投票,我很好奇这个说法是从哪里来的。也许你把我和别人搞混了? - undefined

1

对于那些从未听说过闭包这个词的人,这里是答案:

假设我们有一个函数

function sayHi() { alert('Hello'); }

我们可以通过以下方式调用这个函数:
sayHi();

以上是所谓的命名函数,如果您不知道它的含义,那么它就是您在听到单词"function"时所想到的东西。
在一些语言中,您不必为函数命名,可以像这样留空:
alert('Sup');
function() {alert('Hello'); }
3 + 1;
alert('Peace');

第二行是完全有效的。当然,第二行在您的页面上不会真正执行任何操作,就像第三行不执行任何操作一样。这被称为匿名函数。现在,就像我们可以将变量分配给第三行一样:

result = 3 + 1;

嗨!你好!有什么我可以帮助你的吗?
myFunc = function() { alert('Hello'); };

我们可以像之前的sayHi()函数一样使用myFunc作为函数来调用它。我们调用它的方式与调用sayHi()一样。

sayHi();
myFunc();

现在由于JavaScript被编写成具有多功能性,例如[0, 1, 2].indexOf(1)这样的东西是可行的,我们可以做如下操作:

func = function() { alert('hello'); };
func();
(function() { alert('hello'); })();

第1行和第2行将完成与第3行相同的操作,因为第3行只是第1行和第2行的扩展版本。第3行的优点在于,如果代码中后来有人使用了一个func变量,它不会对你自己的代码造成问题,此外,在第3行的函数中声明的任何变量(使用var关键字)都不会是你函数之外的有效变量,这就是闭包。

好了,这个微型教程就到这里了,希望能对你有所帮助。


你们所有人都很好地回答了我的问题,但是这个回答比其他人更全面。而且,这个回答者的得分很低,却做得非常出色。如果我能为每个回答问题的人投票,我会这样做的。 - undefined

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