JS的閉包

1. 什麼是閉包

       (1)在介紹閉包之前,我們先重新認識一下函數的執行空間:

function fn(){
	console.log("我是fn");
}
fn();
  • 函數在執行的時候,會開闢一個執行空間(暫且叫它xxx);
  • 那麼上面的代碼console.log(“我是fn”) 就是在xxx這個空間內執行的;
  • 代碼執行完畢以後,這個xxx空間就銷燬了。

       (2)閉包就是能夠讀取其他函數內部變量的函數,是JS中函數的一種高級應用。在JS中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解爲”定義在一個函數內部的函數”。

       例:

function fn() {
     var b = 1;
     // 閉包
     function box() {
          console.log(b);
     }
     // 返回一個函數,這個函數就是一個閉包
     return box;
}
// res 就是 box 函數
var res = fn();
// 2秒以後調用res函數,還是能打印b的值,閉包能讓局部變量常駐內存
setTimeout(function() {
     res();
}, 2000);

2. 閉包的特點

       (1)可以讀取函數內部的變量。
              變量的作用域無非就是兩種:全局變量和局部變量;
              JS語言的特殊之處,就在於函數內部可以直接讀取全局變量;
              另一方面,函數外部自然無法讀取函數內的局部變量。
        (2)讓這些變量的值始終保存在內存中,作用域空間不銷燬,相對於局部變量來說,浪費了內存。
        (3)保護私有變量。

3. 閉包的形成環境:
(1)函數的嵌套
(2)內部函數使用外部函數中的變量
(3)將內部函數返回,在外部函數的外部,接收返回值,執行(相當於執行了內部函數)

4. 閉包的應用場景

(1)函數作爲返回值。

function box() {
     var n = 1;  
     function cox() {
          n++;
          return n;
     }
     return cox;
}
// res 就是一個閉包 ,n像是一個全局變量
var res = box();
console.log(res()); // 2
console.log(res()); // 3

(2)循環中的事件,事件處理函數中使用了循環的每次的計數器。

<body>
    <div id="box"></div>
    <ul class="list">
        <li>link1</li>
        <li>link2</li>
    </ul>
</body>

<script>
var ali = document.querySelectorAll(".list li");
for(var i=0;i<ali.length;i++){
    ali[index].onclick = (function(index){
        return function(){
            console.log(index);
        }
   })(i);
}
</script>

(3)給某些系統默認的回調函數,傳參。

function fn(a){
    return function(){
        console.log(a);
    };
}
setTimeout(fn("world"), 1000);

(4)處理掉全局變量。

var f = (function(){
    var a = "hello";
    function fn(){
        console.log(a + "world");
    }
    return fn;
})();
f();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章