你所不知道的 JS 筆記&心得(之二)

你所不知道的 JS 筆記&心得(之一)

前言:

這幾天閱讀了 You Don’t Know JS 系列,覺得如獲至寶,作者以淺顯易懂的方式,介紹了很多 JS 的核心知識與常常我們會誤解的概念,非常推薦給想深入探討 JavaScript 這門程式語言的朋友(尤其是第二本書之後)。

以下摘要一些本書中提到我覺得 JS 重要或是需要注意的概念:

3. You Don’t Know JS: this & Object Prototypes

Chapter 1: this Or That?

  • 為什麼要有this?因為this 提供了一個機制,讓我們可以隱性地reference 物件,設計出更優雅的 API,並可以 reuse function。
  • Instead of avoiding this, we embrace it.
  • this並不是指他處於哪一個 function 或 Scope。
  • this 是在 function 呼叫時才會產生,並且是由哪裡(誰)呼叫而決定this 是表示什麼。

Chapter 2: this All Makes Sense Now!

  • 怎麼判斷this是 reference 哪一個物件?
  1. Is the function called with new (new binding)? If so, this is the newly constructed object. var bar = new foo()
  2. Is the function called with call or apply (explicit binding), even hidden inside a bind hard binding? If so, thisis the explicitly specified object. var bar = foo.call( obj2 )
  3. Is the function called with a context (implicit binding), otherwise known as an owning or containing object? If so,this is that context object. var bar = obj1.foo()
  4. Otherwise, default the this (default binding). If in strict mode, pick undefined, otherwise pick the globalobject. var bar = foo()
  • 使用 new 時,程式自動在做的事:
  1. a brand new object is created (aka, constructed) out of thin air
  2. the newly constructed object is [[Prototype]]-linked
  3. the newly constructed object is set as the this binding for that function call
  4. unless the function returns its own alternate object, the new-invoked function call will automatically return the newly constructed object.
  • 盡量不要使用以下寫法,使用 bind(..) 或是 ES6 arrow-function 取代。
var self = this; // lexical capture of `this`

Chapter 3: Objects

  • 6 primary types object,string, number, boolean, null, and undefined
  • It’s a common mis-statement that “everything in JavaScript is an object”. This is clearly not true.
  • function is a sub-type of object
  • var arr = [] 和 var arr = new Array() 其實有些差異,後者等於再用一個 object 包覆前者。
  • 當我們在取用或設置 object 的屬性的時候,object 會去 call 內建的 [[Get]] 和 [[Put]] function。
  • object 中所有的 property 都可以透過 property descriptor 描述。
Object.getOwnPropertyDescriptor( myObject, "a" );
// {
// value: 2,
// writable: true,
// enumerable: true,
// configurable: true
// }
  • Writable:是否可以被寫, enumerable:是否可以被列舉, Configurable:可否再次設定 property descriptor 的參數(不可逆行為)。

Chapter 4: Mixing (Up) “Class” Objects

  • Javascript 實際上並沒有 Class。
  • Class 的重點在於 copy,新物件是去複製所有 Class 描述的特性。
  • Class 的繼承也是意味著 copies。
  • JS 可以用 mixin 的方式複製,達成類似 class 的方式,但實際上還是有部分是 share 相同的 reference,無法完全複製。
// vastly simplified `mixin()` example:
function mixin( sourceObj, targetObj ) {
for (var key in sourceObj) {
// only copy if not already present
if (!(key in targetObj)) {
targetObj[key] = sourceObj[key];
}
}

return targetObj;
}

Chapter 5: Prototypes (可以再細讀)

  • Prototype chain 將 object 連結起來,當我們在取用 object 特性時,會按照 Prototype chain 去尋找所指的特性。
  • 一般最上層的 Prototype chain 是 Object.prototype。
  • JS 所謂的 Class、inheritance 形式便是由 Prototype chain 模仿而成。
  • 當 myobj 本身沒有 foo 特型,而我們使用 myobj.foo = ‘bar’ 時如果 myobj 的 Prototype chain 上層 object 有 foo 特性,可能會產生 Shadowing Properties issue,會有 3 種不同的情況,因此建議不要有這種操作。

Chapter 6: Behavior Delegation (可以再細讀)

  • JS 物件的特性是 Delegation-Oriented Design。
  • Behavior Delegation 意味著提供一種方式,當找不到一個 obj property or 時 method 可以參考其他的 obj。
  • OLOO (objects-linked-to-other-objects) 是基於 Behavior Delegation 的一種 code style 相較於用 prototype 模仿 class (OO style),OLOO 像以下的寫法:
  • 雖然 OO & OLOO 兩者都可以實現出相同的功能,但在 JS 中,OLOO內部的運作其實更簡潔。
One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.