将JavaScript代码包装在这样的函数中时:
(function(){
var field = ...;
function doSomthing(){...
...
})();
我注意到这在很多网页上为我修复了范围问题。这种做法叫做什么?
答案 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 syntax和Location of parenthesis for auto-executing anonymous JavaScript functions?。
我注意到这在很多网页上为我修复了范围问题。
是的,the purpose of this pattern是通过执行一个函数来引入额外的范围。
模式有时也会扩展为返回值,称为(显示)模块模式,或者带有允许递归调用的函数名称。
答案 6 :(得分:2)
它比“模式”更长。这是scheme / lisp中常见的习惯用法,主要用于封装,特别是在进行元编程时。
答案 7 :(得分:0)
function mySpace()
{
var obj = {};
obj.name = "Deepak";
obj.whoami = function ()
{
return obj.name;
}
window['myObject'] = obj;
}
mySpace();
myName = myObject.whoami();
console.log(myName);
(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>
和 $ 对象可供使用。这种风格称为自我调用功能。