简体   繁体   English

原型继承时 Object.create(Parent.prototype) 和 Object.create(Parent) 的区别

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

In typical JavaScript inheritance, we pass the Parent.prototype to Object.create.在典型的 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();

Is there a difference calling Object.create(Person) vs Object.create(Parent.prototype).调用 Object.create(Person) 和 Object.create(Parent.prototype) 有区别吗?

Many tutorials including the MDN article linked below pass "Parent.prototype" instead of just "Parent".许多教程,包括下面链接的 MDN 文章,都通过“Parent.prototype”而不是“Parent”。

As per MDN definition "The Object.create() method creates a new object, using an existing object as the prototype of the newly created object."根据MDN定义“Object.create() 方法创建一个新对象,使用现有对象作为新创建对象的原型。”

I tried both ways and console.log shows the same result with both approaches.我尝试了两种方法,console.log 使用两种方法显示相同的结果。

A similar question was answered here but doesn't clarify this difference.这里回答了一个类似的问题,但没有澄清这种差异。

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

You usually want to be using Object.create(prototype) for creating an object from another object and Object.create(Class.protoype) for creating an object from a function.您通常希望使用Object.create(prototype)从另一个对象创建对象,并使用Object.create(Class.protoype)从函数创建对象。

Doing Object.create(Class) will use the function as a template, meaning only the "static" fields will be transferred to the new object.执行Object.create(Class)将使用该函数作为模板,这意味着只有“静态”字段将被转移到新对象。 Object.create(Class.protoype) will use the prototype as the template, thus you will be able to get all fields that were declared using Class.prototype.field , you can also get the static fields through the constructor, and finally, once the constructor function is run on the new object the fields declared inside the constructor will also be created. 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) will form a different prototype chain as compared to Child.prototype = Object.create(Parent) Child.prototype = Object.create(Parent.prototype)将形成与Child.prototype = Object.create(Parent)不同的原型链

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

the prototype chain of foo would be Child.prototype ---> Parent.prototype ----> Object.prototype foo 的原型链将是Child.prototype ---> Parent.prototype ----> Object.prototype

simple explanation简单的解释

  • foo is created from Child, so its prototype is Child.prototype foo 是从 Child 创建的,所以它的原型是 Child.prototype
  • Child.prototype is created from Object.create(Parent.prototype), so its prototype is Parent.prototype. Child.prototype 是从 Object.create(Parent.prototype) 创建的,所以它的原型是 Parent.prototype。
  • Parent.prototype is created from Object, so it's prototype is Object.prototye Parent.prototype 是从 Object 创建的,所以它的原型是 Object.prototye
  • prototype of Object.prototype is null. Object.prototype 的原型为空。 This is where the chain end.这是链条的终点。

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

the prototype chain of foo would be different as below Child.prototype ---> Parent ----> Function.prototype ----> Object.prototype foo 的原型链将不同如下Child.prototype ---> Parent ----> Function.prototype ----> Object.prototype

simple explanation简单的解释

  • foo is created from Child, so its prototype is Child.prototype foo 是从 Child 创建的,所以它的原型是 Child.prototype
  • Child.prototype is created from Object.create(Parent), so its prototype is Parent Child.prototype 是从 Object.create(Parent) 创建的,所以它的原型是 Parent
  • Parent is created from Function, so its prototype is Function.prototype Parent 是从 Function 创建的,所以它的原型是 Function.prototype
  • Function.prototype is created from Object, so its prototype is Object.prototype Function.prototype 是从 Object 创建的,所以它的原型是 Object.prototype
  • prototype if Object.prototype is null.如果 Object.prototype 为空,则原型。 This is where the chain end.这是链条的终点。

You can further verify the prototype chain in each case by calling.您可以通过调用进一步验证每种情况下的原型链。 name is defined in Function.prototype.名称在 Function.prototype 中定义。

console.log(foo.name);

For the first case, you will get undefined because Function.prototype is not in the prototype chain whereas in the second case you will get "Parent" as the output of console.log对于第一种情况,您将获得 undefined 因为 Function.prototype 不在原型链中,而在第二种情况下,您将获得“Parent”作为 console.log 的输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM