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

来源:https://www.cnblogs.com/monkeychennn/archive/2018/08/20/9502962.html
-Advertisement-
Play Games

最近剛剛看完了《你不知道的 JavaScript》上捲,對 JavaScript 有了更進一步的瞭解。 《你不知道的 JavaScript》上捲由兩部分組成,第一部分是《作用域和閉包》,第二部分是《this 和對象原型》。下麵我會按照簡單介紹一下每一章的主要內容及閱讀感受。 第一部分《作用域和閉包》 ...


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

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

第一部分《作用域和閉包》

第 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,一般我們是這樣寫的:

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

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

第 4 章 提升

這一章節作者簡單地介紹了一下變數聲明提升和函數聲明提升。沒什麼好說的,需要註意的是函數表達式是賦值操作,並不會提升。

第 5 章 作用域閉包

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

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

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

當函數可以記住並訪問所在的詞法作用域時,就產生了閉包,即使函數是在當前詞法作用域之外執行。

看了是不是還是不懂,沒關係,讓我們來提取關鍵字:

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

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

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 語法的優點與缺點。

全書感悟

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

最後,拋塊磚,希望能引塊玉。下麵是我在閱讀本書過程中的做的思維導圖。導圖的內容比較多,不是很簡潔,因為我希望儘量把書中作者提到的概念提取出來,所以可能會顯得比較啰嗦。
思維導圖


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • TextView EditText Button imageView Spinner下拉列表 RadioGroup(覆選框) / Checkbox(單選框) ProgressBar進度條 RatingBar星級控制項 SeekBar進度條控制項 ...
  • "Android項目刮刮獎詳解(一)" 前言 上期我們簡單地實現了一個畫板的功能,用戶可以在上面亂寫亂畫,其實,刮刮獎也是如此,用戶刮獎的時候也是亂寫亂畫的。 刮刮獎原理 一共有兩層畫布,底層畫布存放中獎信息的圖片,上層畫布則是一個遮蓋層,我們將底層畫布成為信息層,上層畫布稱作為遮蓋層。 用戶再遮蓋 ...
  • Element.getBoundingClientRect()返回元素的大小及相對於視窗的位置 語法: rectObject=object.getBoundingClientRect(); 返回值是一個DOMRect對象,即DOMRect={x:scrollLeft,y:scrollY,width: ...
  • css sprites:精靈圖(雪碧圖):把一堆小圖片整合在一張大圖上,通過背景圖片相關設置(背景圖片、背景圖是否重覆、背景圖定位),顯示圖片,減輕伺服器對圖片的請求數量 優點: 1、減少網頁的HTTP請求,提高頁面性能 2、圖片命名上的困擾 3、更換風格方便 缺點: 1、必須限定容器大小,符合背景 ...
  • 一般性的,當我們需要載入js文件的時候都會使用script標簽來實現,類似於如下代碼: 代碼如下: <script type="text/javascript" src="example.js"></script> 但是直接使用script標簽來載入js文件會有如下一些缺點: 1.嚴格的讀取順序。由 ...
  • angularjs學習筆記,系統學習整理angular。angularjs、$scope、$parse、$interpolate ...
  • 這個系列將從基礎語法講起,把react全家桶都講到,然後到具體的使用,最後完成後,會寫一個完整的demo。 前置要求: 基本的CSS,JS要熟練。 部分ES6語法需要瞭解。可以參考下麵提到的阮一峰老師的《ECMAScript 6 入門》和MDN文檔。 目前已經完成的內容: "react教程(零)安裝 ...
  • CSS3實現各種表情 效果圖: 代碼如下,複製即可使用: 如有錯誤,歡迎聯繫我改正,非常感謝!!! ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...