JS 做用域 閉包 this 原型 知識點總結

若是你能看懂如下兩張圖, 那就能夠跳過本總結了, 固然, 點個贊再走啊喂! (#`O′)! es6

JS類風格代碼
JS對象關聯風格代碼 OLOO Object Link to Other Object

啊喂分割線 (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)!

你不知道的JavaScript(上冊)

做用域和閉包

  1. LHS和RHS查詢, 能夠理解爲查找變量賦值的目標和源頭, 固然, "賦值"能夠是隱晦的
  2. LHS查詢失敗, 將在嚴格模式下致使拋出RefrenceError, 非嚴格模式下則會自動建立新變量
  3. eval額with分別是修改原有做用域和根據參數建立一個新的做用域
  4. 咱們若是把函數理解成代碼片斷之間的接口?
  5. for循環中的var會污染上級做用域 -> var會污染上級做用域 -> js(es5)沒有塊級做用域? -> 經過IIFE能夠假裝一個塊級做用域(但這種方法並不普適), 其實with和catch能夠建立一個塊級做用域 -> js(es5)有塊級做用域, 更別說es6了
  6. 某個函數擁有上級(或上多級)做用域的引用, 就叫作閉包, 詳細一點說明就是: 當函數記住並訪問其所在的詞法做用域, 即使它是在當前詞法做用域以外執行, 這就產生了閉包. 閉包可使得函數就訪問定義時的詞法做用域, 實際上只要使用了回調函數就使用了閉包
  7. 模塊的兩個主要特徵: 爲建立內部做用域而封裝了包裝函數; 包裝函數的返回值必須包括一個內部函數的引用;
  8. JS只有詞法做用域(定義在書寫代碼使得做用域, 固然排除eval和with)
  9. 詞法做用域關注函數在何處聲名, 動態做用域關注函數在何處調用
  10. bind函數常常用於替代匿名的箭頭函數, 以建立具名函數

this和對象原型

  1. 想比較於顯式傳入上下文對象, this關鍵字使用了一種更佳優雅的方式, 傳遞一個對象的引用
  2. this不指向(或不只僅指向)函數自己或者函數的做用域, 他是在函數建立(調用)時被綁定的
  3. 在非嚴格模式中, 直接調用函數, 一般會自動將this綁定到全局對象, 稱之默認綁定
  4. 隱式綁定即判斷調用函數時的上下文對象, 如 obj.say(), 將say中的this隱式綁定到obj
  5. 顯式綁定即call, apply, 其中一種特殊的形式叫作硬綁定, bind
  6. 使用new將會發生以下步驟: 建立新對象, 設置__proto__爲函數的prototype, 綁定this到新對象, 默認返回這個新對象(最後這一點常被認爲是new的一個反作用)
  7. 給bing, call等函數傳入null, undefined將出乎意料的致使this綁定到全局對象, 更安全的解決辦法是使用一個空對象, 如Object.create(null)
  8. JS中基本類型自己不是對象, 只是建立時字面量會自動被轉化爲對象, typeof null === 'object' 的結果是bug
  9. 對象鍵訪問會將其中的值轉化爲字符串, 就算是數字也不例外, 然而數組反之
  10. 經過遍歷對象屬性進行freeze能夠模擬"深度凍結", 可是可能在無心中凍結其它(共享)對象
  11. hasOwnProperty只檢查自身屬性, 而in操做符會搜索至原型鏈
  12. 4 in [1,2,4] 可能不會獲得你想要的結果 --- 答案是false, 由於in操做符檢查的是屬性名
  13. 類/繼承描述了代碼的一種組織結構方式->軟件對真實世界問題領域的建模方法
  14. 多態指父類的通用行爲能夠被子類用更特殊的行爲重寫
  15. JS中利用顯示僞多態(Car子類調用Vehicle.drive.call(this)), 將極大增長維護成本, 代碼複雜度, 應儘可能避免使用, 或者改成將父類方法保存到子類中
  16. 總的來講, 在JS中模擬類是得不償失的
  17. 屬性的屏蔽比想象中的要複雜, 若是底層對象沒有該屬性, 則上層對象的屬性的writable:false或是其做爲setter存在, 會對賦值(=)操做有影響, 固然你可使用defineProperty來解除這種影響. 這裏有個坑, 如a.b++其實至關於a.b=a.b+1
  18. 繼承意味着"複製操做", JS中經過prototype實現的繼承, 將只是建立對象之間的關聯, 而不是複製操做
  19. JS中"構造函數"的概念僅存在於使用new操做符時, new將普通函數劫持, 將調用變成有返回值的"構造函數調用"
  20. JS中.constructor屬性與"構造"毫無關係, 把他當成一個普通的屬性理解就好
  21. JS原型繼承(B.prototype= Object.create(A.prototype))能夠類比爲"類的繼承"
  22. Object.create修改[[Prototype]]以修改對象之間的鏈接關係, 這和new是同樣的, 可是, new還會經過Base.call(newObj)作一些其餘事
  23. 空的對象(__proto__==null)叫作"字典", 由於沒有任何委託, 因此適合用來儲存數據
  24. 總的來講, 用"委託"來描述JS對象之間的關聯關係(OLOO)更合適(而不是"複製")
  25. 類風格代碼(Function,new或是ES6的Class)強調實體和實體的關係, OLOO則只關注對象關聯關係, 這裏有兩張圖太棒了, 惋惜放不出來
  26. 鴨子類型(if(a.b)a.b())有時比instanceof有效
相關文章
相關標籤/搜索