国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

這一次,我們換種姿勢學習 javascript

zone / 2698人閱讀

摘要:操作符或調用函數時傳入參數的操作都會導致關聯作用域的賦值操作。此外可以使用和來設置對象及其屬性的不可變性級別。忽視這一點會導致許多問題。使用調用函數時會把新對象的屬性關聯到其他對象。

前言

《你不知道的 javascript》是一個前端學習必讀的系列,讓不求甚解的JavaScript開發者迎難而上,深入語言內部,弄清楚JavaScript每一個零部件的用途。本書介紹了該系列的兩個主題:“作用域和閉包”以及“this和對象原型”。這兩塊也是值得我們反復去學習琢磨的兩塊只是內容,今天我們用思維導圖的方式來精讀一遍。(思維導圖圖片可能有點小,記得點開看,你會有所收獲)

第一部分 作用域和閉包 作用域是什么

作用域是一套規則,用于確定在何處以及如何查找變量(標識符)。如果查找的目的是對 變量進行賦值,那么就會使用 LHS 查詢;如果目的是獲取變量的值,就會使用 RHS 查詢。賦值操作符會導致 LHS 查詢。 的賦值操作。 =操作符或調用函數時傳入參數的操作都會導致關聯作用域的賦值操作。
JavaScript 引擎首先會在代碼執行前對其進行編譯,在這個過程中,像 var a = 2 這樣的聲 明會被分解成兩個獨立的步驟:

首先, var a 在其作用域中聲明新變量。這會在最開始的階段,也就是代碼執行前進行。

接下來, a = 2 會查詢(LHS 查詢)變量 a 并對其進行賦值。

LHS 和 RHS 查詢都會在當前執行作用域中開始,如果有需要(也就是說它們沒有找到所 需的標識符),就會向上級作用域繼續查找目標標識符,這樣每次上升一級作用域(一層 樓),最后抵達全局作用域(頂層),無論找到或沒找到都將停止。

不成功的RHS引用會導致拋出 ReferenceError 異常。不成功的 LHS 引用會導致自動隱式地創建一個全局變量(非嚴格模式下),該變量使用 LHS 引用的目標作為標識符,或者拋 出 ReferenceError 異常(嚴格模式下)。

詞法作用域

詞法作用域意味著作用域是由書寫代碼時函數聲明的位置來決定的。編譯的詞法分析階段 基本能夠知道全部標識符在哪里以及是如何聲明的,從而能夠預測在執行過程中如何對它 們進行查找。

JavaScript 中有兩個機制可以“欺騙”詞法作用域: eval(..) 和 with 。 前者可以對一段包 含一個或多個聲明的“代碼”字符串進行演算,并借此來修改已經存在的詞法作用域(在 運行時)。后者本質上是通過將一個對象的引用 當作 作用域來處理,將對象的屬性當作作 用域中的標識符來處理,從而創建了一個新的詞法作用域(同樣是在運行時)。

這兩個機制的副作用是引擎無法在編譯時對作用域查找進行優化,因為引擎只能謹慎地認 為這樣的優化是無效的。使用這其中任何一個機制都 將 導致代碼運行變慢。 不要使用它們。

函數作用域和塊作用域

函數是 JavaScript 中最常見的作用域單元。本質上,聲明在一個函數內部的變量或函數會 在所處的作用域中“隱藏”起來,這是有意為之的良好軟件的設計原則。

但函數不是唯一的作用域單元。塊作用域指的是變量和函數不僅可以屬于所處的作用域, 也可以屬于某個代碼塊(通常指 { .. } 內部)。

從 ES3 開始, try/catch 結構在 catch 分句中具有塊作用域。在 ES6 中引入了 let 關鍵字( var 關鍵字的表親), 用來在任意代碼塊中聲明變量。 if(..) { let a = 2; } 會聲明一個劫持了 if 的 { .. } 塊的變量,并且將變量添加到這個塊 中。

有些人認為塊作用域不應該完全作為函數作用域的替代方案。兩種功能應該同時存在,開 發者可以并且也應該根據需要選擇使用何種作用域,創造可讀、可維護的優良代碼。

提升

我們習慣將 var a = 2; 看作一個聲明,而實際上 JavaScript 引擎并不這么認為。它將 var a 和 a = 2 當作兩個多帶帶的聲明,第一個是編譯階段的任務,而第二個則是執行階段的任務。

這意味著無論作用域中的聲明出現在什么地方,都將在代碼本身被執行前 首先 進行處理。 可以將這個過程形象地想象成所有的聲明(變量和函數)都會被“移動”到各自作用域的最頂端,這個過程被稱為提升。

聲明本身會被提升,而包括函數表達式的賦值在內的賦值操作并不會提升。

要注意避免重復聲明,特別是當普通的 var 聲明和函數聲明混合在一起的時候,否則會引 起很多危險的問題!

作用域閉包

閉包就好像從 JavaScript 中分離出來的一個充滿神秘色彩的未開化世界,只有最勇敢的人 才能夠到達那里。但實際上它只是一個標準,顯然就是關于如何在函數作為值按需傳遞的 詞法環境中書寫代碼的。

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

如果沒能認出閉包,也不了解它的工作原理,在使用它的過程中就很容易犯錯,比如在循 環中。但同時閉包也是一個非常強大的工具,可以用多種形式來實現 模塊 等模式。模塊有兩個主要特征:

(1)為創建內部作用域而調用了一個包裝函數;
(2)包裝函數的返回 值必須至少包括一個對內部函數的引用,這樣就會創建涵蓋整個包裝函數內部作用域的閉 包。

現在我們會發現代碼中到處都有閉包存在,并且我們能夠識別閉包然后用它來做一些有用 的事!

第二部分 this 和對象原型 this 全面解析

如果要判斷一個運行中函數的 this 綁定,就需要找到這個函數的直接調用位置。找到之后 就可以順序應用下面這四條規則來判斷 this 的綁定對象。

由 new 調用?綁定到新創建的對象。

由 call 或者 apply (或者 bind )調用?綁定到指定的對象。

由上下文對象調用?綁定到那個上下文對象。

默認:在嚴格模式下綁定到 undefined ,否則綁定到全局對象。

一定要注意,有些調用可能在無意中使用默認綁定規則。如果想“更安全”地忽略 this 綁 定,你可以使用一個 DMZ 對象,比如 ? = Object.create(null) ,以保護全局對象。ES6中的箭頭函數并不會使用四條標準的綁定規則, 而是根據當前的詞法作用域來決定 this ,具體來說,箭頭函數會繼承外層函數調用的 this 綁定(無論 this 綁定到什么)。這 其實和 ES6 之前代碼中的 self = this 機制一樣。

對象

JavaScript 中的對象有字面形式(比如 var a = { .. } )和構造形式(比如 var a = new Array(..) )。字面形式更常用,不過有時候構造形式可以提供更多選項。

許多人都以為“JavaScript 中萬物都是對象”,這是錯誤的。對象是 6 個(或者是 7 個,取 決于你的觀點)基礎類型之一。對象有包括 function 在內的子類型,不同子類型具有不同 的行為,比如內部標簽 [object Array] 表示這是對象的子類型數組。

對象就是鍵 / 值對的集合??梢酝ㄟ^ .propName 或者 ["propName"] 語法來獲取屬性值。訪 問屬性時, 引擎實際上會調用內部的默認 [[Get]] 操作(在設置屬性值時是 [[Put]] ), [[Get]] 操作會檢查對象本身是否包含這個屬性,如果沒找到的話還會查找 [[Prototype]] 鏈(參見第 5 章)。

屬性的特性可以通過屬性描述符來控制,比如 writable 和 configurable 。此外,可以使用 Object.preventExtensions(..) 、 Object.seal(..) 和 Object.freeze(..) 來設置對象(及其 屬性)的不可變性級別。

屬性不一定包含值——它們可能是具備 getter/setter 的“訪問描述符”。此外,屬性可以是 可枚舉或者不可枚舉的,這決定了它們是否會出現在 for..in 循環中。

你可以使用 ES6 的 for..of 語法來遍歷數據結構(數組、對象, 等等)中的值, for..of 會尋找內置或者自定義的 @@iterator 對象并調用它的 next() 方法來遍歷數據值。

混合對象"類"

類是一種設計模式。 許多語言提供了對于面向類軟件設計的原生語法。 JavaScript 也有類 似的語法,但是和其他語言中的類完全不同。

類意味著復制。

傳統的類被實例化時,它的行為會被復制到實例中。類被繼承時,行為也會被復制到子類 中。

多態(在繼承鏈的不同層次名稱相同但是功能不同的函數)看起來似乎是從子類引用父 類,但是本質上引用的其實是復制的結果。

JavaScript 并不會(像類那樣)自動創建對象的副本。

混入模式(無論顯式還是隱式)可以用來模擬類的復制行為,但是通常會產生丑陋并且脆 弱的語法,比如顯式偽多態( OtherObj.methodName.call(this, ...) ),這會讓代碼更加難 懂并且難以維護。

此外, 顯式混入實際上無法完全模擬類的復制行為, 因為對象(和函數!別忘了函數也 是對象)只能復制引用, 無法復制被引用的對象或者函數本身。 忽視這一點會導致許多 問題。

總地來說,在 JavaScript 中模擬類是得不償失的,雖然能解決當前的問題,但是可能會埋下更多的隱患。

原型

如果要訪問對象中并不存在的一個屬性, [[Get]] 操作(參見第 3 章)就會查找對象內部 [[Prototype]] 關聯的對象。這個關聯關系實際上定義了一條“原型鏈”(有點像嵌套的作用域鏈),在查找屬性時會對它進行遍歷。

所有普通對象都有內置的 Object.prototype ,指向原型鏈的頂端(比如說全局作用域),如 果在原型鏈中找不到指定的屬性就會停止。 toString() 、 valueOf() 和其他一些通用的功能 都存在于 Object.prototype 對象上,因此語言中所有的對象都可以使用它們。

關聯兩個對象最常用的方法是使用 new 關鍵詞進行函數調用, 在調用的 章)中會創建一個關聯其他對象的新對象。4個步驟(第2章)中會創建一個關聯其他對象的新對象。

使用 new 調用函數時會把新對象的 .prototype 屬性關聯到“其他對象”。帶 new 的函數調用 通常被稱為“構造函數調用”,盡管它們實際上和傳統面向類語言中的 類構造函數 不一樣。

JavaScript 是 中的機制有一個核心區別, 那就是不會進行復制, 對象之間是通過內部的

雖然這些 機制和傳統面向類語言中的“類初始化”和“類繼承”很相似, 但是 javascript 機制和傳統面向對象類語言中的“類初始化”和“類繼承”很相似但是 javascript 中的機制有一個核心區別,就是不會進行復制,對象之間是通過內部的 [[Prototype]] 鏈關聯的。

出于各種原因,以“繼承”結尾的術語(包括“原型繼承”)和其他面向對象的術語都無 法幫助你理解 JavaScript 的 真實 機制(不僅僅是限制我們的思維模式)。

相比之下,“委托”是一個更合適的術語,因為對象之間的關系不是 復制 而是委托。

行為委托

在軟件架構中你可以 選擇是否 使用類和繼承設計模式。大多數開發者理所當然地認為類是 唯一(合適)的代碼組織方式,但是本章中我們看到了另一種更少見但是更強大的設計模式: 行為委托 。

行為委托認為對象之間是兄弟關系, 互相委托, 而不是父類和子類的關系。 JavaScript 的 [[Prototype]] 機制本質上就是行為委托機制。也就是說,我們可以選擇在 JavaScript 中努 力實現類機制(參見第 4 和第 5 章),也可以擁抱更自然的 [[Prototype]] 委托機制。

當你只用對象來設計代碼時,不僅可以讓語法更加簡潔,而且可以讓代碼結構更加清晰。

對象關聯(對象之前互相關聯)是一種編碼風格,它倡導的是直接創建和關聯對象,不把 它們抽象成類。對象關聯可以用基于 [[Prototype]] 的行為委托非常自然地實現。

擴展

思維導圖能比較清晰的還原整本書的知識結構體系,如果你還沒用看過這本書,可以按照這個思維導圖的思路快速預習一遍,提高學習效率。學習新事物總容易遺忘,我比較喜歡在看書的時候用思維導圖做些記錄,便于自己后期復習,如果你已經看過了這本書,也建議你收藏復習。如果你有神馬建議或則想法,歡迎留言或加我微信交流:646321933

你不知道的javascript上卷第二部分在線文檔

你不知道的 javascript(上卷)PDF 下載地址

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107785.html

相關文章

  • Move Mirror:使用 TensorFlow.js 在瀏覽器中預測姿勢之 AI 實驗

    摘要:文和,創意實驗室創意技術專家在機器學習和計算機視覺領域,姿勢預測或根據圖像數據探測人體及其姿勢的能力,堪稱最令人興奮而又最棘手的一個話題。使用,用戶可以直接在瀏覽器中運行機器學習模型,無需服務器。 文 / ?Jane Friedhoff 和 Irene Alvarado,Google 創意實驗室創意技術專家在機器學習和計算機視覺領域,姿勢預測或根據圖像數據探測人體及其姿勢的能力,堪稱最令人興...

    MiracleWong 評論0 收藏0
  • TP-GAN 讓圖像生成再獲突破,根據單一側臉生成正面逼真人臉

    摘要:中科院自動化所,中科院大學和南昌大學的一項合作研究,提出了雙路徑,通過單一側面照片合成正面人臉圖像,取得了當前較好的結果。研究人員指出,這些合成的圖像有可能用于人臉分析的任務。恢復的圖像的質量嚴重依賴于訓練過程中的先驗或約束條件。 中科院自動化所(CASIA),中科院大學和南昌大學的一項合作研究,提出了雙路徑 GAN(TP-GAN),通過單一側面照片合成正面人臉圖像,取得了當前較好的結果。研...

    gougoujiang 評論0 收藏0
  • 前端基礎

    摘要:談起閉包,它可是兩個核心技術之一異步基于打造前端持續集成開發環境本文將以一個標準的項目為例,完全拋棄傳統的前端項目開發部署方式,基于容器技術打造一個精簡的前端持續集成的開發環境。 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果讀完本文還不懂,可以揍我。 不論你是javascript新手還是老鳥,不論是面試求職,還是日...

    graf 評論0 收藏0
  • 加載和執行JS的正確姿勢

    摘要:在這些文件的下載執行過程中,用戶看到的則是一片空白。頁面仍然必須等到所有代碼下載并執行完畢才能繼續渲染。 前言 kyrieliuの《高性能JavaScript》讀書筆記。 script標簽是一個很霸道的狠角色,它的每次出現都讓頁面等待腳本的解析和執行。也就是說,不管當前的javascript代碼是內嵌還是包含在外鏈文件中,頁面的下載和渲染都必須停下來等待腳本執行完成。 其實,scri...

    zhichangterry 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<