首先我們使用 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