閉包
-
@定義:
有權(quán)訪問另一個函數(shù)的作用域中的變量的函數(shù)
-
@創(chuàng)建閉包的常見方式:
在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)
-
@作用:
讓內(nèi)部函數(shù)可以訪問其所在的外部函數(shù)聲明的參數(shù)和變量,即使在外部函數(shù)被返回即壽命終結(jié)了之后,以及創(chuàng)建塊級作用域.
- 利用閉包可以訪問外部變量特性凌外,隱藏可以被直接修改的數(shù)據(jù),讓name變量私有化
function Person(name) {
this.getName = function() {
return name;
}
this.setName = function(value) {
name = value;
}
}
let person = new Person("kobe")
console.log(person.getName()) //kobe
person.setName("james")
console.log(person.getName()) //james
getName()和SetName()能作為閉包訪問name變量雨饺,除了Person生成的對象可以通過這兩個特權(quán)函數(shù)訪問和修改name變量惑淳,其他沒有辦法訪問歧焦。
- 創(chuàng)建塊級別作用域.
function outputNumbers1(num) {
//塊級作用域
(function() {
for (var i = 0; i < num; i++) {
console.log(i); // 0, 1, ... num - 1
}
})()
console.log(i); //Uncaught ReferenceError: i is not defined
}
outputNumbers1(10);
閉包的內(nèi)存泄露詳細講解將在作用域篇講解肚医。
-
@缺點:閉包會使函數(shù)中的變量(無論有沒有用)一直保存在內(nèi)存中,出現(xiàn)內(nèi)存泄露(內(nèi)存消耗很大的情況下影響網(wǎng)頁性能)
function(){
var element = document.getElementById("id");
element.onclick = function(){
........
alert(element.id);
}
}
匿名函數(shù)存在著對element的引用舰涌,匿名函數(shù)只要存在你稚,element的引用計數(shù)就一直為1,就永遠不會被內(nèi)存回收搁痛。
所以不能濫用閉包,解決辦法是鸡典,退出函數(shù)之前枪芒,將不使用的局部變量刪除。簡單的說就是把那些不需要的變量舅踪,但是垃圾回收又收不走的的那些賦值為null,然后讓垃圾回收走贷腕,
解決方法為
function(){
var el = document.getElementById("id");
var id = el.id; //解除循環(huán)引用
el.onclick = function(){
alert(id);
}
el = null; // 將閉包引用的外部函數(shù)中活動對象清除
}