文章地址:
http://benalman.com/news/2010/11/immediately-invoked-function-expression/
最近正在学习javascript一些稍微深层次一点的东西,因此有必要去了解javascript的一些细节。上面的那篇文章讲的就是关于javascript函数立即运行的用法。
在javascript中,每个函数被调用时,都会创建一个新的执行环境,因为在函数内,定义的变量与函数只能在本函数内部才能访问,要从外部访问函数内部的变量也比较简单,那就是在函数内部内部定义一个函数,在这个内部的函数中返回定义的私有变量:
function makeCounter() {
// i 只能在makeCounter内部可以访问
var i = 0;
return function() {
console.log( ++i );
};
}
// 注意,counter与counter2都有它们自己的作用域,相互之间互不干扰
var counter = makeCounter();
counter(); // logs: 1
counter(); // logs: 2
var counter2 = makeCounter();
counter2(); // logs: 1
counter2(); // logs: 2
上面的代码主要就集中在“return function()...”,这其实就是一个传说中的闭包,与java在的内部类有一点相似。
问题的核心:
现在我们定义一个函数,function foo(){} 或者 var foo = function(){},
//这段代码可以正确运行,foo作为一个引用,指向定义的函数
var foo = function(){ alert(""); };
//这个会出错,如果没有显示的告诉解析器,它会认为你在定义一个函数,而不是在执行一个
//表达式,而解析器发现这个函数没有名字,所以会出错。
function(){ alert("==");}();
函数、括号、语法错误:
//这个函数申明是合法有效的,但作为一个申明,它带着一对圆括号,这个是不合法的。
//可以把它作为一个组操作符,但组操作符需要一个表达式
function foo(){ /* code */ }(); // SyntaxError: Unexpected token )
//现在这个带着圆括号的函数有效,不会出错,但这个函数也不会被执行
function foo(){ /* code */ }( 1 );
//它实际上相当于,一个函数后面跟着一个完全不相关的表达式,就像下面这样:
function foo(){ /* code */ };
( 1 );
立即执行函数表达式:
幸运的是,修正这个语法也比较的简单,普遍的方式是用一对圆括号把函数括起来,这样的作用是告诉解析器,这是一个函数表达式而不是一个函数申明。因为括号中可以包含函数申明。
//推荐第一种,但我个人比较喜欢第二种
(function(){ /* code */ }()); // Crockford recommends this one
(function(){ /* code */ })(); // But this one works just as well
//也可以像下面这么用:
var i = function(){ return 10; }();
后面一系列的东西代码有点多了,暂时先翻译到这里。