十分鐘快速瞭解《你不知道的 JavaScript》(上卷)

最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進一步的瞭解。javascript

《你不知道的 JavaScript》上卷由兩部分組成,第一部分是《做用域和閉包》,第二部分是《this 和對象原型》。下面我會按照簡單介紹一下每一章的主要內容及閱讀感覺。java

第一部分《做用域和閉包》es6

第 1 章 做用域是什麼

  1. 編譯原理:簡單介紹分詞/詞法分析、解析/語法分析、代碼生成的概念;
  2. 理解做用域:介紹引擎、編譯器、做用域之間的關係;
  3. 做用域嵌套。

在這一章節中,做者經過引擎、編譯器、做用域之間的對話,將這三者之間的關係及做用生動形象地展示出來,並引出了 LHS 查詢和 RHS 查詢的概念。設計模式

第 2 章 詞法做用域

  1. 詞法做用域及其相關概念;
  2. 欺騙詞法的方式:
    • 在代碼運行時修改詞法做用域,如 eval()
    • 在代碼運行時建立新的詞法做用域,如 with

這一章做者介紹了詞法做用域以及欺騙詞法的方式。說來慚愧,在看這章以前,我徹底沒據說過「詞法做用域」這個概念,一開始我還覺得是個很高大上的東西,看完以後你會以爲其實也沒什麼,就是你平時都在寫的東西,只不過你沒有留意而已。數組

第 3 章 函數做用域和塊做用域

  1. 函數做用域:函數聲明和函數表達式的區別、具名函數和匿名函數;
  2. 塊做用域:withtry/catchletconst

這一章做者介紹了 JavaScript 中的函數做用域及塊做用域,講了函數聲明和函數表達式的區別,其實很簡單,就是看 function 這個關鍵字是不是在聲明中的第一個詞,若是是,那就是函數聲明,不然就是函數表達式。另外,做者還簡單地介紹了下 ES6 中具備塊做用域做用的 letconst 關鍵字。閉包

在這以前,我一直覺得 ES6 以前是沒有塊做用域的,只有全局做用域和函數做用域,看完這章以後,我才知道其實在 ES3 的時候就有塊做用域了。好比,with 。再好比,try/catch 中的 catch,通常咱們是這樣寫的:app

try {
    // do something
} catch (err) {
    console.log(err)
}

其中這個 err 只存在 catch 分句內部,從別處引用時會拋出錯誤。這不就是塊做用域嗎?函數

第 4 章 提高

這一章節做者簡單地介紹了一下變量聲明提高和函數聲明提高。沒什麼好說的,須要注意的是函數表達式是賦值操做,並不會提高。性能

第 5 章 做用域閉包

  1. 閉包;
  2. 做用域和閉包;
  3. 模塊機制。

閉包是 JavaScript 中的一大難點,在這章中做者用了 4 個小節來介紹閉包,還有 1 個小節來介紹模塊機制。不要看閉包有四個小節,其實也不過 8 頁而已,核心的文字加起來也就 2 頁,但就是這短短的 2 頁,就把閉包給講得很是清楚。this

下面是書中給出關於閉包的定義:

當函數能夠記住並訪問所在的詞法做用域時,就產生了閉包,即便函數是在當前詞法做用域以外執行。

看了是否是仍是不懂,不要緊,讓咱們來提取關鍵字:

  • 函數;
  • 記住並訪問所在的詞法做用域;
  • 當前詞法做用域以外執行。

再來看下書中的一段代碼,看完以後再結合書中的定義來理解,我相信你對閉包確定會有更進一步的理解。

function foo() {
    var a = 2;

    function bar() {
        console.log(a);
    }

    return bar;
}

var baz = foo();

baz(); // 2 —— 朋友,這就是閉包的效果。

下面結合咱們剛剛提取的關鍵字來理解。

  • 函數。這裏的函數是 bar()
  • 記住並訪問。 bar() 當前所在的詞法做用域是 foo() 的函數做用域。bar() 的詞法做用域可以訪問 foo() 的內部做用域。
  • 當前詞法做用域以外執行。在上面的代碼中,咱們將函數 bar() 當作一個值類型傳遞給外部,在這句代碼中 var baz = foo();,咱們將 foo() 的返回值(也就是 bar())賦值給變量 baz 並調用 baz(),實際上就是調用 bar()。上面第 2 點裏咱們說了,bar() 的做用域是 foo() 的函數做用域,可是,在這裏,它倒是在本身定義的詞法做用域之外的地方執行。

怎麼樣,經過上面的分析,是否是對閉包有了進一步的理解了。

附錄 A 動態做用域

做者在這一章中簡單地分析了下動態做用域,並經過一小段代碼將它與詞法做用域作了對比。詞法做用域與動態做用域的主要區別在於:詞法做用域是在定義時肯定的,而動態做用域是在運行時肯定的。

附錄 B 塊做用域的替代方案

這一章簡單地介紹了塊做用域的替代方案 Traceur,以及所以可能會帶來的性能問題。

附錄 C this 詞法

這一章並無說明 this 機制 ,只是介紹了 ES6 中的箭頭函數引入的行爲 —— this 詞法。關於 this 機制的詳細說明是在第二部分《this 和對象原型》中的第 1 章和 第 2 章。

附錄 D 致謝

這一章做者致謝了一大堆的人,光人名的排版就佔了兩頁多,說真的,我都懷疑是否是在湊字數了(純調侃,沒別的意思)。


第二部分《this 和對象原型》

第 1 章 關於 this

  1. this 的指向;
  2. this 的做用域。

這一章中做者先是提出咱們「爲何要使用 this?」這個問題,而後再指出「this 究竟是什麼?」,爲第 2 章作鋪墊。

這一章我我的認爲最核心的就是兩句話。第一句是「當一個函數被調用時,會建立一個活動記錄(有時也稱爲執行上下文)。這個記錄會包含函數在哪裏被調用(調用棧)、函數的調用方式、傳入的參數等信息。this 就是這個記錄的一個屬性,會在函數執行的過程當中用到」。也就是說,this 是活動記錄裏的一個屬性,與函數執行的過程有關。

第二句話是「this 其實是函數被調用時發生的綁定,它指向什麼徹底取決於函數在哪裏被調用。」。第 2 章實際上就是在講這個綁定。

第 2 章 this 全面解析

  1. 調用位置;
  2. 綁定規則:
  • 默認綁定;
    • 隱式綁定;
    • 顯式綁定:call()apply()bind()
    • new 綁定;
    • 箭頭函數的綁定;
    • 一些例外的綁定。
  1. 綁定規則的優先級。

做者在這一章中全面介紹了 this 的綁定規則。

要弄清楚 this 的綁定對象,須要明白如下兩點:

  • 調用位置
  • 綁定規則

什麼是調用位置?簡單來講,就是函數在代碼中被調用的位置。爲了找到調用位置,咱們須要分析調用棧,也就是爲了到達當前執行位置所調用的全部函數,而調用位置就在當前正在執行的函數的前一個調用中。

而綁定規則就是說 this 綁定的對象是有規則的,而且這些規則是有優先級的,總的來講有下面四點:

  1. new 調用的,綁定到新建立的對象;
  2. callapplybind 調用的,綁定到指定的對象;
  3. 由上下文對象調用的,綁定到該上下文對象;
  4. 默認的,在嚴格模式下綁定到 undefined,在非嚴格模式下綁定到全局對象。

固然了,ES6 中新增的箭頭函數並不在這四條規則裏面,而是繼承外層第一個非箭頭函數調用的 this 綁定。

在看這一章以前,我對 this 只知其一;不知其二,網上找的答案也是五花八門,根本不知道哪一個對哪一個錯。在看完這一章以後,我算是對 this 的所綁定的對象有了較爲清晰的認識,之後再遇到相似的問題時,直接套用上面的規則就能夠了。

第 3 章 對象

  1. JavaScript 中的數據類型;
  2. 內置對象;
  3. 對象屬性與方法;
  4. 數組;
  5. 對象複製;
  6. 屬性描述符;
  7. [[Get]] 操做與 [[Put]] 操做;
  8. Getter 和 Setter;
  9. 遍歷及 ES6 中的 Symbol.iterator。

這一章講到了不少平時我並無注意到的東西,好比,通常來講,咱們使用數組的時候都是下標/值對,可是,給數組添加屬性竟然也是能夠,雖然這並不會改變數組的長度。當我看到這一部分的內容時內心在想:我去,這是什麼騷操做?這樣竟然也能夠?後面想了想,數組其實也是對象,是一個特殊的對象,從這一方面來講也是行得通的;再好比,屬性訪問與賦值時發生的 [[Get]] 操做與 [[Put]] 操做,可以更好地瞭解其工做原理;還有,咱們能夠利用 ES6 中的 Iterator 接口實現本身的迭代邏輯。

第 4 章 混合對象 「類」

  1. 類理論;
  2. 類的機制;
  3. 類的繼承;
  4. 混入。

這一章講到了 「類」 這一設計模式,以及 JavaScript 中各類實現這一模式的方法。

這一章的核心就是:類的本質是複製,多態和繼承也是。這一點很重要,JavaScript 中也有類,可是二者的本質是不一樣的,這一點在《第 5 章 原型》和《第 6 章 行爲委託》裏面有詳細的說明。

這一章一開始看的時候我是很模糊的,由於做爲一名 JavaScript 開發者,說實話我對於 「類」 這個東西的理解不是很明白,因此我跳過了這一章,等到看完了後面三章以後再回過來看,瞬間感受清晰不少了。

第 5 章 原型

  1. [[Prototype]] 屬性;
  2. 屬性設置和屏蔽;
  3. JavaScript 中的 「類」;
  4. (原型)繼承;
  5. 對象關聯。

這一章中,第一小節的 [[Prototype]] 屬性能夠和第 3 章中的 [[Put]] 操做結合一塊兒看,這樣可以完整的瞭解屬性賦值的工做原理;屬性設置和屏蔽這一部分能夠和第 4 章結合着閱讀,以便更好地瞭解 JavaScript 中的類與其它語言中的類的區別。

第 6 章 行爲委託

這一章做者主要從類理論與委託理論(其實也就是對象關聯)兩種不一樣的設計模式來介紹他們之間在代碼上實現的不一樣,能夠看作是第 4 章和第 5 章的對象關聯的實踐部分。

附錄 A ES6 中的 Class

這一章做者分析了 ES6 中新增的 Class 語法的優勢與缺點。

全書感悟

以上就是本書中的一些主要內容介紹,我寫得比較簡單,其實書中還有不少比較細小的東西,有興趣的同窗能夠去買來看看。總的來講,這本書仍是挺不錯的,能讓你學到一些平時沒有注意到的東西,做者偏向於用口語化的文字來介紹知識點,不會顯得枯燥。

最後,拋塊磚,但願能引塊玉。下面是我在閱讀本書過程當中的作的思惟導圖。導圖的內容比較多,不是很簡潔,由於我但願儘可能把書中做者提到的概念提取出來,因此可能會顯得比較囉嗦。
思惟導圖

相關文章
相關標籤/搜索