一、閉包的概念
簡單來說:
閉包就是一個(gè)函數(shù)+它的詞法作用域上要找的變量。
詞法作用域:
- 函數(shù)在執(zhí)行的過程中珊楼,先從自己的內(nèi)部作用域找變量;
- 在自己的內(nèi)部沒有找到的話度液,就到這個(gè)函數(shù)聲明所在的作用域(即詞法作用域)里面去找厕宗,依次向上。(最后也沒有找到的話就是undefined或報(bào)錯(cuò))
- 找到的變量是變量當(dāng)前的狀態(tài)堕担,而不一定是聲明時(shí)的狀態(tài)已慢。
作用域鏈:作用域鏈,是由當(dāng)前環(huán)境與上層環(huán)境的一系列變量對(duì)象組成霹购,它保證了當(dāng)前執(zhí)行環(huán)境對(duì)符合訪問權(quán)限的變量和函數(shù)的有序訪問佑惠。
閉包使用的意義:
?1.封裝數(shù)據(jù)
?2.暫存數(shù)據(jù)
二、閉包的案例
經(jīng)典案例:
function car(){
var speed = 0
function fn(){
speed++
console.log(speed)
}
return fn
}
var speedUp = car()
speedUp() //1
speedUp() //2
案例一:
var fnArr = [];
for (var i = 0; i < 10; i++){
fnArr[i] = function(){
return i
};
}
console.log(fnArr[3]()) //10
理解:fnArr是一個(gè)空數(shù)組齐疙,然后去遍歷這個(gè)數(shù)組膜楷,遍歷的時(shí)候給數(shù)組賦值,這個(gè)數(shù)組的值為一個(gè)匿名函數(shù)贞奋,fnArr[3]指向的是一個(gè)函數(shù)赌厅,在for循環(huán)中遍歷的時(shí)候,將i已經(jīng)賦值了轿塔,但是在function()中并沒有賦值變量i特愿,所以在function中找不到的時(shí)候就去它的詞法作用域(for循環(huán)沒有作用域仲墨,所以即是全局作用域)里面去找,因?yàn)閒or循環(huán)執(zhí)行完后i的值為10揍障,所以最終輸出結(jié)果就為10目养。
改造:
case 1 :
var fnArr = []
for(var i = 0; i < 10; i++){
fnArr[i] = (function(j){
return function(){
return j
}
})(i)
}
console.log(fnArr[3]()) //3
case 2:
var fnArr = []
for(var i = 0; i < 10; i++){
(function(i){
fnArr[i] = function(){
return i
}
})(i)
}
console.log(fnArr[3]()) //3
case 3:
var fnArr = []
for(let i = 0; i < 10; i++){
fnArr[i] = function(){
return i
}
}
console.log(fnArr[3]()) //3
案例二:封裝一個(gè)car
var Car = (function(){
var speed = 0;
function set(s){
speed = s
}
function get(){
return speed
}
function speedUp(){
speed++
}
function speedDown(){
speed--
}
return {
setSpeed: setSpeed,
get: get,
speedUp: speedUp,
speedDown: speedDown
}
})()
Car.set(30)
Car.get() //30
Car.speedUp()
Car.get() //31
Car.speedDown()
Car.get() //30