当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在javascript中自执行函数的目的是什么?》经验,为你挑选了9个好方法。

在javascript中,你想什么时候使用它:

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

对此:

//Bunch of code...

Ken Browning.. 385

一切都与变量范围有关.默认情况下,在自执行函数中声明的变量仅可用于自执行函数中的代码.这允许编写代码而不用考虑如何在其他javascript代码块中命名变量.

例如:

(function(){ 
    var foo = 3; 
    alert(foo); 
})(); 

alert(foo); 

这将首先警告"3",然后在下一个警报上抛出错误,因为未定义foo.



1> Ken Browning..:

一切都与变量范围有关.默认情况下,在自执行函数中声明的变量仅可用于自执行函数中的代码.这允许编写代码而不用考虑如何在其他javascript代码块中命名变量.

例如:

(function(){ 
    var foo = 3; 
    alert(foo); 
})(); 

alert(foo); 

这将首先警告"3",然后在下一个警报上抛出错误,因为未定义foo.


例如(对于那些对我有帮助的人):`(function(){var foo = 3; alert(foo);})(); alert(foo);`将首先警告"3",然后在下一个警报上抛出错误,因为未定义foo.
而且为了包括一大堆Netflix工程师在内的许多人的利益:它只是一个功能.它本身并不代表封闭.有时候自动调用者会与封闭相关的场景一起使用来做整洁的事情,但是如果你没有看到某些东西坚持使用垃圾收集并使用非封闭语言进行的引用,它就没有任何内容与CLOSURES有关.

2> 小智..:

简单化.看起来很正常,几乎让人感到安慰:

var userName = "Sean";

console.log(name());

function name() {
  return userName;
}

然而.如果我在页面中包含一个非常方便的javascript库,将高级字符转换为基本级别表示,该怎么办?

等等......什么?

我的意思是.如果有人输入带有某种重音的角色(例如法语或西班牙语),但我只想要'英语'字符?Az在我的节目中?嗯......西班牙语'n~'和法语'e /'字符(我为这些字符分别使用了两个字符,但你可以在表达重音的字符中进行精神跳跃),这些字符可以被翻译成为'n'和'e'的基本字符.

所以有一个好人已经写了一个全面的字符转换器,我可以包括在我的网站...我包括它.

一个问题:它有一个名为'name'的函数,与我的函数相同.

这就是所谓的碰撞.我们在相同的范围内声明了两个具有相同名称的函数.我们想避免这种情况.

所以我们需要以某种方式确定代码的范围.

在javascript中扩展代码范围的唯一方法是将其包装在函数中:

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter libarary's name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

这可能会解决我们的问题.现在所有东西都是封闭的,只能从我们的开始和结束括号中访问.

我们在函数中有一个函数......这看起来很奇怪,但完全合法.

只有一个问题.我们的代码不起作用.我们的userName变量永远不会回显到控制台!

我们可以通过在现有代码块之后添加对函数的调用来解决此问题...

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter libarary's name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

main();

或之前!

main();

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter libarary's name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

次要问题:"主要"这个名称还没有被使用的可能性有多大?......非常非常苗条.

我们需要更多的范围.以及一些自动执行main()函数的方法.

现在我们来到自动执行功能(或自动执行,自运行,等等).

((){})();

语法像罪一样尴尬.但是,它的工作原理.

当您将函数定义包装在括号中并包含参数列表(另一组或括号!)时,它将充当函数调用.

所以让我们再看一下我们的代码,使用一些自动执行的语法:

(function main() {
  var userName = "Sean";

    console.log(name());

    function name() {
      return userName;
    }
  }
)();

因此,在您阅读的大多数教程中,您现在将使用"匿名自执行"或类似的术语进行轰炸.

经过多年的专业开发,我强烈建议您为调试目的命名您编写的每个函数.

当出现问题时(它会出现问题),您将在浏览器中检查回溯.它总是更容易缩小你的代码的问题时,在堆栈跟踪中的条目有名字!

非常啰嗦,我希望它有所帮助!


谢谢:)我一直在搜索互联网,试图了解IIFE在可变隐私方面与正常功能相关的优势,你的答案就是最好的.每个人都说,最好的优势之一是,当正常功能只给你完全相同的东西时,IIFE内部的变量和函数是"最终"私有的.最后我想我通过你的解释过程得到了它.毕竟IIFE只是一个功能,但现在我明白了为什么要使用它.再次感谢你!

3> M A Hossain ..:

自调用(也称为自动调用)是函数在定义时立即执行的.这是一个核心模式,是许多其他JavaScript开发模式的基础.

它是一个伟大的粉丝:)因为:

它将代码保持在最低限度

它强制将行为与表达分开

它提供了一个阻止命名冲突的闭包

极大 - (为什么你应该说它好?)

它是关于一次定义和执行一个函数.

您可以让该自执行函数返回一个值,并将该函数作为参数传递给另一个函数.

封装很有用.

它也适用于块范围.

是的,您可以将所有.js文件包含在自执行功能中,并可以防止全局命名空间污染.;)

更多这里.


要点1.怎么样?第2点.那是一种完全不同的最佳实践.要点3.什么功能没有?4,5,6,7.关联?嗯,我猜是1/8也不错.
迟了七年,但是,对于第1点,它根本不会减少代码,实际上它在创建函数时至少添加了两行代码.

4> Christoph..:

命名空间.JavaScript的范围是功能级别的.


downvotes仍在进行,因为我使用*namespacing*instad of*scoping*; 这是一个定义问题 - 参见[维基百科](http://en.wikipedia.org/wiki/Namespace):*计算机科学中的命名空间(有时也称为名称范围),是一个抽象的容器或创建的环境保持唯一标识符或符号(即名称)的逻辑分组.*和*名称空间标识符可以为名称提供上下文(计算机科学中的范围),这些术语有时可互换使用.*
Javascript的函数级范围提供变量名称所在的空间,*namespace*; 它是一个与命名空间标识符无关的匿名者是无关紧要的......

5> David W. Kei..:

我不敢相信没有提到暗示全局的答案.

(function(){})()构造不能防止隐含的全局变量,这对我来说是更大的问题,请参阅http://yuiblog.com/blog/2006/06/01/global-domination/

基本上,功能块确保您定义的所有相关"全局变量"仅限于您的程序,它不会保护您不会定义隐式全局变量.JSHint等可以提供有关如何防御此行为的建议.

更简洁的var App = {}语法提供了类似的保护级别,并且可以在"公共"页面上包含在功能块中.(有关使用此构造的库的真实示例,请参阅Ember.js或SproutCore)

private属性来说,除非你要创建公共框架或库,否则它们会被高估,但如果你需要实现它们,Douglas Crockford有一些好主意.


严格模式可以防止隐含的全局变量.与自动调用程序一起使用可以让你满意.我从未理解过私人财产的喧嚣.在func构造函数中声明变量.完成.如果忘记使用'new'关键字的想法让你夜不能寐,请写一个工厂函数.再做一次.

6> Lonely..:

我已经阅读了所有答案,在此遗漏了一些非常重要的内容,我会接吻。有两个主要原因,为什么我需要自执行匿名函数,或者最好说“ 立即调用函数表达式(IIFE) ”:

    更好的名称空间管理(避免名称空间污染-> JS模块)

    封闭(模拟私有类成员,从OOP已知)

第一个已经很好地解释了。对于第二个,请研究以下示例:

var MyClosureObject = (function (){
  var MyName = 'Michael Jackson RIP';
  return {
    getMyName: function () { return MyName;},
    setMyName: function (name) { MyName = name}
  }
}());

注意1:我们没有分配功能MyClosureObject,更何况是调用该功能的结果。请注意()最后一行。

注意2:您还需要进一步了解Java语言中的函数,即内部函数可以访问内部定义的函数的参数和变量

让我们尝试一些实验:

我可以MyName使用了getMyName,它可以工作:

 console.log(MyClosureObject.getMyName()); 
 // Michael Jackson RIP

以下巧妙的方法不起作用:

console.log(MyClosureObject.MyName); 
// undefined

但是我可以设置另一个名称并获得预期的结果:

MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName()); 
// George Michael RIP

编辑:在上面的示例MyClosureObject中设计为不带new前缀使用,因此按照惯例,不应将其大写。



7> stesch..:

是否有参数和"一堆代码"返回一个函数?

var a = function(x) { return function() { document.write(x); } }(something);

关闭.something分配给的函数使用的值的值a.something可以有一些不同的值(for循环)和每次a有一个新的功能.



8> chaos..:

范围隔离,也许.这样函数声明中的变量不会污染外部命名空间.

当然,在那里的JS实现的一半,他们无论如何.


这将是什么实现?

9> sg.cc..:

这是一个自我调用匿名函数如何有用的可靠示例.

for( var i = 0; i < 10; i++ ) {
  setTimeout(function(){
    console.log(i)
  })
}

输出: 10, 10, 10, 10, 10...

for( var i = 0; i < 10; i++ ) {
  (function(num){
    setTimeout(function(){
      console.log(num)
    })
  })(i)
}

输出: 0, 1, 2, 3, 4...

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有