Javascript立即调用函数模式

aln*_*fie 12 javascript design-patterns function

你怎么称呼这些模式?他们之间有什么区别?你什么时候用?还有其他类似的模式吗?

(function() {
    console.log(this);  // window
})();

(function x() {
    console.log(this);  // window
})();

var y = (function() {
    console.log(this);  // window
})();

var z = function() {
    console.log(this);  // window
}();
Run Code Online (Sandbox Code Playgroud)

编辑:我刚刚通过在最后两种情况下命名函数,发现了另外两种看似多余的方法...

var a = (function foo() {
    console.log(this);  // window
})();

var b = function bar() {
    console.log(this);
}();
Run Code Online (Sandbox Code Playgroud)

EDIT2: 下面是@GraceShao提供的另一种模式,它使函数可以在函数范围之外访问.

(x = function () {
    console.log(this);  // window
    console.log(x);     // function x() {}
})();
console.log(x);         // function x() {}

// I played with this as well 
// by naming the inside function 
// and got the following:

(foo = function bar() {
    console.log(this);  // window
    console.log(foo);   // function bar() {}
    console.log(bar);   // function bar() {}
})();
console.log(foo);       // function bar() {}
console.log(bar);       // undefined
Run Code Online (Sandbox Code Playgroud)

Pau*_*aul 35

以下是您的函数,其中一些注释描述了它们可能有用的时间/原因:

(function() {
    // Create a new scope to avoid exposing variables that don't need to be
    // This function is executed once immediately
})();

(function fact(i) {
    // This named immediately invoked function is a nice way to start off recursion
    return i <= 1 ? 1 : i*fact(i - 1);
})(10);

var y = (function() {
    // Same as the first one, but the return value of this function is assigned to y
    return "y's value";
})();

var z = function() {
    // This is the exact same thing as above (except it's assigned to z instead of y, of course).
    // The parenthesis in the above example don't do anything since this is already an expression
}();
Run Code Online (Sandbox Code Playgroud)

  • +1值得注意的是,您通常也会存储函数的结果,例如第二个函数. (2认同)

小智 6

在这种情况下,它们在语义上都是相同的.ECMAScript规范包含完整的生产规则,因此这是一个严格的简化.

另请注意,我忽略了命名函数的name(x),因为名称未被使用; 它可以在body中引用,但由于它是一个FunctionExpression(通过语法生成),它永远不会(在正确的 JS实现中)污染包含范围 - 请参阅注释.

(function() {
    console.log(this);  // window
})();

(function x() {
    console.log(this);  // window
})();

var y = (function() {
    console.log(this);  // window
})();

var z = function() {
    console.log(this);  // window
}();
Run Code Online (Sandbox Code Playgroud)

减少(在这种情况下,身体无关紧要,它们都"返回未定义"):

(function() {})();

(function x() {})();

var y = (function() {})();

var z = function() {}();
Run Code Online (Sandbox Code Playgroud)

减少(在ECMAScript语法中FunctionExpression是一个生产规则,但在这里我用它来表示"一个函数的表达式"):

FunctionExpression()

FunctionExpression()

var y = FunctionExpression()

var z = FunctionExpression()
Run Code Online (Sandbox Code Playgroud)

忽略结果的赋值(总是如此undefined)可以看出所有形式都是相同的.

快乐的编码.

  • 请注意,IE(9之前)是一个不正确的JS实现的示例,其中命名函数表达式**会污染包含范围. (3认同)
  • @alnafie是的,你可以很容易地测试它:`(function x(){console.log(this); // window})(); window.x; //在IE> 8或真正的浏览器中未定义 (2认同)