一.立即执行函数
1.定义
立即执行函数 ( IIFE ):自动执行,执行完成以后立即释放
IIFE: immediately-invoked function expression
2.写法
立即执行函数有两种写法:
- (function( ){
语句; }) ( ); - (function(){
语句; } ( ) ); //两种方法都可以,W3C建议第二种
所以说括号括起来的任何东西即使不是表达式也都会变成表达式(详细看第四点)
和普通函数一样,立即执行函数执行以后就销毁了
3. 立即执行函数传递实参的方式
<script>
(function (a, b) {
console.log(a + b);
}(2, 4));
</script>
4.实例
<script>
function test() {
console.log(1);
} (); //语法错误
</script>
<script>
(function test() {
console.log(1);
} ()); //能执行
</script>
<script>
var test = function test() {
console.log(1);
} (); //能执行
</script>
(1).从第2、3个代码块中可知:一定是表达式才能被执行
从以上第1、2、3个代码块中可知: 括号包起来的变成了表达式才能执行
(2).立即执行函数的销毁
②这里自动执行了,执行完就销毁,所以最后test1 输出undefined
所以说立即执行函数 后面声明的函数名(如test) 会自动忽略
(3)变为表达式的方法
+ function test(){
console.log(10);
}();//能执行
1 || function test(){...} //能执行
0 && function test(){...} //能执行
所以说 在function之前 加运算符(+ - / * %等 甚至|| &&)等会变成表达式从而可以执行函数
二.逗号运算符
逗号运算符只会输出逗号最后面一个
<script>
var num = (2 - 1, 6 + 5, 24 + 1, 66, 77, 1 + 2)
console.log(num);
</script>
三.闭包的深入
(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>
第一个for循环可以理解为:
<script>
function test() {
var arr = [];
var i = 0; /for循环拆开
for ( ;i < 10;) {
arr[i] = function () {
document.write(i + " ")
}
i++; /for循环拆开
}
return arr;
}
</script>
for循环遇到里面小函数的时候,先把自己的弄完 再执行这个小函数
但是return arr;的时候形成了闭包
所以到最后 i 放到大函数的AO里面时已经变成了10,这时再运行小函数时自然返回10
以后看到 return 的时候都要想到闭包
上述函数想返回0到9的话,可以选择使用立即执行函数
<script>
function test() {
for(var i = 0; i < 10; i++){
(function(){
document.write(i+" ");
})();
}
}
</script>
或者:
<script>
function test() {
for(var i = 0; i < 10; i++){
(function(j){ (接受下面传过来的实参)
arr[j] = function(){
document.write(i+" ");
}
})(i); //每次接收for循环的i
}
return arr;
}
······
······
</script>
(2)面试题2
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
var oLi = document.querySelectorAll("li");
for (var i = 0; i < oLi.length; i++) {
oLi[i].onclick = function () {
console.log(i); /输出5
}
}
</script>
而上式去掉函数语句输出为:
for (var i = 0; i < oLi.length; i++) {
console.log(i); /输出0 1 2 3 4
}
即一般for()循环里面出现函数 都会产生闭包。 等它执行完时,还不会执行,只有我onclick 时,它才会执行,此时for循环已经结束,i = 5
(3)面试题3
<script>
var a = 10;
if(function b(){}){
a += typeof(b);
}
console.log(a); //输出10undefined
</script>
function b(){}在if的括号里面, 变成了表达式, 所以此时忽略函数名 b ,语法错误,输出undefined
但是if里边有判断符的话 如 if(1 < function b () { } ) 此时不输出后面的语句
1 > function b(){} 此时不输出后面的语句
1 == function b(){} 此时不输出后面的语句
0 < function b(){} 此时不输出后面的语句
0 && function b(){} 此时不输出后面的语句
0 || function b(){} 此时输出后面的语句
1 && function b(){} 此时输出后面的语句
总结:当表达式内只是函数时输出后面的语句 而里面有判断符时不会输出 逻辑判断符有时会输出后面的语句