每個函數都有一個prototype
屬性,創建函數對象時,它的分配,它指向一個新創建的對象,從Object.prototype
繼承,它有一個constructor
屬性,簡單地回指向函數本身。
prototype
屬性的目的是給出一種方法來實現繼承,使用構造函數。當您使用new
運算符調用函數時,它將創建一個從該構造函數的prototype
繼承的新對象。現在
,該constructor
財產的目的是有辦法重新引用已創建的對象的構造函數,例如:
function Foo() {}
// default value of the property:
Foo.prototype.constructor == Foo; // true
此屬性是由的Foo
「實例」繼承,這樣你就可以知道哪個構造函數用於創建一個對象:如果您分配一個新的對象給函數的原型
var foo = new Foo();
foo.constructor == Foo;
,這種關係將丟失:
function Bar() {}
Bar.prototype = { inherited: 1 };
Bar.prototype.constructor == Bar; // false
Bar.prototype.constructor == Object; // true
而且這也影響了功能的實例:
var bar = new Bar();
bar.constructor == Bar; // false
bar.constructor == Object; // true
另一個類似的例子是,當你有使用構造繼承的兩個或兩個以上的水平,最常見的方式是用來表示繼承關係在功能之間,是指定第二級的屬性,例如:
function Parent() {}
function Child() {}
Child.prototype = new Parent();
上面的代碼有幾個問題,第一,它執行父構造函數來創建的繼承關係的邏輯,但那是另一個故事,在上面的例子中constructor
財產也受到影響,因爲我們更換完全Child.prototype
對象:
var child = new Child();
child.constructor == Parent; // true
如果我們更換分配給它更換後的Child.prototype
的constructor
屬性的值,它會顯示預期的行爲:
function Child() {}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
var child = new Child();
child.constructor == Child; // true
來源
2011-10-10 22:00:11
CMS
感謝您的詳細解釋。這一切都有道理。唯一讓我感到困惑的東西,但我可以忽略的是它看起來有點兒在Child.prototype.constructor = Child –
@Nik,不客氣!是的,這確實是循環設計,例如:'Object.prototype.constructor.prototype.constructor.prototype.constructor == Object;';-) – CMS