JS立即执行函数
JS立即执行函数形式与具体应用
首先分清函数声明和函数表达式
//函数声明:
function a() {
//.....
}
//函数表达式:
var b = function(){
//.....
}
注意:函数声明在预编译时,会被提升到最顶部
函数表达式不会被提升
立即执行函数的写法
当一对圆括号跟在函数表达式之后,该函数将成为立即执行函数
立即执行函数的两种常用写法:
(function (){
//执行代码
}());
(function (){
//执行代码
})();
//基本原理可以理解为:
var abc=function(){
console.log(123);
}
abc();
立即函数的实参与形参位置
(function ( a, b, c){
console.log(a + b + c);
})( 1, 2, 3);
//可以理解为:
var abc=function( a, b, c){
console.log(123);
}
abc( 1, 2, 3);
! + - = ()等运算符都能将函数声明或匿名函数转换为函数表达式
例如立即执行函数的其他写法:
+ function a(b){
nsole.log(b);
}(123) //打印出123
- function a(b){
console.log(b);
}(123) //打印出123
! function a(b){
console.log(b);
}(123) //打印出123
但是当立即执行函数有返回值时,! + -这些符号也会和返回值进行运算,从而出现不必要的麻烦,例如:
var a=!function(){
return 123;
}()
console.log(a); //打印出false,因为a接受的为!123运算后的值
所以推荐使用以上两种用()包裹的方法
立即执行函数的应用
- 页面的初始化工作(执行完成后销毁,不会占用空间)
- 避免污染全局变量
- 只执行一次的代码需要变量,将这些临时变量定义成全局变量会非常不好,这时可以将这些变量包裹在立即执行函数中
- 立即执行函数会形成一个单独的作用域
一个典型的例子:
function demo(){
var arr=[];
for(var i = 0; i < 10; i++){
arr[i]=function(){
document.write(i+" ");
}
}
return arr;
}
//循环执行函数,并打印值
var myarr = demo();
for(var k = 0; k < 10; k++){
myarr[k]();
}
最后输出十个10,并不是0到9
因为在该段代码中,生成了十对一的闭包,在匿名函数中的 i 并不会在赋值过程中变现(替换为数字)
arr数组的所有函数拿到的均为demo产生的执行期上下文对象(AO),所以他们共用一个 i
当循环触发时,在向demo中的AO寻找 i 时,i 已经变为10,所以全部打印10
function demo(){
var arr=[];
for(var i = 0; i < 10; i++){
//通过立即执行函数,生成十对十的闭包
//每个函数拿到的都是立即执行函数的执行期上下文(AO),所j不同
(function(j){
arr[j]=function(){
document.write(j + " ");
}
}(i));
}
return arr;
}
var myarr = demo();
for(var k = 0; k < 10; k++){
myarr[k]();
}
通过立即执行函数解决了这一问题,每个匿名函数都在立即执行函数中,即每个函数都有各自的立即执行函数的AO对象
所以每个函数所打印的 j 即为各自AO对象中的 j(因为立即执行函数运行后会被销毁,所以每次循环都会创建新的AO对象,各自 j 的值不会互相影响)