原型继承期间Object.create(Parent.prototype)与Object.create(Parent)之间的差异

时间:2019-01-25 07:59:14

标签: javascript

在典型的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在两种方法中都显示了相同的结果。

一个similar question was answered here,但没有阐明这种区别。

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

2 个答案:

答案 0 :(得分:0)

您通常希望使用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);

答案 1 :(得分:0)

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 的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
  • prototype 如果 Object.prototype 为空。这是链条的终点。

您可以通过调用进一步验证每种情况下的原型链。名称在 Function.prototype 中定义。

console.log(foo.name);

对于第一种情况,您将得到 undefined 因为 Function.prototype 不在原型链中,而在第二种情况下,您将得到“Parent”作为 console.log 的输出