new
關鍵字做了什麼?
在JavaScript中,使用new關鍵字後,意味着做了如下四件事情:
創建一個新的對象,這個對象的類型是
object
;設置這個新的對象的內部、可訪問性和
[[prototype]]
(即obj.__proto__
)屬性爲構造函數(指prototype.construtor
所指向的構造函數)中設置的;執行構造函數,當this關鍵字被提及的時候,使用新創建的對象的屬性;
返回新創建的對象(除非構造方法中返回的是‘無原型’)。
在創建新對象成功之後,如果調用一個新對象沒有的屬性的時候,JavaScript會延原型鏈向止逐層查找對應的內容。這類似於傳統的‘類繼承’。
注意:在第二點中所說的有關[[prototype]]
屬性,只有在一個對象被創建的時候起作用,比如使用new
關鍵字、使用Object.create
、基於字面意義的(函數默認爲Function.prototype
,數字默認爲Number.prototype
等)。它只能被Object.getPrototypeOf(someObject)
所讀取。沒有其他任何方式來設置或讀取這個值。
樣例說明
ObjMaker = function() {
this.a = 'first';
};
ObjMaker只是一個用於作爲 構造器 的方法,沒有其他意義。
ObjMaker.prototype.b = 'second';
與其他函數類似, ObjMaker擁有一個可被我們修改的prototype
屬性. 我們添加一個屬性b
給它。與所有對象一樣,ObjMaker也擁有一個不可訪問的[[prototype]]
屬性,我們無法對其進行改變。
obj1 = new ObjMaker();
這裏發生了三件事情:
- 一個叫
obj1
的空對象被創建,首先obj1
與{}
一致; obj1
的[[prototype]]
屬性被設置爲ObjMaker的原型屬性的拷貝;- ObjMaker方法被執行,所以
obj1.a
被設置爲‘first‘。
obj1.a; //返回'first'。
obj1.b; //返回'second'。
//obj1沒有'b'屬性。所以JavaScript在它的[[prototype]]中查找。它的[[prototype]]與ObjMaker.prototype屬性一致。而ObjMaker.prototype屬性有一個叫'b'的屬性,其值爲'second',所以返回'second'。
模仿繼承
你可以使用如下的方式實例化ObjMaker類的子類:
SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker();
由於這裏使用了new關鍵字,所以SubObjMaker的[[prototype]]
屬性被設置爲ObjMaker.prototype的一個拷貝。
SubObjMaker.prototype.c = 'third';
obj2 = new SubObjMaker();
obj2的[[prototype]]
屬性被設置爲SubObjMaker的prototype屬性的一個拷貝。
obj2.c; //返回'third', 來自SubObjMaker.prototype
obj2.b; //返回‘second’。來自ObjMaker.prototype
obj2.a; //返回‘first’。來自SubObjMaker.prototype,這是因爲SubObjMaker是使用ObjMaker的構造方法創建的,這個構造方法賦值給a。