閉包理解
如何產生閉包
- 當一個嵌套的內部(子)函式參考了嵌套外部(父)函式的變數(函式)時--就產生了閉包
閉包是什么
-
使用chrome除錯查看
-
理解一 -- 閉包是嵌套的內部函式
-
理解二 -- 閉包是包含被參考變數(函式)的物件
-
閉包存在于嵌套的內部函式中
-
產生閉包的條件
-
函式嵌套
-
內部函式參考了外部函式的資料(變數或函式)
<script>
function fn1() {
var a = 3;
function fn2() {
console.log(a);
}
fn2();
}
fn1();
</script>

常見閉包
將函式作為另一個函式的回傳值
function fn1() {
var a = 2;
function fn2() {
a++;
console.log(a);
}
return fn2;
}
var f = fn1();
f(); //3--fn1的回傳值是fn2--相當于呼叫了fn2()--相當于fn1()()
f(); //4--閉包不會消失--第一次fn1()執行時--閉包內的資料是3--第二次執行時就是4
將函式作為實參傳遞給另一個函式呼叫
function showDelay(msg, time) {
setTimeout(function () {
console.log(msg); //閉包
}, time);
}
showDelay('zao', 2000);

閉包的作用
-
使用函式內部的變數在函式執行完后--仍然存活在記憶體中--延長了區域變數的生命周期
-
讓函式外部可以操作(讀寫)到函式內部的資料--變數/函式
問題
- 函式執行完--函式內部宣告的區域變數是否還存在--一般不存在,存在于閉包中的變數才可能存在
- 在函式外部能直接訪問函式內部的區域變數嗎--不能,但可以通過閉包讓外部操作它
閉包的生命周期
- 產生--在嵌套內部函式定義執行完時就產生了
- 死亡--在嵌套內部函式成為垃圾物件時
function fn1(){
// 閉包產生--函式提升--內部函式已經創建了
var a = 2;
function fn2(){
a++;
console.log(a);
}
return fn2;
}
//只要有變數參考fn1()閉包就一直存在
var f = fn1();
f();
f();
//閉包死亡--包含閉包的函式成為垃圾物件
f = null;
閉包的應用
定義JS模塊
- 具有特定功能的js檔案
- 將所有資料和功能都封裝在一個函式內部--私有
- 只向外暴露一個包含n個方法的物件或函式
- 模塊的使用者--只需通過模塊暴露的物件呼叫方法來實作對應的功能
//JS檔案
function myMoudle() {
var msg = 'zaoya';
function doSomething() {
//toUpperCase--字串轉換為大寫
console.log('doSomething()' + msg.toUpperCase());
}
function doOtherthing() {
//toLowerCase--字串轉換為小寫
console.log('doOtherthing()' + msg.toLowerCase());
}
//向外暴露物件
return {
doSomething: doSomething,
doOtherthing: doOtherthing
}
}
//html檔案
<script src="https://www.cnblogs.com/Liu-h/p/myMoudle.js"></script>
<script>
let fn = myMoudle();
fn.doSomething();
fn.doOtherthing();
</script>
//JS檔案
(function myMoudle1() {
let msg = 'zaozao';
function doSomething() {
console.log('doSomething()' + msg.toUpperCase);
};
function doOtherthing() {
console.log('doOtherthing()' + msg.toLowerCase);
}
window.myMoudle1 = {
doSomething: doSomething,
doOtherthing: doOtherthing
}
})()
//html檔案
<script src="https://www.cnblogs.com/Liu-h/p/myMoudle1.js"></script>
<script>
myMoudle1.doSomething();
myMoudle1.doOtherthing();
</script>
閉包的缺點
缺點
- 函式執行完后--函式內的區域變數沒有釋放--占用記憶體時間會變長
- 容易造成記憶體泄漏
解決
- 能不用閉包就不用閉包
- 及時釋放
記憶體溢位
- 一種程式運行出現的錯誤
- 當程式運行需要的記憶體超過了剩余的記憶體時--就會拋出記憶體溢位的錯誤
記憶體泄漏
- 占用的記憶體沒有及時釋放
- 記憶體泄漏積累多了就容易導致記憶體溢位
常見記憶體泄漏
- 意外的全域變數
- 沒有及時清理的計時器或回呼函式
- 閉包
面試題
var name = 'The Window';
var object = {
name: 'My Object',
getNameFunc: function () {
return function () {
return this.name;
}
}
}
//object.getNameFunc()--是物件呼叫--通過object呼叫--this為object
//通過object.getNameFunc()--呼叫函式--object.getNameFunc()()--是函式呼叫--this為window
alert(object.getNameFunc()()); //The Window
var name2 = 'The Window';
var object = {
name2: 'My Object',
var that = this;
return function () {
return that.name2;
}
}
}
//object.getNameFunc()--是物件呼叫--通過object呼叫--this為object
//object.getNameFunc()()--中that是object.getNameFunc()的this--指向object
alert(object.getNameFunc()()) //My Object
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/551228.html
標籤:JavaScript
上一篇:了解一下XSS
下一篇:返回列表
