一些Greasemonkey脚本顶部的这一行是什么?

时间:2012-08-17 01:15:45

标签: javascript garbage-collection anonymous-function iife

背景 我有一个自学成才的爱好者对C ++的理解水平,已经转化为对javascript的类似理解。为了更好地理解javascript,我决定编写一个Greasemonkey脚本来解决Google处理multiple results from the same domain的问题。

我写了我的剧本,这简直太容易了。现在我觉得这个脚本对其他人有用,所以我想发布它。在我这样做之前,我想确定我不会发布不负责任的代码。

我知道糟糕的垃圾收集通常被认为是扩展的问题,并且做了一些关于我需要在javascript中做什么以防止这种情况的研究。似乎答案是当函数退出时,函数中包含的任何内存都将被回收。这似乎解释了为什么我看到的一些流行脚本被包含在一个无用的函数中。

这让我想到了这些问题:

  1. 我应该如何处理基本的javascript函数,以确保它不会泄漏内存?
  2. 这是我在许多剧本中看到的答案:

    (function(){  
        //code goes here    
    })();
    
  3. 在上面的代码中,第一个括号的目的是什么?这对我来说似乎是多余的。

  4. 当我试图理解这一行时,我把它重写为:

    (function main(){  
        //code goes here  
    })   
    main();  
    
  5. 这个想法是,这只是调用以前未命名的函数。这不起作用,为什么?

    我对一般答案更感兴趣,但如果需要这里是我当前的代码: http://pastebin.com/qQWKfnJT

3 个答案:

答案 0 :(得分:9)

这种模式(在一对括号中包含一个函数,然后在第一对之后放置另一对)被称为“立即 nvoked F 取消 E xpression“模式(简称IIFE)。它的作用是定义一个匿名函数,然后立即执行它。第一组括号将函数标记为表达式,而不是语句。第二个集合执行从第一个表达式返回的函数:

// This:
(function(){
    // Todo: Add code
})();

// Translates *approximately* to this:
var _anonymous_function_2723113 = function() {
    // Todo: Add code
};
_anonymous_function_2723113();
delete _anonymous_function_2723113;

至于为什么这个功能在你给它命名时不起作用,我建议你阅读kangaxx's article on the subject,尤其是他触及Named Function Expressions的地方。缺点是当你有一个命名函数表达式(而不是一个语句)时,名称假设只能用于函数的范围。

对于三个和四个这么多 - 至于避免内存泄漏,IIFE不是一种避免内存泄漏的方法(正如@elclanrs指出的那样,它只是帮助你避免污染全局范围)。为避免内存泄漏,请避免使用循环引用(请记住,闭包可以是循环引用的来源)。

祝你好运,享受自己!

答案 1 :(得分:0)

这个问题已经so many answers已经......这是一个自我执行的功能。在许多情况下,它用于保护您的代码免受全局范围的影响。它也以其他方式编写:

function(){}()
(function(){})()
(function(){}())
!function(){}()
(function(){}).call(this)

答案 2 :(得分:0)

这是一个示例,可以使用匿名函数: 让我们有4个带有id的元素:id_1,id_2,id_3 ...... 我们想要对每个循环进行循环并分配onclick事件。

for (var i=0; i<5; i++) {
    document.getElementById("id_"+i).onclick = function()  {alert(i)}
}

当你单击元素时,每个元素都会发出相同的警告 - 4.原因是在JavaScript闭包中只存储了局部变量的最后一个值。 你能做什么:

for (var i=0; i<5; i++) {
(function(n){
    document.getElementById("id_"+n).onclick = function() {alert(n)};
})(i);

}