立即执行函数:自动执行,执行完成以后立即释放
IIFE: immediately-invoked function expression
关于立即执行函数的两种写法
方法1(倾向于写这种,w3c推荐):
(function test(){
}());
方法2:
(function test(){
})();
总结:一定是表达式才能被执行符号执行
函数声明变成表达式的方法 + - ! || &&
1 && function(){
conlog.log(1);
}();
闭包
变量作用域:全局变量和局部变量
闭包:能够读取其他函数内部变量的函数;函数内部和函数外部连接起来的桥梁
<script>
function test(){
var arr = [];
for(var i = 0;i < 10;i++){
arr[i] = function(){
document.write(i+' ');
}
}
return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){
myArr[j]();
}
</script>
通过作用域和作用域链的理解,return arr返回的i是10,当执行myArrj时,实际上就是打印10个10;
打印如下:
如果要打印0~9,可以使用 立即执行函数。
<script>
function test(){
for(var i = 0; i < 10; i++){
(function(){
document.write(i+' ');
})();
}
}
test();
</script>
打印如下:
下面这个方法是最常用,要打印0~9
<script>
function test(){
var arr = [];
for(var i = 0; i < 10; i++){
(function(j){
arr[j] = function(){
document.write(j + ' ');
}
})(i);
}
return arr;
}
var myArr = test();
for(var j = 0;j < 10; j++){
myArr[j]();
}
</script>
打印如下:
这个函数立即执行的时候,形参j就被传入实参i了。
实现一个小需求,当点击ul中的li时,就显示下标。
<script>
var oLi = document.querySelectorAll('li');
for (var i = 0; i < oLi.length; i++) {
(function (j) {
oLi[j].onclick = function () {
console.log(j);
}
})(i);
}
</script>
也是采用立即执行函数,当点击1时,函数立即执行,显示下标0,函数执行完成,立即销毁。
打印如下:
看一下这个有关于立即执行函数的面试题
<script>
var fn = (
function test1() {
return 1;
},
function test2() {
return '2';
}
)();
console.log(typeof(fn));
</script>
打印如下:
解析:当遇到运算符,只会打印后面test2,返回的是string2,所以打印的是string。
再来一个面试题:
<script>
var a = 10;
if(function b(){}){
a += typeof(b);
}
console.log(a);
</script>
打印如下:
解析:括号里面的function是个表达式,表达式忽略函数名,所以b是undefined。