Scope & Hoisting & Closure
Scope
Scope 以及 Hoisting、Closure 這三段是搞懂 JavaScript 該如何 coding 的主力內容,建議將 Scope 這段提供的電子書連結看過一遍,我覺得網路上很難找到完整的資訊,還是看書最快
一句話說清楚:Scope 就是一個程式語言的規則,這些規則和作法會決定變數(variables)如何被查找:變數是怎麼宣告的?怎麼被賦值?怎麼被取值?
有兩種主流 Scope:lexical scope(JavaScript 用這款) 和 dynamic scope
一大串一定會忘記的內容:JavaScript 的編譯可粗分成三步驟
一、Tokenzing and Lexing,從一堆字串取出各種基本單元(tokens)
二、Parsing,做出一顆樹,AST(Abstract syntax tree)
三、Code-Generation,把 AST 轉成 executable code/a set of machine instructions
Engine、Compiler、Scope
如果 RHS 在 Scopes 中找不到東西,Engine 會丟出 ReferenceError
如果 LHS 在 Scopes 中找不到東西,則 Engine 會收到「因為找不到所以被創建出來的新變數」, 若是在 Strict Mode 下,則和 RHS 的情形一樣,Engine 會丟出 ReferenceError
如果 RHS 有找到東西,但你的操作不合理,Engine 會丟出 TypeError
有兩個東西可以在 runtime 時改變 scope,一、eval(不要用),二、with(已被棄用)
ES6-let & const
let 會被附接到所在的 { .. } 上,並且不會被 hoisting。(總之使用起來會比較符合其他語言 block scope 的習慣)
const,不可改變的變數
以上詳細內容推薦必看(看完還是會忘記):《你所不知道的 JS-範疇與Closures,this與物件原型》 https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/README.md
Hoisting
承 Scope
一句話說清楚:Hoisting 拉升指的是「宣告這個動作被提高到所屬範疇(scope)的頂端」
若有同樣名稱的宣告,函式會比變數優先。但是 variable assignment 又可以將 function declaration OVERRIDE
Closure
承 Scope
一句話說清楚:到處都是 closures。closure 指的是會記得其 Scope,即使傳送調用到原本的範疇外,仍有存取其變數的能力
直接看錯誤例子最快,而且避開地雷、避開無意義的 bug,正是這份文件的用途
補充閱讀資訊
這篇可以做為 Closure 的快速導覽,有圖有實例,(文章日期:2016.04.29)https://medium.freecodecamp.org/lets-learn-javascript-closures-66feb44f6a44
時間足夠的話,可以看本書上面 Scope 那段裡的系列電子書複習,https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/README.md
各方大德的解釋方法,Stack Overflow 上的十年來(到 2017.10 都還有活躍活動)的經典討論串(不過我沒看),https://stackoverflow.com/questions/111102/how-do-javascript-closures-work
那麼 Closure 可以拿來做什麼?可以做出一種 code pattern:模組(module)
Module
簡單介紹現代(文章日期:2017.02.21)的 module loaders and bundlers https://www.jvandemo.com/a-10-minute-primer-to-javascript-modules-module-formats-module-loaders-and-module-bundlers/
常見的格式(format) Asynchronous Module Definition (AMD):用於瀏覽器 CommonJS:用於 Node.js
Universal Module Definition (UMD):用於瀏覽器和 Node.js 都可以
System.register:ES5 的作法
ES6 module format:ES6 的作法
現代常見的 module bundlers(取代 loaders 的功能) Browserify:for CommonJS modules
Webpack:for AMD, CommonJS, ES6 modules
例子
搞懂為何設定 REACT、JSX、ES2015、BABEL、WEBPACK 的學習筆記(文章日期:2017.09.12)http://blog.turn.tw/?p=3532
Last updated