1.對于閉包,個人理解:
有權訪問另一個函數作用域中的變量的函數
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
var outerValue = '我是外部變量';
var later;
function outerFunction() {
var innerValue = '我是內部變量';
var innerFunction = function () {
console.log(outerValue);
console.log(innerValue);
};
later = innerFunction;
}
outerFunction();
later();
</script>
</body>
</html>
打印結果
閉包是一種特殊的對象。
它由兩部分構成:函數
,以及創建該函數的環境
。環境由閉包創建時在作用域中的任何局部變量組成。
理解閉包的關鍵在于:外部函數調用之后其變量對象本應該被銷毀,但
閉包的存在使我們仍然可以訪問外部函數的變量對象
,這就是閉包的重要概念。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
let outer;
function father(){
let inner = '我是函數的內部變量';
function child(){
console.log(inner);
}
}
father();
</script>
</body>
</html>
打印結果,并沒有打印出inner
分析:此時js腳本中,調用了father函數,該函數含有一個內部變量inner,同時在該函數中創建了另一個child函數,child函數可以訪問father函數的內部變量,但是child函數在father函數的內部,外部沒法直接調用,所以控制臺沒有打印任何結果
換一下寫法:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
let outer;
function father(){
let inner = '我是father函數的內部變量';
outer = function child(){
console.log(inner);
}
}
father();
outer();
</script>
</body>
</html>
有打印結果
此時有打印結果,因為child函數的引用賦給了一個外部的變量
產生一個閉包
? ?創建閉包最常見方式,就是在一個函數內部創建另一個函數
。下面例子中的 child 就是一個閉包:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
function father(){
let a =1 ,b=2;
function child(){ //閉包函數,訪問外部函數的
return a+b; //返回father函數內部變量a+b的合
}
return child; //返回閉包函數
}
console.log(father());
</script>
</body>
</html>
打印出閉包函數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
function father(){
let a =1 ,b=2;
function child(){ //閉包函數,訪問外部函數的
return a+b; //返回father函數內部變量a+b的合
}
return child(); //返回閉包函數的執行結果
}
console.log(father());
</script>
</body>
</html>
打印出閉包函數的執行結果
閉包的作用域鏈包含著它自己的作用域,以及包含它的函數的作用域和全局作用域。
閉包的注意事項
.通常,函數的作用域及其所有變量都會在函數執行結束后被銷毀。但是,在創建了一個閉包以后,這個函數的作用域就會一直保存到閉包不存在為止。