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

时间:2022-05-08 18:14:39

I often see the following code:

我经常看到以下代码:

(function () {
  // init part
})();

but I never could get my head around how it works. I find the last brackets especially confusing. Could someone explain how it works in terms of Execution Contexts (EC) and Variable Objects (VO)?

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

7 个解决方案

#1


47  

That pattern will create a new execution context (EC) in which any local variable objects (VO's) will live, and will likewise die when the EC exits. The only exception to this lifetime is for VO's which become part of a closure.

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

Please note that JavaScript has no magic "init" function. You might associate this pattern with such since most any self-respecting JS library (jQuery, YUI, etc.) will do this so that they don't pollute the global NS more than they need to.

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

A demonstration:

示范:

var x = 1; // global VO
(function(){        
    var x = 2; // local VO
})();
x == 1; // global VO, unchanged by the local VO

The 2nd set of "brackets" (those are actually called parens, or a set of parentheses), are simply to invoke the function expression directly preceding it (as defined by the prior set of parenthesis).

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

#2


79  

The way I usually explain this to people is to show how it's similar to other JavaScript patterns.

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

First, you should know that there are two ways to declare a function (actually, there's at least five, but these are the two main culprits):

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

function foo() {/*code*/}

function foo(){/ * code * /}

and

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

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

Even if this construction looks strange, you probably use it all the time when attaching events:

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

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

在window.onload =函数(){/ *代码* /};

You should notice that the second form is not much different from a regular variable declaration:

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

var bar = 5;
var baz = 'some string';
var foo = function() {/*code*/};

But in JavaScript, you always have the choice between using a value directly or through a variable. If bar is 5, then the next two statements are equivalent:

但在JavaScript中,您始终可以选择直接使用值还是通过变量。如果bar为5,则接下来的两个语句是等效的:

var myVal = bar * 100; // use 'bar'
var myVal = 5 * 100;   // don't use 'bar'

Well, if you can use 5 on its own, why can't you use function() {\*code*\} on its own too? In fact, you can. And that's called an anonymous function. So these two examples are equivalent as well:

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

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

(function(){/*code*/}());        // don't use 'foo' 

The only difference you should see is in the extra brackets. That's simply because if you start a line with the keyword function, the parser will think you are declaring a function using the very first pattern at the top of this answer and throw a syntax error exception. So wrap your entire anonymous function inside a pair of braces and the problem goes away.

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

In other words, the following three statements are valid:

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

5;                        // pointless and stupid
'some string';            // pointless and stupid
(function(){/*code*/}()); // wonderfully powerful

#3


26  

The code creates an anonymous function, and then immediately runs it. Similar to:

代码创建一个匿名函数,然后立即运行它。如同:

var temp = function() {
  // init part
}
temp();

The purpose of this construction is to create a scope for the code inside the function. You can declare varaibles and functions inside the scope, and those will be local to that scope. That way they don't clutter up the global scope, which minimizes the risk for conflicts with other scripts.

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

#4


15  

I can't believe no-one has answered the ops question!

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

The last set of brackets are used for passing in the parameters to the anonymous function. So, the following example creates a function, then runs it with the x=5 and y=8

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

(function(x,y){
    //code here
})(5,8)

This may seem not so useful, but it has its place. The most common one I have seen is

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

(function($){
    //code here
})(jQuery)

which allows for jQuery to be in compatible mode, but you can refer to it as "$" within the anonymous function.

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

#5


7  

Self invoking anonymous function (SIAF)

自我调用匿名函数(SIAF)

Self-invoking functions runs instantly, even if DOM isn't completely ready.

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

jQuery document.ready vs self calling anonymous function

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

#6


1  

In simple word you can understand that whenever page load, by this second pair of brackets () function will have called default.We need not call the function.It is known as anonymous function.

简单来说你可以理解,每当页面加载时,通过这第二对方括号()函数都会调用default.We不需要调用函数。它被称为匿名函数。

i.e.

(function(a,b){
//Do your code here
})(1,2);

It same like as

和它一样

var test = function(x,y) {
  // Do your code here
}
test(1,2);

#7


1  

Its is called immediatly invoking function expression (IIFE). Mainly associated with the JavaScript closure concept. Main use is to run the function before the global variable changed, so that the expected behaviour of code can be retained.

它被称为immediatly调用函数表达式(IIFE)。主要与JavaScript闭包概念相关联。主要用途是在全局变量更改之前运行该函数,以便可以保留代码的预期行为。

#1


47  

That pattern will create a new execution context (EC) in which any local variable objects (VO's) will live, and will likewise die when the EC exits. The only exception to this lifetime is for VO's which become part of a closure.

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

Please note that JavaScript has no magic "init" function. You might associate this pattern with such since most any self-respecting JS library (jQuery, YUI, etc.) will do this so that they don't pollute the global NS more than they need to.

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

A demonstration:

示范:

var x = 1; // global VO
(function(){        
    var x = 2; // local VO
})();
x == 1; // global VO, unchanged by the local VO

The 2nd set of "brackets" (those are actually called parens, or a set of parentheses), are simply to invoke the function expression directly preceding it (as defined by the prior set of parenthesis).

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

#2


79  

The way I usually explain this to people is to show how it's similar to other JavaScript patterns.

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

First, you should know that there are two ways to declare a function (actually, there's at least five, but these are the two main culprits):

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

function foo() {/*code*/}

function foo(){/ * code * /}

and

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

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

Even if this construction looks strange, you probably use it all the time when attaching events:

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

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

在window.onload =函数(){/ *代码* /};

You should notice that the second form is not much different from a regular variable declaration:

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

var bar = 5;
var baz = 'some string';
var foo = function() {/*code*/};

But in JavaScript, you always have the choice between using a value directly or through a variable. If bar is 5, then the next two statements are equivalent:

但在JavaScript中,您始终可以选择直接使用值还是通过变量。如果bar为5,则接下来的两个语句是等效的:

var myVal = bar * 100; // use 'bar'
var myVal = 5 * 100;   // don't use 'bar'

Well, if you can use 5 on its own, why can't you use function() {\*code*\} on its own too? In fact, you can. And that's called an anonymous function. So these two examples are equivalent as well:

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

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

(function(){/*code*/}());        // don't use 'foo' 

The only difference you should see is in the extra brackets. That's simply because if you start a line with the keyword function, the parser will think you are declaring a function using the very first pattern at the top of this answer and throw a syntax error exception. So wrap your entire anonymous function inside a pair of braces and the problem goes away.

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

In other words, the following three statements are valid:

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

5;                        // pointless and stupid
'some string';            // pointless and stupid
(function(){/*code*/}()); // wonderfully powerful

#3


26  

The code creates an anonymous function, and then immediately runs it. Similar to:

代码创建一个匿名函数,然后立即运行它。如同:

var temp = function() {
  // init part
}
temp();

The purpose of this construction is to create a scope for the code inside the function. You can declare varaibles and functions inside the scope, and those will be local to that scope. That way they don't clutter up the global scope, which minimizes the risk for conflicts with other scripts.

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

#4


15  

I can't believe no-one has answered the ops question!

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

The last set of brackets are used for passing in the parameters to the anonymous function. So, the following example creates a function, then runs it with the x=5 and y=8

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

(function(x,y){
    //code here
})(5,8)

This may seem not so useful, but it has its place. The most common one I have seen is

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

(function($){
    //code here
})(jQuery)

which allows for jQuery to be in compatible mode, but you can refer to it as "$" within the anonymous function.

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

#5


7  

Self invoking anonymous function (SIAF)

自我调用匿名函数(SIAF)

Self-invoking functions runs instantly, even if DOM isn't completely ready.

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

jQuery document.ready vs self calling anonymous function

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

#6


1  

In simple word you can understand that whenever page load, by this second pair of brackets () function will have called default.We need not call the function.It is known as anonymous function.

简单来说你可以理解,每当页面加载时,通过这第二对方括号()函数都会调用default.We不需要调用函数。它被称为匿名函数。

i.e.

(function(a,b){
//Do your code here
})(1,2);

It same like as

和它一样

var test = function(x,y) {
  // Do your code here
}
test(1,2);

#7


1  

Its is called immediatly invoking function expression (IIFE). Mainly associated with the JavaScript closure concept. Main use is to run the function before the global variable changed, so that the expected behaviour of code can be retained.

它被称为immediatly调用函数表达式(IIFE)。主要与JavaScript闭包概念相关联。主要用途是在全局变量更改之前运行该函数,以便可以保留代码的预期行为。