立即执行函数
定义:此类函数没有声明,在一次执行过后即释放(被销毁)。
适合做初始化工作。 针对初始化功能的函数:只想让它执行一次的函数 立即执行的函数也有参数,也有返回值,有预编译
(function () {
var a = 123;
console.log(a);
})
// 立即执行函数的形参和实参;
(function (a, b, c) {
console.log(a + b + c)
}(1, 2, 3))
// 立即执行函数也可以有返回值;
var num = (function (a,b){
return a + b
}(1,2))
console.log(num) // 3
立即执行函数的两种写法
一
(function (){}());
//
在
W3C
建议使用这一种
二
(function (){})();
只有表达式才能被执行符号执行
能被执行符号执行的表达式,这个函数的名字就会被自动忽略(放弃名字)
能被执行符号执行的表达式基本上就是立即执行函数
函数声明和函数表达式是两个东西,虽然都能定义函数
函数声明:
function test ( ){}
函数表达式:
var test = function( ){}
例
function (){
var a = 123;
}()
答案
这是函数声明,不能执行,报语法错误,因为
只有表达式才能被执行符号执行
例
function test(){
console.log(‘a’);
}
答案
这也是函数声明
例
function () {
var a = 123;
}
test();
答案
test()
;就是表达式,所以能执行
例
var test = function (){
console.log(‘
a’);
}()
答案
这是表达式,可以被执行,此时在控制台执行
test
的结果是
undefined
,
这个函
数的名字就会被放弃
例
+ function test(){
console.log(‘a’);
}()
答案
加了个“+“,在趋势上要把他转换成数字,就是表达式了,既然是表达式就 能被执行,就会放弃名字,此时 console.log (test)
,就会报错;这就是立即执行函数
同样放了正号,负号,!就会放弃函数名字,转换成表达式;但是
*
和
/
不行,
&&||
前
面放东西也行
其中
= function (){}
把
function
赋到
test
里面去叫表达式,
var test
是声明 在执行时,会放弃这个函数,储存到 test
里面储存引用,让这个
test
恢复到被声明的状态。
例
(function test(){console.log(‘a’);})()
这个被
()
包起来的
function
函数声明变表达式了,就能被外面的最后的
()
执行
例
(function test(){console.log(‘a’);} ())
最外面的大括号是数学运算符号,是最先被执行,其余的括号都是有语法意义的, 就把函数变表达式了 ()也是数学执行符,能
打印
a
,但是执行
test
就报错,所以干脆就不写
test
例
function test (a, b, c, d){
console.log(a + b + c + d);
}(1, 2, 3, 4);
理论上不能执行,只写
()
就会被当成执行符,但是
(1, 2, 3, 4);
这样写暂时不会当成运 算符,没意义,但是不会执行,也不报错。还能调用 test。
例
先定义一个
10
位数的数组,就是在
var arr = [function () {console.log(i);}
有十个
]
并 且把数组返回
function test() {
var arr = []; //定义一个空数组
for (var i = 0; i < 10; i++) {
//丰满空数组,让空数组添加十条数组, 每一条都是一个
function () {}
arr[i] = function () { //随着 for 循环 i 变,数组 i 也变, arr 每一次都等于一个全新的函数体
document.write(i + “”);
}
}
return arr; //把 arr 返回到外部
}
var myArr = test();
for (var j = 0; j < 10; j++) { //分别执行十个函数体,函数体里面定义了 document.write
myArr[j]();
}
// 答案 10 10 10 10 10 10 10 10 10 10
第二个
for
是为了
打印
这个数组,麻烦写法
myArr[0](); myArr[1]();
。。。
myArr[9](); 过程
for (var i = 0; i < 10; i ++){}
执行了十次,产生了十个彼此独立的函数。并且把这 十个函数放在数组里面去,还把数组返回了,这十个函数和 test
一起产生了一个闭包。
既然是闭包,那么访问
test
里面的变量时,实际上访问的是同一套,而
test
产生了
arr
和
i
变量(写在
for
循环里面的
i
变量),而这十个函数在外边要访问
i
变量,其实
访问的是同一个
i。什么时候访问的?在
test
执行完以后,在下面
for(j)访问的
第一个
i=0
,转到
9
的时候,
i ++
变
10
终止
for
循环,结束的时候
i=10
,结束之后把
return arr
返回,
arr
;
这十个函数都是为了
打印
i
的,在外部访问
i
的时候
i=10
,所以
打印
的是
10;
理解过程:
在这个函数体中,当
arr[0]
时,
document.write(i)
的
i
是不变的,还是
i
,
等函数保存到外部之后,等执行的时候,才会去找
i
的值。
这个赋值语句中,
arr[0] =
函数
;
把一个函数体或者说是一个函数引用赋给数组的当前
位,数组的当前位需要马上被索取出来的(数组现在是当前第几位,我们是知道的, 因为这个是执行语句),当 for(var i = 0)
时,
arr[i]
会变成
arr[0]
,但是这个
i
跟函数体里面的 d.w(i+
“”)里面的
i
是没有关系的,因为函数体
function(){}
不是现在执行,不会在意函数里面写的是什么,不是现在执行那么里面的 document.write
不会变成现实的值,不是现在执行就是函数引用(函数引用就被折叠起来的,系统不知道里 面写的是什么) 在执行 myArr[j]();
的时候,系统才会读
document.write(i +
””
)
里面的语句在定义函数的时候是不看里面的,在执行的时候才看。
例
我们让上面这个变成
打印
0,1,2,3,4,5,6,7,8,9
,用立即执行函数解决
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]();
}
理解过程:
相当于在
for
循环里面有十个立即执行函数
function(j){} 在第一圈 i
是
0
,j 也是
0
,
function(){document.write( j +
“ ”)}
拿着
j=0
,进行循环的第二圈 i
是
1
,又有了一个新的
j
是
1
,反复循环形成了十个立即执行函数,有十个 j
对应
例
for(var i = 0; i < 10; i ++){
console.log(i);
}
答案 0,1,2,3,4,5,6,7,8,9
例for(var i = 0; i < 10; i ++){
(function(){
}())
}
中间
function
这个会执行
10
次
此处延伸(后续添加)
javasicript 闭包及立即执行函数 拓展https://mp.csdn.net/mp_blog/creation/editor/122410892
上一篇:
JavaScript 闭包的作用及用途https://mp.csdn.net/mp_blog/creation/editor/122342968