JavaScript中自执行函数的目的是什么?

515

在JavaScript中,什么时候需要使用this:

(function(){
    //Bunch of code...
})();

在这个问题上:

//Bunch of code...

4
请参考这个技术性的 解释,还有这里。 关于语法,请看为什么需要括号它们应该放在哪里 - Bergi
3
@Johnny,这两个括号之前的部分声明了一个(匿名)函数。这两个括号调用了该函数。 - Ej.
10
"IIFE" 是 "立即调用函数表达式" 的更好名称,详情请参见 此链接 - Flimm
这是一篇关于该主题的有用文章。感谢Parth找到它。 - faintsignal
显示剩余3条评论
21个回答

3

简短回答是:为了防止全局(或更高级别)范围的污染。

IIFE(立即调用的函数表达式)是编写插件、附加组件、用户脚本或其他期望与其他人的脚本一起工作的脚本的最佳实践。这确保您定义的任何变量不会对其他脚本产生不良影响。

这是另一种编写IIFE表达式的方法。我个人更喜欢以下方法:

void function() {
  console.log('boo!');
  // expected output: "boo!"
}();

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void

从上面的例子可以清楚地看出,立即调用函数表达式(IIFE)也会影响效率和性能,因为预计只运行一次的函数将只被执行一次,然后被永久地丢弃。这意味着函数或方法声明不会保留在内存中。

不错,我以前没见过 void 的这种用法。我喜欢它。 - Ej.

2
自执行函数用于管理变量的作用域。
变量的作用域是定义它的程序区域。
全局变量具有全局作用域;它在JavaScript代码中的任何地方都可以访问,甚至在函数中也可以。另一方面,在函数中声明的变量仅在函数体内定义。它们是局部变量,具有局部作用域,并且只能在该函数内部访问。函数参数也被视为局部变量,仅在函数体内定义。
如下所示,您可以在函数内部访问全局变量变量,并且请注意,在函数体内,具有相同名称的局部变量优先于全局变量。
var globalvar = "globalvar"; // this var can be accessed anywhere within the script

function scope() {
    alert(globalvar);
    var localvar = "localvar"; //can only be accessed within the function scope
}

scope(); 

基本上,自执行函数允许编写代码而不必考虑其他 JavaScript 代码块中变量的命名方式。


2

您可以使用此函数返回值:

var Test = (function (){
        
        
        const alternative = function(){ return 'Error Get Function '},
        methods = {
            GetName: alternative,
            GetAge:alternative
            }
            
            

// If the condition is not met, the default text will be returned
// replace to  55 < 44
if( 55 > 44){



// Function one
methods.GetName = function (name) {
        
        return name;

};

// Function Two

methods.GetAge = function (age) {
        
        return age;

};





}










    return methods;
    
    
    }());
    
    
    
    
    
    
    
    // Call
   console.log( Test.GetName("Yehia") );

    console.log( Test.GetAge(66) );


我们可以把它当作一个库命名空间来使用吗? - undefined

2

首先,您必须访问MDN IIFE,现在关于此的一些要点

  • 这是立即调用函数表达式。因此,当您的JavaScript文件从HTML中调用时,该函数会立即被调用。
  • 这可以防止在IIFE习语中访问变量以及污染全局范围。

1
(function(){
    var foo = {
        name: 'bob'
    };
    console.log(foo.name); // bob
})();
console.log(foo.name); // Reference error

实际上,上述函数将被视为没有名称的函数表达式。
使用括号包裹函数的主要目的是避免污染全局空间。
函数表达式中的变量和函数成为私有的(即它们在函数外部不可用)。

1

鉴于你的简单问题:“在javascript中,何时想要使用this:…”

我喜欢@ken_browning和@sean_holding的答案,但这里有另一个用例,我没有看到提到:

let red_tree = new Node(10);

(async function () {
    for (let i = 0; i < 1000; i++) {
        await red_tree.insert(i);
    }
})();

console.log('----->red_tree.printInOrder():', red_tree.printInOrder());

其中Node.insert是一种异步操作。

我不能在函数声明时调用await而不使用async关键字,并且我不需要为以后使用命名函数,但需要等待该插入调用或者需要其他更丰富的功能(谁知道呢?)。


1

Javascript中的自执行函数:

自执行表达式是自动开始(调用)的,而不需要被调用。自执行表达式在创建后立即被调用。这主要用于避免命名冲突以及实现封装。变量或声明的对象在该函数之外是不可访问的。为避免最小化问题(filename.min),始终使用自执行函数。


1

由于 Javascript 中的函数是一等对象,因此通过这种方式定义函数,它有效地定义了一个类,类似于 C++ 或 C#。

该函数可以定义局部变量,并且可以在其中拥有函数。内部函数(有效的实例方法)将访问局部变量(有效的实例变量),但它们将与脚本的其余部分隔离。


0

使用这种方法是用于闭包。阅读这个link以了解有关闭包的更多信息。


1
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分,并提供参考链接。 如果链接的页面发生更改,则仅具有链接的答案可能会变得无效。 -来自审核 - user16217248

0

看起来这个问题已经被回答了,但我还是会发表我的意见。

我知道什么时候喜欢使用自执行函数。

var myObject = {
    childObject: new function(){
        // bunch of code
    },
    objVar1: <value>,
    objVar2: <value>
}

该函数允许我使用一些额外的代码来定义childObjects属性和属性,以获得更清晰的代码,例如设置常用变量或执行数学方程式;哦!或者错误检查。与嵌套对象实例化语法相比,这种方法更加灵活。
object: {
    childObject: {
        childObject: {<value>, <value>, <value>}
    }, 
    objVar1: <value>,
    objVar2: <value>
}

一般来说编程有很多晦涩难懂的方式可以实现同样的功能,让你不禁想问:“为什么要这么做?”但是新的情况不断出现,你不能再仅依赖基本/核心原则。


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