立即执行函数IIFE
来源:互联网 发布:淘宝实名认证可以改吗 编辑:程序博客网 时间:2024/05/21 19:40
到底什么是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
- IIFE--立即执行函数
- 关于立即执行函数IIFE
- IIFE 立即执行函数表达式
- 立即执行函数表达式IIFE
- 立即执行函数表达式(IIFE )
- JavaScript立即执行函数表达式(IIFE)
- JS基础---立即执行函数表达式IIFE
- javascript立即执行函数表达式(IIFE)
- IIFE(立即执行函数表达式)
- js 之IIFE 立即执行函数表达式
- JavaScript匿名、具名函数与立即执行函数IIFE详解
- 立即执行函数(IIFE)的理解与运用
- 详解javascript立即执行函数表达式(IIFE)
- 详解javascript立即执行函数表达式(IIFE)
- 详解javascript立即执行函数表达式(IIFE)
- 【WEB开发】JavaScript中的立即执行函数表达式(IIFE)
- javascript模块化编程-详解立即执行函数表达式IIFE
- Bootloader学习笔记
- javascript 报错
- JS正则replace的使用方法
- android关于shape的gradient属性详解
- Ajax和JSF
- 立即执行函数IIFE
- leg_交易方
- LR接口测试REST的接口
- Android Studio git首次部署
- perl put 请求创建elasticsearch 索引
- org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)错误记录
- juicer.js 使用 示例
- 插件化知识详细分解及原理 之代理,hook,反射
- C语言学习------1.3输入输出