Js學習筆記:閉包

# 1、前言javascript

這個週末,注意力都在學習基礎Js知識上面,恰好看到了閉包這個神聖的東西,因此打算把這兩天學到的總結下來,算是鞏固本身所學。也可能有些不正確的地方,也請你們看到了,麻煩在評論下提醒一下,算是互相學習了。html

2、什麼是閉包?

百度百科定義:閉包就是可以讀取其餘函數內部變量的函數。

在解釋以前,得先講講做用域。先來看下面這個示例:java

var a = 1;
function f(){
  var b = 2;
  console.log(a) // 1
}
console.log(b) // undefined

示例中包含了兩種做用域,一種是屬於全局的全局做用域,另外一種是屬於函數f的局部做用域。因爲Javascript這種鏈式做用域(父做用域是能夠被其子做用域訪問的,而子做用域卻不能被父做用域訪問)的機制,使得示例最後一行輸出了undefined閉包

今後能夠看出,沒法從父做用域中訪問子做用域。而咱們再來看閉包的定義:閉包就是可以讀取其餘函數內部變量的函數。也就是閉包可讓咱們從父做用域中訪問到子做用域,具體怎麼實現的呢?來看這個經典的例子:異步

function foo(){
    var a = 2;
    function bar(){
        console.log(a);
    }
    return bar;
}

var baz = foo();

baz(); // 2 -> 這就是閉包的效果

這個示例中,閉包就是函數bar。能夠看到,咱們經過在函數foo內部定義其子函數bar,並將其做爲foo返回值,由於bar函數做用域能夠訪問foo的做用域,因此實現了從全局做用域訪問foo函數做用域的效果。函數

3、閉包的應用

其實,平時你所寫的代碼中,早就用到了閉包,只是你還沒發現而已。性能

本質上,不管什麼時候何地,若是將函數看成值傳遞到其餘地方使用(非函數所在做用域),你就已經使用了閉包。例如上面示例說的函數bar,咱們將他傳遞到了全局做用域下,經過這種方式訪問到本該不能訪問的變量a學習

在定時器、事件監聽器、Ajax請求、任何其餘異步(或同步)任務中,只要使用了回調函數,實際上就是在使用閉包!code

4、注意事項

閉包會讓他所在做用域中的變量始終保存在內存中,而不會被垃圾回收機制回收。htm

function foo(p){
    function bar(){
        console.log(++p);
    }
    return bar;
}

var baz = foo(1);
baz(); // 2
baz(); // 3
baz(); // 4

var bazz = foo(2);

bazz(); // 3
bazz(); // 4
bazz(); // 5

baz(); // 5

看到了沒,閉包的使用,函數調用以後,讓其外層函數的內部變量(foo函數內的變量)始終保存在了內存中,而不會被回收。

值得注意的是,每次調用一次foo,都會生成一個新的閉包,都會在內存中保存下其外層函數的內部變量。所以要注意閉包的使用,不然會致使性能問題。

5、總結

閉包的做用:

  • 可以讀取其餘函數內部變量。
  • 讓其餘函數的內部變量始終保存在內存中。

參考:

附:你不知道的Javascript系列電子書網盤連接, 密碼:i8jf

相關文章
相關標籤/搜索