掌握作用域与作用域链就可以着手学习闭包了,但是不急,在此之前我们先来看一类很有特色的函数——立即执行函数
1. 作用
在编程中,我们会需要函数来使代码更模块化,但这些函数有的可能只会调用一次就不再调用。此类函数可称为初始化函数(或初始化功能的函数),为了让这些函数调用一次后自动销毁来避免空间的浪费,我们使用立即执行函数,在执行完会立即释放空间
2. 举个例子
function abc() {
var a = 123;
var b = 456;
console.log(a + b);//579
}
abc();
console.log(abc);//function abc(){
// ...
// }
普通函数执行后并不会立即销毁
(function abc() {
var a = 123;
var b = 456;
console.log(a + b);//579
}())
console.log(abc);//error abc is not defined
而上面的函数,执行完后被立即销毁,这样的函数称为立即执行函数
3. 形式
(function(){
...
}()) //W3C推荐
(function(){
...
})()
以上两种为立即执行函数的标准形式,第一种形式为W3C推荐形式
立即执行函数除了执行完立即销毁以外,与普通函数无任何区别
var 接收变量 = (function(形参) {
return 返回值
}(实参))
var test = (function(a, b) {
return a + b;
}(1, 2))
console.log(test);//3
4. 拓展
立即执行函数并不是JavaScript的特殊语法,只是表达式利用执行符号( )得出的产物。首先,我们还是再次复习一下函数定义的两种常见方式
//1.函数声明
function test() {
...
}
//2.函数表达式
var test = function() {
...
};
我们来看一下在函数声明后加上执行符号会出现什么样的效果
function test() {
console.log('可以被执行哦');
}();//error
而正常的调用函数
function test() {
console.log('可以被执行哦');//可以被执行哦
}
test();
由此得出结论 只有表达式才能被执行符号( )执行(test也是表达式),而函数声明并不能被执行符号执行,那函数表达式呢?
var test = function() {
console.log('可以被执行哦'); //可以被执行哦
} ();
能被执行符号执行的函数,函数名会被自动忽略(失去对函数的引用)
var test = function() {
console.log('可以被执行哦'); //可以被执行哦
} ();
console.log(test);//undefined
对于函数声明,可以通过将其变为表达式来立即执行
+ function test() {
console.log('可以被执行哦');//可以被执行哦
}();
console.log(test);//error test is not defined
- function test() {
console.log('可以被执行哦');//可以被执行哦
}();
console.log(test);//error test is not defined
! function test() {
console.log('可以被执行哦');//可以被执行哦
}();
console.log(test);//error test is not defined
//* /不能将函数声明变为表达式,+ - 当作正负号看待
来点刺激的
将( )看作数学运算符,来将函数声明变为表达式
(function test(){
console.log('可以被执行哦');可以被执行哦
})();
console.log(test);//error test is not defined
胆子再大点,将执行符( )放在运算符( )中
(function test(){
console.log('可以被执行哦');可以被执行哦
}());
console.log(test);//error test is not defined
再精简点,将本就会被忽略的函数名给省略,就成为了立即执行函数的标准形式
(function(){
console.log('可以被执行哦');//可以被执行哦
}());
5. 诡异的面试题
function test(a, b) {
console.log(a + b);
}(1, 2)
按理说这样的写法会报错,因为函数声明并不能被执行符执行,可javascript引擎会尽可能少报错,所以会将以上代码中的( )理解为运算符( ),而里面的内容会理解为逗号表达式
function test(a, b) {
console.log(a + b);
}
(1, 2)//被运算符()包裹的逗号表达式
所以上述代码并不会报错,也不会执行,可在下方调用函数来执行
function test(a, b) {
console.log(a + b);//3
}(1, 2)
test(1, 2);
立即执行函数可用来解决闭包带来的常见错误,所以也尤为重要。
本文根据渡一教育JavaScript视频总结,有兴趣的可去b站搜索观看。
https://www.bilibili.com/video/av64563473?t=4640&p=14