### 閉包
* * * * *
> 在《javascript高級程序設計第三版》中有講到:“閉包”是指有權訪問另一個函數作用域中的變量的“函數”
> 通俗理解:“閉包”就是一個函數,只不過在這個函數內部可以訪問到其他函數的作用域中的變量。
##### **這里涉及了很多關于js作用域鏈的知識,可以先行百度“javascript作用域鏈”并理解作用域鏈后再來看,本文只對作用域鏈做簡單介紹**
> 在javascript中,當某個函數被調用時,會創建一個執行環境(execution context)以及與這個執行環境相對應作用域鏈,使用arguments(***函數的參數對象,function對象默認自帶,無需聲明,function內部可以調用***)和其他命名參數的值來初始化當前函數的活動對象(activation object),但在作用域鏈中,外部函數的活動對象始終處于第二位,外部函數的外部函數的活動對象處于第三位...以此類推直至作用域鏈終點的全局執行環境(***這里有點類似于對象的原型鏈可以一直向上追溯到object對象***)。
> 接下來,我們一步一步實現一個閉包
~~~
//首先創建一個com函數,這個函數內返回一個匿名函數,匿名函數有兩個參數
function com(propertyName){
return function(obj1,obj2){
let value1 = obj1[propertyName]
let value2 = obj2[propertyName]
if(value1 < value2){
return -1
}else if(value1 > value2){
return 1
}else{
return 0
}
}
}
//將com函數賦值給coms,此時的coms變量接收的是com函數return的匿名函數
let coms = com("name")
//然后調用coms函數
let values = coms({name:2},{name:1})
console.log(values) // 此處打印 -1
//接觸對匿名函數的引用,以便釋放內存,否則容易內存溢出
coms = null
~~~
> 上面例子就是一個典型的閉包案例,因為com返回對匿名函數中包含了com的作用域鏈,所以可以通過匿名函數來實現引用com作用域內的變量和參數,以達到引用其他函數作用域中的變量的目的!
> ??注意:關于閉包中this的引用,this默認是與執行環境綁定的,在嚴格模式和非嚴格模式的閉包中,this的指向也會不同,非嚴格模式中this指向的是全局對象(如:瀏覽器中的window),而嚴格模式中this指向的是當前對象!當然,通過call/apply/bind改變函數執行環境的情況下,this就會指向其他對象!