Javascript “的目的”;(函数(){quot;在脚本开头(仅限GreaseMonkey?)

Javascript “的目的”;(函数(){quot;在脚本开头(仅限GreaseMonkey?),javascript,function,greasemonkey,Javascript,Function,Greasemonkey,我对JavaScript非常陌生,我自己也在学习。我目前正在创建和调整GreaseMonkey脚本。我注意到大多数简单脚本(即不需要命名函数的脚本)直接进入主代码,但有些脚本的设置如下: (function() { //main code here })(); var MyNamespace = (function () { var that = {}; that.square = function(x) { return x*x; }

我对JavaScript非常陌生,我自己也在学习。我目前正在创建和调整GreaseMonkey脚本。我注意到大多数简单脚本(即不需要命名函数的脚本)直接进入主代码,但有些脚本的设置如下:

(function() {  
    //main code here  
})();
var MyNamespace = (function () {
    var that = {};

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

    return that;
})();
myFunc = function() { alert('Hello'); };
这种编码的意义是什么?我已经注释掉了顶部和底部,脚本仍然运行完全相同


它只是一个编码标准,还是真的有一个函数?而且,正如我的标题所问,它是特定于GreaseMonkey的东西,还是我应该一直做的东西?

它是一个自动执行的匿名函数


它通常用于更改作用域,在此范围内声明的所有变量/函数都将位于匿名函数的作用域中,而不是全局(窗口)作用域。

此技术有效地创建了一个私有名称空间,仅可由此脚本访问。例如,此代码:

(function() {
    var a = 5;
})();
对全局命名空间没有影响(闭包捕获了
a
变量,因此
窗口。a
将不受影响)。这是一种很好的方法,可以使许多脚本不受全局变量的影响,从而避免它们相互影响。我在编写任何JavaScript时都会使用这种技术,而不仅仅是Greasemonkey脚本,并且强烈建议在编写库时将其作为最佳实践

如果希望将某些函数公开给其他JavaScript代码,而不是完全隔离脚本,可以执行以下操作:

(function() {  
    //main code here  
})();
var MyNamespace = (function () {
    var that = {};

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

    return that;
})();
myFunc = function() { alert('Hello'); };

然后,您可以从另一个脚本执行
MyNamespace.square(5)
,这将返回25。

代码有两个用途:

  • 它将对象/变量保持在匿名函数作用域的局部。这一点很重要,因为我们看到,您可能有多个脚本文件,所有这些文件都可能共享相同的变量名。如果它们共享相同的变量名,则它们可以替换变量值,并真正影响您的应用程序

  • ()
    在行尾调用声明的函数。换句话说,您在第一组括号内创建的匿名函数可以立即自动调用。除非您将其分配给变量,否则将没有其他方法调用它。这样可以避免在内存中创建变量,而只需在runti处调用该函数我


  • 以下是那些从未听说过闭包这个词的人的答案:

    假设我们有一个函数

    function sayHi() { alert('Hello'); }
    
    我们将通过以下操作调用此函数:

    sayHi();
    
    上面这就是所谓的命名函数,如果你不知道这是什么意思,那就是你听到函数这个词时的想法

    在某些语言中,您不必命名函数,可以将其保留为空,如下所示:

    alert('Sup');
    function() {alert('Hello'); }
    3 + 1;
    alert('Peace');
    
    第2行是完全有效的。当然,第2行不会在您的页面中做任何事情,就像第3行不会做任何事情一样。这被称为匿名函数。现在,就像我们可以为第3行分配变量一样:

    result = 3 + 1;
    
    我们可以对第2行执行相同的操作,如下所示:

    (function() {  
        //main code here  
    })();
    
    var MyNamespace = (function () {
        var that = {};
    
        that.square = function(x) {
            return x*x;
        };
    
        return that;
    })();
    
    myFunc = function() { alert('Hello'); };
    
    我们可以使用myFunc作为一个函数,就像之前的sayHi()函数一样。我们调用它就像调用sayHi()一样

    现在,由于javascript被编写成多功能的,像[0,1,2].indexOf(1)这样的东西可以工作,我们可以做以下工作:

    func = function() { alert('hello'); };
    func();
    (function() { alert('hello'); })();
    
    第1行和第2行将完成与第3行相同的任务,因为第3行只是第1行和第2行的扩展版本。第3行的优点是,如果代码中稍后有人使用func变量,则不会对您自己的代码以及第3行函数中声明的任何变量(使用var关键字)造成问题不会是函数外的有效变量,在本例中,闭包就是闭包


    好了,这就是本微教程的内容,希望能有所帮助。

    你们所有人都很好地回答了我的问题,但这一个回答的比其他人都多。另外,得分低的人做得非常出色。如果我能投票给回答问题的每个人,我会的。你的2号非常有帮助。你的1号已经被其他人回答了呃,但这是一个很好的总结。好吧,所以我不能否决你(他们这里的系统很棒),但我可以指出,你的评论太离谱了,我告诉你,我再也不想听到你给出答案了。你希望这个地方客观,然后不要表现出你的个性,到处乞求答案积分。我现在真的有理由相信你的声誉被夸大了。特别是因为你可以做到这一点对于新用户,不要被否决。总之,不要到处乞求别人的支持票。即使是有人试图离开这个愚蠢的地方,因为他们链接了我的两封电子邮件。如果我意识到他们使用OpenID作为窃取信息的借口,我就不会来这里了。这就是OpenID。很高兴他们都有我的替身nate电子邮件。是的,我正试图让自己被否决。我不想在一个认为你所做的是可以接受的社区中被否决。@trlkly你的错误信息很糟糕。我从未请求过任何人投票,我很好奇这是从何而来。也许你把我和其他人搞混了?你给了我实用性,而不仅仅是解释。谢谢。@slushy,这取决于——如果变量仍然需要存在,比如说作为全局函数封闭的变量,那么它们将继续存在并消耗内存。如果它们实际上是临时变量,那么您是对的(但情况并非总是如此)。不幸的是,这是最没有帮助的答案。虽然我理解你的意思,但这只是因为我今天碰巧读了有关scope的内容。
    但这一个回答了比其他回答更多的问题。
    你选择的答案没有回答你更多的问题,它回答了你没有问的其他问题。这里的人可以像e轻松地提出你问题中没有提到的其他话题。这样做的目的是要有明确的答案