函数闭包
在函数内部也有一个函数,在内部函数里面用到了外部函数的局部变量,外部函数将内部函数作为返回值返回出去。
函数闭包的意义:通常调用一个函数,函数内的局部变量在函数调用结束后销毁,使用了函数闭包后,局部变量就不会随着原函数的销毁而销毁。例如下面代码中,test函数内的变量a一直存在,a犹如一个全局变量一样存在着。但是为什么不直接定义一个全局变量a,而使用函数闭包呢?全局作用域是一个公共区域,如果为了一个单一的功能而定义一个全局的变量,会导致全局变量过多。因此利用函数闭包,可以减少不必要的全局变量。
function test(){
let a = 0;
return function(){
a++;
console.log(a);
}
}
//可以这么调用
test()();
//也可以
let innerFunction = test(); //首先获取test的内部函数
innerFunction(); //再调用内部函数
innerFunction();
innerFunction();
自执行函数
自执行函数是在函数定义之后立刻自己执行的函数,一般自执行函数没有名字,也正因为没有名字,也只会被执行一次。
自执行函数可以和闭包配合使用,以上述闭包函数的代码为例,我其实是想获取test内部函数,对于外部的test函数其实只是为了产生闭包而临时定义的函数,无所谓叫什么名字。因此,可以将上个例子的代码改成如下方式:
var inner = (function(){
let a = 0;
return function(){
a++;
console.log(a);
}
})();
inner();
inner();
inner();
回调函数
闭包是把一个函数作为了另一个函数的返回值返回,而回调函数则是将一个函数作为另一个函数的参数入参。因为函数本身是一个对象类型,所以既可以当做入参,在另一个函数内部执行,也可以作为返回值将其执行后返回。
我先想了个例子1,把自执行函数作为了入参,在sayhi内部执行。实际使用中,我遇到的很多情况是我需要在一系列操作后再执行某些功能,因此入参函数同时是作为返回值执行的,于是我又想到了个例子2用来说明这种情况。
//例子1:我写完后因为sayhi函数没有return,感觉好像并不能表达得非常清晰。
function sayhi(hi, callback){
callback(hi);
}
sayhi('hello',function(param){
console.log(`${param},world`);
})
sayhi('你好',function(param){
console.log(`${param},世界`);
})
//例子2:callback作为入参,先做些处理,随后又return出去再执行。
function myNumbers(callback){
let a = 1;
let b = 2;
return callback(a,b);
}
function plus(m, n){
return m+n;
}
function minus(m,n){
return m-n;
}
let result1 = myNumbers(plus); //result1 = 3
let result2 = myNumbers(minus); //retsult2 = -1