1.什么是函数?
我们先了解一下对于函数的定义
函数 : 就是将一些功能或语句进行封装,在需要的时候,通过调用的形式,执行这些语句。
在javascript中我们用function来声明一个函数,当我们用typeof返回一个函数的时候,返回值是function类型;如下:
这里的function类型叫做函数方法。
2.函数的作用。
将大量重复的语句抽取出来,写在函数里,以后需要这些语句的时候,可以直接调用函数,避免重复劳动。
简化编程,让编程模块化。高内聚、低耦合。
如下:
console.log("你好");
sayHello(); // 调用函数
// 定义函数
function sayHello(){
console.log("欢迎");
console.log("welcome");
}
3.立即执行函数
它具有函数的基本特征以及作用
首先来看它的写法
(function() {
console.log('我是立即执行函数');
})();
我们看看执行函数的写法
fun();
有没有发现共同之处?
当我们把上面的 (function() {console.log(‘我是立即执行函数’);}) 看成下面的 fun的时候,是不是就一目了然了?
这样可以理解,但是它肯定是有底层逻辑的原因,我们在往下看
函数当我们用到它的时候就可以调用一次,用到多次便多次调用,节省了大量重复语句。
但如果我们有个函数只想让它存在一次,然后就立即销毁,这时候 立即执行函数 就站了出来说了句:这我熟啊。
于是知道立即执行函数除了会被立即销毁,其他的和函数一模一样。
我们来看这个相似处
(1)
如果在这里它不是数学表达式的话,它是什么?
这里它有个名字叫执行符号,这下就解释通了为什么fun();是函数fun在执行了。然而这个执行符号有个问题就是它只能执行表达式,比如看这个
function test(){
var a = 123;
console.log(a);
}();
就会报错。但如果是这样
! function test(){
var a = 123;
console.log(a);
}();
就会输出123,因为后面那个前面有个符号!,这样它就不是函数了,它成为了一个表达式。
包括
var a = function test(){
var a = 123;
console.log(a);
}();
就会输出123,因为后面那个前面有个符号!,这样它就不是函数了,它成为了一个表达式。
包括
var a = function test(){
var a = 123;
console.log(a);
}();
这个就很熟悉了吧, a 的后面是一个表达式,所以他可以执行。
然后我们就会发现个新的问题
这时候我们发现名为test的函数不存在。那为什么会输出123?所以这里不存在的是函数名而非函数。
被执行符号执行的函数自动放弃该函数的名称
所以
(function test() {
console.log('我是立即执行函数');
})();
我们将test自己省略就是个立即执行函数了
(function() {
console.log('我是立即执行函数');
})();
w3c对于立即执行函数有另一种写法
(function() {
console.log('我是立即执行函数');
}());
将括号写到里面。
4.使用立即执行函数解决闭包问题
到这里相信各位童靴已经有想法了,闭包是如何产生的呢?是内部函数调用外部函数的变量时产生的,那么如果内部函数他会被立即销毁的话,内外函数都将作用域链里的执行上下文销毁,就不会产生闭包问题了,这里我们看一个例子
function fun1(){
var a = [];
for(var i=1;i>10;i++){
a[i] = function(){
document.write(i);
}
}
return a;
}
var arr = fun1();
for(var j=1;j>10;j++){
arr[j]();
}
由于生成了闭包打印出了10个10,原本应该是1,2,3,4,5,6,7,8,9,10的。
所以我们将内部函数写成立即执行函数就可以解决这个问题了。
function fun1(){
var a = [];
for(var i=1;i>10;i++){
(function(j){
a[j] = function(){
document.write(j);
}
}(i))
return a;
}
var arr = fun1();
for(var j=1;j>10;j++){
arr[j]();
}
输出12345678910
当我们在内部函数外面套一个立即执行函数就可以阻断闭包的产生了。