閉包1

閉包的定義有很多,但是被定義的對象確是一樣的,只不過看待問題的角度不一樣罷了。都是研究是函數(shù)跟它的作用域合在一起的一種類似于生態(tài)體系的樣子,好像母體和胎兒的意思,畢竟函數(shù)的聲明本身就是也限定了它的作用范圍,引用的變量等等都與作用域有關(guān)。

詞法作用域

函數(shù)的各個變量需要有聲明的,否則就是undefined,要找聲明,先從內(nèi)部找,再從函數(shù)當前所在的作用域(詞法作用域)找,依次往上。
函數(shù)連同它作用域鏈上找的這個變量,共同構(gòu)成閉包。
作用:

  • 封裝數(shù)據(jù)
  • 暫存數(shù)據(jù)
    例子:
function car(){
  var speed = 0
  function fn(){
    speed++
    console.log(speed)
  }
  return fn
} 

var speedUp = car()   //邏輯就是先運行car(),就要運行fn(),就要找變量speed
speedUp()    //1     
speedUp()  //2 

如果沒有里面的fn()返回出來賦值給speedUp,speed運行了就銷毀了。
全局作用域的speedUp是一直存在的,除非關(guān)閉頁面,才會銷毀變量,局部的是運行完以后就銷毀,所以fn也是一直存在的,fn的作用域也要存在,變量speed就保存了。上面的可以這樣:


 var speed = 0
  function fn(){
    speed++
    console.log(speed)
  }
fn()   //1    這就是閉包的兩個要素,函數(shù)和變量。
fn()  //2這里沒有return fn所以沒形成閉包,執(zhí)行了就被銷毀了。
fn()  //3

案例


var fnArr =[]
for (var i =0;i<10;i++){
  fnArr[i] =function(){
    return i
  }
}
console.log(fnArr[3]())  //10不是3,為什么?要fnArr[3](),就要執(zhí)行里面的function,就要return i,
//在哪里,在全局的for循環(huán)里,所以,這時候for循環(huán)早執(zhí)行完了。

如圖:

global全局作用域哦。
改造:

var fnArr=[]
 for(var i=0;i<10;i++){
   fnArr[i]=(function(j){
     return function(){
        return j  
     }
   })(i)
 }
console.log(fnArr[3]())  //3   

立刻執(zhí)行的函數(shù),這時候的i=3造成了
(function(j){
     return function(){
        return j  
     }
   })(i)的i等于3,這時候相當于:
var fn =function(j){
     return function(){
        return j  
     }
執(zhí)行fn(3),相當于找j的值,相當于在函數(shù)內(nèi)加了var j=arguments[0]
//i=3賦值給一個臨時變量,返回這個臨時變量就是這個意思了。
var fnArr=[]
for(var i=0;i<10;i++){
  (function(i){
   fnArr[i] = function(){
    return i
  }
   })(i)
}
console.log(fnArr[3]())//3
這里也是將i=3的值封裝進了return i的包里了,這就是作用域與函數(shù)的奇妙結(jié)合,避免了全局下的i值為10。
var fnArr=[]
for(let i=0;i<10;i++){
  fnArr[i]=function(){
    return i
  }
}
console.log(fnArr[3]())   //3這里是let的用法,作為拓展的,沒有閉包的相關(guān)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容