立即执行函数IIFE
2017-02-24 15:24
162 查看
到底什么是IIFE?
比较以下两种方式var foo=function(){ /*code*/} foo();
另一种错误的方法:
function(){}(); //Unexpected token
报错原因
JS代码解释的时候,遇到function关键字会默认把它当做一个函数声明,而不是函数表达式,如果没有把它显示表达成函数表达式就会报错。 没有函数名,所以会报错加上函数名
function foo(){}() //unexpected token
加上了名字仍然报错,我们在一个表达式后面加上括号表示这个表达式立即执行。
但如果是一个语句后面加括号,则前后没有关系。以上代码等价于:
function foo(){} ();
相当于先声明了一个叫foo的函数,之后进行()内的表达式运算,但是()(分组操作符)内的表达式不能为空,所以报错。
IIFE正解
(function(){ /* code */ }());
成功,为什么? JS中,括号内部不能包含语句,当解释器对代码进行解释时,先碰到了(),然后碰到function关键字就会自动将()里面的代码识别为函数表达式而不是函数声明~~
IIFE其他更多的写法:
//常用写法 (function(){}()); (function(){})(); //括号 和 JS的一些操作符如(= && || , 等)可以在函数表达式和函数声明上消除歧义 //但是这种写法你不能交换两个的位置,解释器如果是先遇到function关键字就会报错了。 var i=fuction(){return 10;}(); true&&function(){/*code*/}(); 0,function(){}();
一元运算符
!function(){}(); ~function(){}(); -function(){}(); +function(){}();
new操作符
new function(){} new function(){}() //带参数
通过以上的介绍,我们大概了解通过()可以使得一个函数表达式立即执行。
有的时候,我们实际上不需要使用()使之变成一个函数表达式,啥意思?比如下面这行代码,其实不加上()也不会保错:
var i = function(){ return 10; }();
道理还是一样,因为解释器先遇到=号了,就把后面的默认当做表达式处理了
但是好的代码规范
仍然是需要加上括号var i = (function(){ return 10; }());
为了代码的可读性。
IIFE与闭包
IIFE可以配合闭包保存状态在IIFE里面再定义一个函数,这个函数能够引用IIFE内部的变量和参数,利用这一点我们就可以利用IIFE锁住变量的状态了。
//执行后,我们得到了想要的结果,就是因为IIFE把循环变量的每个i都锁在内存中了, //尽管for循环结束后i的值已经变了,但是闭包的原因,其实内存中还是有对这些变量的引用存在,就是说有副本存在。 var elems=document.getElementsByTagName( 'a' ); for ( var i = 0; i < elems.length; i++ ) { (function(lockedIndex){ elems[i].addEventlistener('click',function(e){ e.preventDefault(); console.log('i am '+lockedIndex); },'false'); })(i) }
其实上面的代码中的lockedIndex换成i也是可以的,因为是在两个作用域(形参在内部函数作用域,而传入的i在外部IIFE的作用域)
函数声明和函数提升
有一种值得我们注意的做法:if(condition){ function sayHi(){ alert('Hi'); } }else{ function sayHi(){ //other code } }
这么做是有问题的,在ECMAScript中是无效语法,JS引擎会修改这个错误,转换成合理的状态。 但问题是浏览器尝试修正错误的做法并不一致。
大多数浏览器返回第二个声明,直接忽略condition
但是如果使用函数表达式,那么就没问题:
if(condition){ sayHi=function (){ alert('Hi'); } }else{ sayHi=function (){ //other code } }
应该使用命名函数表达式,而不是callee
//arguments.callee 在严格模式下不通过 function factoral(num){ if(num<=1){ return 1; }else{ return num*arguments.callee(num-1); } } var factoral=(function f(num){ if(num<=1){ return 1; }else{ return num*f(num-1); } })
相关文章推荐
- IIFE-js中(function(){…})()立即执行函数写法理解
- 立即执行函数(IIFE)的理解与运用
- 立即执行函数(IIFE)的理解与运用
- 详解javascript立即执行函数表达式(IIFE)
- JavaScript立即执行函数表达式(IIFE)
- (译)详解javascript立即执行函数表达式(IIFE)
- 立即执行函数(IIFE)的理解与运用
- 立即执行函数表达式(IIFE)
- 立即执行函数(IIFE)的理解与运用
- 详解javascript立即执行函数表达式(IIFE)
- 立即执行函数表达式(IIFE )
- 立即执行函数(IIFE)的理解与运用
- 立即执行函数(IIFE)的理解与运用
- 详解javascript立即执行函数表达式(IIFE)
- (译)详解javascript立即执行函数表达式(IIFE)
- 立即执行函数(IIFE)的理解与运用
- 立即执行函数(IIFE)的理解与运用
- 立即执行函数(IIFE)的理解与运用
- IIFE 立即执行函数表达式
- JavaScript匿名、具名函数与立即执行函数IIFE详解