javascript中的init函数及其工作原理

Ale*_*oev 55 javascript

我经常看到以下代码:

(function () {
  // init part
})();
Run Code Online (Sandbox Code Playgroud)

但我永远无法理解它是如何运作的.我发现最后一个括号特别令人困惑.有人可以解释它在执行上下文(EC)和变量对象(VO)方面的工作原理吗?

And*_*rew 79

我通常向人们解释的方式是展示它与其他JavaScript模式的相似之处.

首先,您应该知道有两种方法来声明一个函数(实际上,至少有五种,但这些是两个主要元凶):

function foo() {/*code*/}

var foo = function() {/*code*/};

即使这种结构看起来很奇怪,你也可能在附加事件时一直使用它:

window.onload=function(){/*code*/};

您应该注意到第二种形式与常规变量声明没有太大区别:

var bar = 5;
var baz = 'some string';
var foo = function() {/*code*/};
Run Code Online (Sandbox Code Playgroud)

但是在JavaScript中,您总是可以选择直接使用值还是通过变量.如果bar5,那么接下来的两个语句是等价的:

var myVal = bar * 100; // use 'bar'
var myVal = 5 * 100;   // don't use 'bar'
Run Code Online (Sandbox Code Playgroud)

那么,如果你可以5自己使用,为什么你也不能自己使用function() {\*code*\}呢?事实上,你可以.这就是所谓的匿名功能.所以这两个例子也是等价的:

var foo = function() {/*code*/}; // use 'foo'
foo();                           

(function(){/*code*/}());        // don't use 'foo' 
Run Code Online (Sandbox Code Playgroud)

您应该看到的唯一区别是在额外的括号中.这只是因为如果你用关键字开始一行function,解析器会认为你使用这个答案顶部的第一个模式声明一个函数并抛出一个语法错误异常.因此,将整个匿名函数包装在一对括号中,问题就会消失.

换句话说,以下三个陈述是有效的:

5;                        // pointless and stupid
'some string';            // pointless and stupid
(function(){/*code*/}()); // wonderfully powerful
Run Code Online (Sandbox Code Playgroud)

  • "我通常向人们解释的方式是展示它与其他JavaScript模式的相似之处." 这非常有帮助,所以谢谢你花时间做那个:) (2认同)
  • @RayLoveless,对于胖箭头函数来说,情况似乎并非如此 (() => {console.log('<----------------> 我在这里! <--- ------------>')}()) 运行失败 while (function () {console.log('<---------------->我在这里! <---------------->')})() 工作得很好,这是一个非常古老的评论,但掌握这些变化仍然很有趣。谢谢你的回答,顺便说一句。 (2认同)

ken*_*ken 48

该模式将创建一个新的执行上下文(EC),其中任何本地变量对象(VO)将存在,并且当EC退出时同样会死亡.这一生的唯一例外是VO,它成为闭包的一部分.

请注意,JavaScript没有神奇的"初始化"功能.您可以将此模式与此类型相关联,因为大多数任何自尊的JS库(jQuery,YUI等)都会执行此操作,以便它们不会污染全局NS,而不是他们需要的.

示范:

var x = 1; // global VO
(function(){        
    var x = 2; // local VO
})();
x == 1; // global VO, unchanged by the local VO
Run Code Online (Sandbox Code Playgroud)

第二组"括号"(实际上称为括号或一组括号)只是调用它前面的函数表达式(由前面的括号组定义).

  • 我没有定义EC和VO,因为最初的问题包含了这些问题的定义,所以如果您阅读了问题,那么您应该已经知道它们的含义;)另外,这2页可能有助于您更好地理解EC/VO(变量): 1. http://jibbering.com/faq/ 2. http://jibbering.com/faq/notes/closures/ (14认同)
  • 现在,如果你向那些不​​理解的开发人员解释了EC和VO是什么,那么我会给你一个向上投票,但不是一个完整的答案,而是我可能要用谷歌缩略语. (7认同)

Guf*_*ffa 26

代码创建一个匿名函数,然后立即运行它.相近:

var temp = function() {
  // init part
}
temp();
Run Code Online (Sandbox Code Playgroud)

这种结构的目的是为函数内部的代码创建一个范围.您可以在范围内声明变量和函数,这些变量和函数将在该范围内.这样他们就不会混淆全局范围,从而最大限度地降低与其他脚本冲突的风险.

  • @ken:人们似乎喜欢我如何解释代码的作用,以及为什么使用代码.仅仅因为我没有使用你所使用的确切术语,所以不会错. (3认同)

SEo*_*EoF 16

我无法相信没有人回答了操作问题!

最后一组括号用于将参数传递给匿名函数.因此,以下示例创建一个函数,然后使用x = 5和y = 8运行它

(function(x,y){
    //code here
})(5,8)
Run Code Online (Sandbox Code Playgroud)

这似乎没那么有用,但它有它的位置.我见过的最常见的是

(function($){
    //code here
})(jQuery)
Run Code Online (Sandbox Code Playgroud)

这允许jQuery处于兼容模式,但您可以在匿名函数中将其称为"$".


小智 7

自我调用匿名函数(SIAF)

即使DOM没有完全准备就绪,自动调用函数也会立即运行.

jQuery document.ready vs自调用匿名函数


归档时间:

查看次数:

113145 次

最近记录:

7 年,6 月 前