立即执行函数
定义:此函数没有声明,在一次执行过后即释放。适合做初始化工作。
格式:
-
(function(){}());
W3C 建议这种
外面一层括号叫数学符号,跟在函数后面的括号叫执行符号。数学符号优先级高于执行符号,会先将数学符号里的变为表达式再执行。 -
(function(){})();
(function (){…})是个表达式 加执行符号()可以执行
<script>
(function add(){
var a = 123;
var b = 234;
console.log(a+b);
}())
</script>
(function add(){…})是个表达式 ,不再是定义函数的语句,函数名add会被忽略,故访问add会报错,因为没有定义add函数
除了执行后立即销毁外,与其他函数没有区别。可以传递参数,也可以有返回值。
<script>
var num=(function (a,b,c){ //里面是个匿名函数
return a+b+c;
}(1,2,4))
console.log(num);
</script>
只有表达式才能被执行符号执行(被()括起来的都叫表达式 如(function test(){…})是个表达式)
<script>
function test(){
var a = 123;
var b = 234;
console.log(a+b)
}
test(); //test是表达式 加执行符号()可以执行
</script>
<script>
function test(){
var a = 123;
var b = 234;
}() //不能执行 因为function test(){...}是函数声明不是表达式
</script>
被执行符号执行的函数表达式 会被自动放弃函数名称
<script>
var test = function(){
console.log('a');
}() // 可以执行 因为var test = function(){...}是函数表达式
</script>
"+""-""!"都能连同后面所接的函数声明变成函数表达式 不再是定义函数的语句
<script>
+function test(){
var a = 123;
var b = 234;
console.log("+");
}()
-function test(){
var a = 123;
var b = 234;
console.log("-");
}()
!function test(){
var a = 123;
var b = 234;
console.log("!");
}()
</script>
访问test会报错 因为没有定义该函数
有个例外:
<script>
function test(a,b,c,d){
console.log(a+b+c+d);
}(1,2,3,4);
</script>
理论上会报错 但系统会理解为
<script>
function test(a,b,c,d){
console.log(a+b+c+d);
}
(1,2,3,4);
</script>
不报错也不执行 test函数不是立即执行函数
例题:
要求调用函数返回的数组打印出0~9的数字
<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>
但输出的结果是
可以在test函数for循环里的函数表达式的末尾添加执行符号()变为立即执行函数来解决输出问题 但被执行符号执行的函数表达式 会被自动放弃函数名称 无法实现题目中要求的调用返回的数组来实现(返回的数组是undefined)
<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>
我们要实现在每一次循环的时候将内部函数需要的i绑定在各自对应的外部函数的作用域中上(当内部函数在执行前被保存到外部 它的作用域中保存的是其对应的的外部函数的作用域)
十次循环会产生十个立即执行函数和其对应的内部函数。当内部函数在外部被调用时,要输出的变量会在其作用域中查找,而内部函数的作用域中保存的就是外部函数的作用域,故可以把i作为实参传递给外部函数
<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>