首先我們使用 function 來建構一個物件 (Object Constructor)
function Earth(){};接著建立一個物件實例(Object Instances)
var e1 = new Earth();建立實例的過程中不單單是設定 name 屬性, 還把 Employee 所繼承的物件帶給 e1
new 的動作相當於
var e1 = {}; e1.__proto__ = Earth.prototype;//__proto__ Non-standard Earth.call(e1);使用 Chrome Developer Tools 可看出 e1 的屬性和方法
測試 e1.constructor (關於 constructor 參考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor)
> e1.constructor [Function: Earth]e1 沒有 constructor 屬性, 所以往內部查找 __proto__ 正好有這屬性, 所以輸出 __proto__.constructor, 由此可推論 e1.constructor == e1.__proto__.constructor
> e1.constructor == e1.__proto__.constructor true > Earth.prototype.constructor == e1.constructor true從上面的例子可看出 prototype 屬性會決定繼承的物件, 改變 prototype 屬性後, 再 new 出來的物件繼承關係也跟著改變
接下來說明 instanceof, instanceof 在 Java 中也有這個功能, 作用也類似,
Javascript 的 instanceof 會從 prototype chain 查找, 是否包含建構物件的 prototype, MDN 中有實做出類似 instanceof 內部運作的方式, 可參考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FDetails_of_the_Object_Model#Determining_instance_relationships
做個綜合測試
> function X(){} undefined > X.constructor //所有 function 都是 Function object function Function() { [native code] } > X.prototype.constructor //參考到 X function X(){} > var o1 = new X() undefined > o1 instanceof X true > o1.constructor //等於 o1.__proto__.constructor function X(){} > X.prototype = [] //改變 X.prototype 參考到陣列 [] > var o2 = new X() undefined > o1 instanceof X // 相當於 o1.__proto__ == X.prototype false > X.prototype.isPrototypeOf(o1); false > o2 instanceof X // 相當於 o2.__proto__ == X.prototype true > o1 instanceof Array false > o2 instanceof Array true > X.constructor function Function() { [native code] } > X.prototype.constructor function Array() { [native code] } > o1.constructor function X(){} > o2.constructor function Array() { [native code] }所有 function 都是 Function object 的實例, 所以 X.constructor 指向 Function, X.prototype.constructor 指向 X,
建立物件會沿著 prototype chain 尋找, 因此
var o1 = new X();相當於
var o1 = {}; o1.__proto__ = X.prototype;//reference X X.call(o1);而 X.prototype = []; 改變了 prototype 的參考對象, 因此 X 的 prototype chain 改變了
var o2 = {}; o2.__proto__ = X.prototype;//reference Array X.call(o2);要怎麼讓 o1 instanceof X 變成 true 呢? 只要讓 o1.__proto__ 和 X.prototype 一致就行了
> o1.__proto__ = X.prototype; [] > o1 instanceof X; true > X.prototype.isPrototypeOf(o1); true
0 comments:
Post a Comment