一、基本概念
閉包是指有權訪問另一個函數作用域中變量的函數,即在函數內部創建另一個函數。閉包可以從內層函數訪問外層函數的作用域,但外層函數卻不能訪問內層函數的作用域。
function outer() {
var name = "Alice";
function inner() {
console.log(name);
}
return inner;
}
var func = outer();
func(); // 輸出 "Alice"
在上述代碼中,outer函數返回了inner函數,inner函數可以通過閉包訪問到outer函數作用域中的name變量。
二、優點
1、保護變量不受全局污染
閉包可以讓某些變量不受全局污染,只有在創建閉包的函數中才能訪問。這樣可以有效地保護變量不會被非法修改。
function counter() {
var count = 0;
return function() {
console.log(++count);
}
}
var c = counter();
c(); // 輸出 1
c(); // 輸出 2
在上述代碼中,count變量只能在counter函數內部訪問,不受全局污染。
2、實現私有變量和函數
閉包可以模擬面向對象中的私有變量和函數,實現數據的封裝性和安全性。
function Person() {
var name = "Alice";
function getName() {
return name;
}
this.showName = function() {
console.log(getName());
}
}
var p = new Person();
p.showName(); // 輸出 "Alice"
console.log(p.name); // undefined
console.log(p.getName); // undefined
在上述代碼中,name變量和getName函數都是私有的,只有通過showName函數才能訪問。
3、實現函數式編程
閉包可以用於實現函數式編程,即將函數作為參數傳遞給另一個函數。
function add(x) {
return function(y) {
return x + y;
}
}
var add1 = add(1);
console.log(add1(2)); // 輸出 3
console.log(add1(3)); // 輸出 4
在上述代碼中,add函數返回一個閉包,用於實現柯里化,從而實現類似函數式編程的效果。
三、缺點
1、內存泄漏
由於閉包會將外部函數的作用域對象保存在內存中,因此如果使用不當可能會導致內存泄漏。
function count() {
var arr = [];
for(var i = 0; i < 1000000; i++) {
arr[i] = function() {
console.log(i);
};
}
return arr;
}
var arr = count(); // arr中包含1000000個閉包
在上述代碼中,count函數返回一個包含1000000個閉包的數組,由於每個閉包都保存了i變量,因此會導致內存泄漏。
2、性能問題
由於閉包會涉及到作用域鏈查找和內存管理等操作,因此會對性能造成一定的影響。
function func() {
var str = "";
for(var i = 0; i < 10000; i++) {
str += i;
}
return function() {
console.log(str);
}
}
var f = func(); // f是一個閉包
f();
在上述代碼中,func函數返回一個閉包,閉包訪問了func函數中的str變量,由於str變量是一個較大的字符串,因此會對性能造成影響。
3、作用域鏈增長
由於閉包會涉及到作用域鏈的查找操作,因此頻繁地使用閉包可能會導致作用域鏈過長,從而影響性能。
function func() {
var name = "Alice";
return function() {
console.log(name);
}
}
var f1 = func();
var f2 = func();
在上述代碼中,func函數返回一個閉包,每次調用func函數都會創建一個新的閉包,從而增加作用域鏈的長度。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/272379.html
微信掃一掃
支付寶掃一掃