December 19, 2012
Javascript 的 Object 與 Function
雖然說只要翻兩下書看幾個網站就能開始寫 code,而且看了這些東西也不見得對於寫程式有一日千里的幫助。出於阿宅很純粹的好奇心,我還是花了點時間看了 ECMAScript Q___Q程式寫了一段時間,有時會對某一句天經地義的話沉思很久,總感覺此中有真意,欲辯「不知言」 - 不知道該怎麼解釋它,當然也有可能是庸人自擾,痴人發夢。往往好奇心就在此時被挑起,追尋了半天終於得到了一個原本就知道而且跟大家一模一樣的結論。或許此時只能用「過程比結果重要」來安慰自己。
從來沒想過自己會寫 javascript,剛碰 javascript 就讀到了不少讓人「津津樂道」的特色。好比 Hoisting 或 Closure 這種沒有在 spec 裡面出現,而是在實務中衍生出來的概念,又或著惡名昭彰的全域變數,一不小心就會跟它打上交道,看到不少說法都是因為 spec 定得不好。
這就有意思了,究竟是什麼樣的 spec 可以把一個語言搞成這樣?平常會用觀察的方式去理解一個語言的行為,但是 Javascript 的「出名」讓我有點擔憂,害怕自己觀察到的是某一個實作獨有的現象。因此才會去翻 ECMAScript 順便滿足好奇心。
好奇心被挑起之後,想要釐清以下幾個問題
- 什麼叫做物件
- 什麼叫做 function
- 什麼是 function call, new,constructor
- 產生新物件的過程為何
- 產生的新物件與 constructor 的關係為何
接下來是一點閱讀的心得與筆記,若有疏誤請不吝指教
4.2 Language Overview
4.2 指的是 spec 裡面的 4.2 章節,後面還會重複出現類似的數字。
在 Overview 的部份對一些常見且富含多種意義的名詞做了稍微明確解釋,先記起這些名詞往後會比較順利
- ECMAScript program
一群可以相互溝通的物件(is a cluster of communicating objects),程式就是在物件的互動之中完成功能。 - ECMAScript object 帶有一些 properties 的集合。(is a collection of properties each with zero or more attributes that determine how each property can be used)
- Properties
容器,可保有物件、函式或是 primitive value(are containers that hold other objects, primitive values, or functions.) - Primitive value
- Undefined
- Null
- Boolean
- Number
- String
- Object
內建型別 Object 的成員(is a member of the remaining built-in type Object)
- Function 可以呼叫的 object (is a callable object.)
- Method
物件的 property 如果是個 function,稱之為 method(A function that is associated with an object via a property.)
- Object object
- Function object
- Array object
- String object
- Boolean object
- Number object
- Math object
- Date object
- RegExp object
- JSON object
- Error object
- Error
- EvalError
- RangeError
- ReferenceError
- SyntaxError
- TypeError
- URIError
8.6.2 Object Internal Properties and Methods
這一章節指出,所有的物件都一定帶有某些 internal properties,這邊僅列出幾項- [[Prototype]]
- [[Class]]
- [[Get]]
- [[GetOwnProperties]]
[[Get]] 指向一個 internal method,這個 method 需要一個參數叫 propertyName,執行的結果是回傳一個 property 的 value。
而 [[Prototype]] 就是 __proto__,至於它的值後面再說明。
此外,某些物件還有這些 internal properties
- [[Constructor]] new operator 會用這個 property
- [[Call]] 單純的 function call 會使用這個 property
- [[Code]] 只有 Function Object 會有這個屬性
接下來更深入地看一下產生 Function object 的過程
13.2 Creating Function Object
先定義名詞- FormalParameterList - 參數 list
- FunctionBody - function 的內容
- 產生 native ECMASCript object, 令其名為 F
- 除了 [[Get]] 之外設定所有的 internal methods
- 把 F 的 internal property [[Class]] 設成 "Function"
- 把 F 的 internal property [[Prototype]] 設成 Function.prototype,即 built-in object Function 的prototype 屬性所指向的物件
- 把 [[Code]] 設成 FunctionBody
- 設定許多 internal properties,其中一些 property 會指向特定的 internal method,以下這兩個與 function 的行為有關
- internal method [[Call]] 被 invoke 時這一次執行的狀態放入 funcCtx。[[Code]] 這個 internal property 就是 FunctionBody,執行之後的結果回傳,且把之前的執行狀態 restore 回來。
- internal method [[Constructor]] 被 invoke 時
- 產生新的 ECMAScript object(假設叫 obj),並且設定一些 internal methods。
- 把 obj 的 [[Class]] 設成 "Object"
- 對 F 呼叫 [[Get]] property,參數是 "prototype",假設呼叫的結果叫做 proto
- 如果 proto 是一個 Object,把 obj 的 [[Prototype]] 指向該物件
- 如果 proto 不是一個 Object,把 obj 的 [[Prototype]] 指向 built-in Object 的 prototype 屬性
- 回傳值是 invoke [[Call]] 的結果並且把 this 指向新產生的 Obj 。因為 [[Call]] 其實是執行 Code,所以Constructor 與 Call 都同樣是去跑一遍 Code
Function 也是物件,只是這個物件帶的屬性有點不一樣,因此成為一個可以呼叫(callable)的物件。
產生 Function object 的時候,也會並為該物件設定一些 properties。好比把 [[Call]], [[Constructor]] [[Code]]。Code 的內容是 FunctionBody,[[Call]] 跟 [[Constructor]] 指向 internal method。
執行這個 function 的時候(call function),就會 invoke [[Call]],[[Call]] 指向了 built-in function,作用是拿 [[Code]] 的值來執行。
如果用 new 來執行 function,就會 invoke [[Constructor]]。spec 說 [[Constructor]] 也會去 inkvoke [[Call]],但是多了一些動作,譬如說設定 prototype,而且在 invocke [[Call]] 的時候會把 'this' 指到一開始產生的物件。
所以 new 跟平常的 function call 各自執行不同的 internal method,前者會多做一些事情,譬如說把 this 指向剛剛產生的物件,以及設定 prototype。
prototype property 跟 [[Prototype]] 是不一樣的東西。*.prototype 僅是一個 property,它什麼都可以指。而 [[Prototype]] 是 internal property,會指向 Constructor 的 prototype property,或是內建物件的 prototype property,總之就是會指向某一個物件,查找 property 的時候才有一個 chain 可以用。謹記這兩者的分別,閱讀 jQuery core 的時候會有幫助。
Subscribe to:
Post Comments (Atom)

No comments:
Post a Comment