这种做法在JavaScript中被称为什么?

时间:2010-09-15 17:48:10

标签: javascript design-patterns terminology

将JavaScript代码包装在这样的函数中时:

(function(){

  var field = ...;
  function doSomthing(){...
  ...


})();

我注意到这在很多网页上为我修复了范围问题。这种做法叫做什么?

8 个答案:

答案 0 :(得分:38)

该模式称为自我调用自我调用函数。它可以创建一个闭包,但这是模式的效果(可能是预期的效果),而不是模式本身。

答案 1 :(得分:20)

为了澄清以下评论,大多数创建闭包的时间,它会将您的变量限定为该局部闭包,以免创建全局变量,它既保持清洁,又避免对这些变量进行任何潜在的不必要的改变。

这里有一些很好的答案可以解释为什么更多:How does a javascript closure work?

只有创建闭包时,该范围内的某些内容暴露给外部作用域,通常是的情况,但我无法确定您的示例没有看到更多的代码。如果没有任何东西暴露,那么就没有创建闭包......否则它只是一个立即执行的匿名函数。

最后的})();格式与});相反,实际上是在没有参数的情况下调用该闭包来立即执行。如果您有内容,例如})(something);,那么something将作为第一个参数传递到此处:(function(somethingParam){

答案 2 :(得分:15)

包装函数被称为匿名(它没有名称,也没有分配给变量)自动执行(它自己立即执行)函数。

我不记得看到此模式的确切名称,但它可以防止变量泄漏到全局范围。

答案 3 :(得分:12)

Ben Alman对这种“模式”的常用术语提出了一个有趣的论点。

他的博客文章是here (http://benalman.com/news/2010/11/immediately-invoked-function-expression/)

如果他的帖子对你来说太长了,这里是我的总结(我仍然建议阅读它,因为这个摘要遗漏了很多):

如果你想让一个命名函数自动执行/调用它应该是这样的:

// Hello, my name is "foo". I am a named function.
// When I am invoked I invoke my self when I am invoked.
function foo(){
   foo();
}

如果你想让一个匿名函数自动执行/调用它应该是这样的:

// Hello, I have no name...
//   (though I am assigned to the variable "foo" it's not who I am).
// When I am invoked I invoke my self when I am invoked.
// In ECMAScript 5 I no longer work. :-(
var foo = function(){
    arguments.callee();
};

如果您希望立即执行/调用匿名函数,它应如下所示:

// Hello, I have no name. I am immediately invoked.
// People sometimes call me a "self-invoking anonymous function"...
//    even though I don't invoke myself.
// Ben Alman calls me an "Immediately-Invoked Function Expression"...
//    or "iffy" for short.
(function(){ /...code.../ }());

我对此事的看法:

其他答案是正确的;你所问的通常被称为“自我调用的匿名函数” 但是,该术语并不能准确反映真实情况; “立即调用函数表达式”(简称“iffy”)似乎是一个更合适的术语。


有趣的事实给你的朋友留下深刻印象:

您也可以像这样创建一个Iffy:

!function(){
   alert("immediately invoked!");
}();

+function(){
   alert("immediately invoked!");
}();

或者如果你真的 cRaZy(example):

!1%-+~function(){
   alert("immediately invoked!");
}();

在大多数浏览器中(如果不是全部,我不确定)并且效果将相同(Facebook使用!版本)。

答案 4 :(得分:6)

Douglas Crockford和YUI团队称之为the module pattern

答案 5 :(得分:3)

  

这种做法叫做什么?

简称为immediately-invoked function expression:IIFE。它在表达式中定义一个函数,然后由它自己执行(不将函数分配给任何标识符)。它有时也称为立即执行的函数表达式(IEFE)。

在Ben Alman写他们的博客文章之前,他们也被称为自我调用(匿名)函数,这个术语从那以后变得不常见。它在技术上是不精确的,暗示了一种实际上不会发生的递归调用。

有关语法的详细信息,请参阅Explain the encapsulated anonymous function syntaxLocation of parenthesis for auto-executing anonymous JavaScript functions?

  

我注意到这在很多网页上为我修复了范围问题。

是的,the purpose of this pattern是通过执行一个函数来引入额外的范围。

模式有时也会扩展为返回值,称为(显示)模块模式,或者带有允许递归调用的函数名称。

答案 6 :(得分:2)

它比“模式”更长。这是scheme / lisp中常见的习惯用法,主要用于封装,特别是在进行元编程时。

答案 7 :(得分:0)

版本1: -

function mySpace()
{
    var obj = {};

    obj.name = "Deepak";
    obj.whoami = function ()
    {
        return obj.name;
    }

    window['myObject'] = obj;
}

mySpace();

myName = myObject.whoami();

console.log(myName);

版本2: -

(function(){

    var obj = {};

    obj.name = "Deepak";
    obj.whoami = function ()
    {
        return obj.name;
    }

    window['myObject'] = obj;
})();

myName = myObject.whoami();

console.log(myName);

我们没有调用版本2 中的任何命名函数来初始化myObject,但它可用于全局范围。

您只能链接<script src="jquery.min.js"></script> $ 对象可供使用。这种风格称为自我调用功能。