JS 立即执行函数可以让函数在创建后立即执行,这种模式本质上就是函数表达式(命名的或者匿名的),在创建后立即执行。
1、立即执行函数的写法
立即执行函数通常有下面两种写法:
(function(){ ... })(); (function(){ ... }()); //错误的写法 function (){ ... }(); //报错: Uncaught SyntaxError: Unexpected token (
第三种写法报错的原因是,Javascript引擎看到function关键字之后,认为后面跟的是函数定义语句,而在一条语句后面加上() 会被当做分组操作符,分组操作符里必须要有表达式,所以这里报错,不应该以圆括号结尾。以圆括号开头,引擎就会认为后面跟的是一个表示式,而不是函数定义,所以就避免了错误。
让Javascript引擎认为这是一个表达式的方法还有很多:
!function(){}(); +function(){}(); -function(){}(); ~function(){}(); new function(){ /* code */ } new function(){ /* code */ }() // 只有传递参数时,才需要最后那个圆括号
2、立即执行函数的作用
立即执行函数只有一个作用:创建一个独立的作用域。这个作用域里面的变量,外面访问不到(即避免了「变量污染」)。
面试题:
var liList = ul.getElementsByTagName('li') for(var i=0; i<6; i++){ liList[i].onclick = function(){ alert(i) // 为什么 alert 出来的总是 6,而不是 0、1、2、3、4、5 } }
因为输出的 i 是全局作用域的,当循环结束后 i 的值是 6,所以输出的 i 就是6。
用立即执行函数给每个 li 创造一个独立作用域即可,此时 i 无法被循环改变,因为 i 是在独立的作用域里,外面无法访问到。
var liList = ul.getElementsByTagName('li') for(var i=0; i<6; i++){ !function(j){ liList[j].onclick = function(){ alert(j) // 0、1、2、3、4、5 } }(i) }