從閱讀 ECMA 262 腳本語言規範看 JavaScript — (Objects)

Whien
4 min readNov 12, 2017

--

文件參考位置

http://www.ecma-international.org/ecma-262/8.0/index.html#sec-objects

可能要知道的概念

  • Object-oriented

JavaScript 這門腳本語言在 ECMA 262 的規範下有許多與其他語言定義上不太相同的實作方法,有些專有名詞或用法翻譯理解上會有點不太懂,不過在文章中盡可能做一個了解與心得記錄。

在 JavaScript 中任何被建立的事物都是從「Object」開始,JavaScript 中也有定義類*[1]( Reference Type — 參考型)的方法,但方式與其他如( C++, JAVA)面像對象式(Object-oriented)的語言實現方法不一樣。

ECMA 262 規定建立類型的 Object 後,通過定義一個「prototype」屬性,而這個屬性將會用來鏈結(繼承與共享)給實例,如果要繼承或創建一個實例時只要用 new 這個關鍵字就可以把創建實例並與 prototype 建立(複製)鏈結。

例如從文件上說的 Date,本身是一個內建的原生物件,如果直接呼叫 Date 則會得到原本預設所擁有的屬性與值,要創建一個新的 Date 實例時就用 new Date(2009,11) 得到的結果會是一個給予值後的新實例結果並繼承 Date 的所有建構函數中的屬性。

// 假使用 Date()
console.dir(Date());
// 得到 Sun Nov 12 2017 16:55:59 GMT+0800 (台北標準時間) 並且不帶有 Date prototype 中所擁有的任何屬性
// 改用 new Date()
console.dir(new Date(2009, 11));
// 得到 Tue Dec 01 2009 00:00:00 GMT+0800 (台北標準時間) 並且帶有 __proto__ 屬性將鏈結到 Date 的 prototype

這張圖的意思是,有一個 CF 的構造函數,這個建構函數中有 P1, P2 這兩個屬性,另外 prototype 屬性中帶有 CFp 這個屬性,CFp 可能是個任意類型,而 cf1, cf2, cf3, cf4 與 cf5 是通過繼承創建出來的實例。

以程式角度來看,而如何創建一個構造函數就用 Function 來建造

// 構造函數(原型模式)
const CF = function() {};
CF.prototype.CFp = 'Im CFp';
CF.P1 = 'CF-P1';
CF.P2 = 'CF-P2';
// CF 實例
const ct1 = new CF();
const ct2 = new CF();
const ct3 = new CF();
const ct4 = new CF();
const ct5 = new CF();
ct1.P1 // 不可見 undefined
ct1.CFp // Im CFp

發現 ct1.P1 是看不到 CF 的 P1 屬性的,其原因是因為建立了新實例 ct1 後繼承的是 CF 的 prototype 底下屬性,並不是 CF 本身的屬性,因此在 ct1 中繼承到的只有 CFp 這個屬性。

因此可以了解在此規範中,如果要建立一個實例並繼承一個 Object,Object 中就必須帶有 prototype,並且實例只會繼承 prototype 中的屬性

如果文中有更好的表達方式或錯誤的地方歡迎與我討論,Welcome so much!

至於怎麼繼承的,是通過 __proto__ 來鏈結 prototype,實現詳細內容可以參考底下提供的其他作者連結。

--

--

Whien

遨遊在硬體與軟體世界中,對於計算機一切事物都充滿好奇及熱情。