簡體   English   中英

原型繼承時 Object.create(Parent.prototype) 和 Object.create(Parent) 的區別

[英]Difference between Object.create(Parent.prototype) vs Object.create(Parent) during prototype inheritance

在典型的 JavaScript 繼承中,我們將 Parent.prototype 傳遞給 Object.create。

function Parent() {};

function Child() {
    Parent.call(this);
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

var foo = new Child();

調用 Object.create(Person) 和 Object.create(Parent.prototype) 有區別嗎?

許多教程,包括下面鏈接的 MDN 文章,都通過“Parent.prototype”而不是“Parent”。

根據MDN定義“Object.create() 方法創建一個新對象,使用現有對象作為新創建對象的原型。”

我嘗試了兩種方法,console.log 使用兩種方法顯示相同的結果。

這里回答了一個類似的問題,但沒有澄清這種差異。

var o = Object.create(Object.prototype); // same as var o = {};

您通常希望使用Object.create(prototype)從另一個對象創建對象,並使用Object.create(Class.protoype)從函數創建對象。

執行Object.create(Class)將使用該函數作為模板,這意味着只有“靜態”字段將被轉移到新對象。 Object.create(Class.protoype)將使用原型作為模板,因此您將能夠獲取使用Class.prototype.field聲明的所有字段,您也可以通過構造函數獲取靜態字段,最后,一次構造函數在新對象上運行,構造函數中聲明的字段也將被創建。

 function Foo() { // Only visible by prototype after running constructor this.test = function() {}; } Foo.prototype.bar = "Bar"; // Visible by prototype Foo.fooBar = "FooBar"; // Visible by class var classFoo = Object.create(Foo); var protoFoo = Object.create(Foo.prototype); // fooBar is static, so it can be viewd bu classFoo console.log(classFoo.fooBar); // bar was added to the prototype, cant be viewed console.log(classFoo.bar); // test is declared in the constructor, to which there is no pointer from classFoo console.log(classFoo.test); // this constructor is the base constructor for all classes console.log(classFoo.constructor); // fooBar was added to the constructor, so it cannot be viewed this way console.log(protoFoo.fooBar); // but it can be viewed like this console.log(protoFoo.constructor.fooBar); // this is the Foo function/constructor console.log(protoFoo.constructor); // bar is added to the prototype so it can be viewed console.log(protoFoo.bar); // test has not been declared yet as the constructor has not been run yet console.log(protoFoo.test); // the foo function is run with protoFoo as this protoFoo.constructor(); // the test function has now been added to protoFoo console.log(protoFoo.test);

Child.prototype = Object.create(Parent.prototype)將形成與Child.prototype = Object.create(Parent)不同的原型鏈

使用Child.prototype = Object.create(Parent.prototype)

foo 的原型鏈將是Child.prototype ---> Parent.prototype ----> Object.prototype

簡單的解釋

  • foo 是從 Child 創建的,所以它的原型是 Child.prototype
  • Child.prototype 是從 Object.create(Parent.prototype) 創建的,所以它的原型是 Parent.prototype。
  • Parent.prototype 是從 Object 創建的,所以它的原型是 Object.prototye
  • Object.prototype 的原型為空。 這是鏈條的終點。

Child.prototype = Object.create(Parent);

foo 的原型鏈將不同如下Child.prototype ---> Parent ----> Function.prototype ----> Object.prototype

簡單的解釋

  • foo 是從 Child 創建的,所以它的原型是 Child.prototype
  • Child.prototype 是從 Object.create(Parent) 創建的,所以它的原型是 Parent
  • Parent 是從 Function 創建的,所以它的原型是 Function.prototype
  • Function.prototype 是從 Object 創建的,所以它的原型是 Object.prototype
  • 如果 Object.prototype 為空,則原型。 這是鏈條的終點。

您可以通過調用進一步驗證每種情況下的原型鏈。 名稱在 Function.prototype 中定義。

console.log(foo.name);

對於第一種情況,您將獲得 undefined 因為 Function.prototype 不在原型鏈中,而在第二種情況下,您將獲得“Parent”作為 console.log 的輸出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM