这两种继承方式之间有区别吗?

时间:2019-05-06 21:51:36

标签: javascript oop inheritance prototype

问题是当我们要建立继承时,这两种方法之间没有区别:

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

和:

Child.prototype.__proto__ = Father.prototype;

第一个选项允许我们获取父亲共享的所有属性和方法,但在此过程中将覆盖Child构造函数。这就是我们需要再次将Child构造函数设置回Child的原因。第二种方法执行相同的操作,但没有覆盖。那么,为什么人们/指南不使用第二种选择?我有什么不对吗?

这是一个完整的示例:

function Father( name ) {
  this.name = name;
}

Father.prototype.getName = function() {
  console.log( this.name );
}

function Child( name, lastName ) {
  Father.call( this, name );
  this.lastName = lastName;
}

Child.prototype.__proto__ = Father.prototype;

//Child.prototype = Object.create( Father.prototype );
//Child.prototype.constructor = Child;

var c = new Child( 'Will' , 'Travolta');
c.getName();

2 个答案:

答案 0 :(得分:2)

  

这两种方法之间没有区别

结果的确没有区别(除了一些小细节,例如.constructor属性的可枚举性)。

  

那么,为什么人们/指南不使用第二种选择?

因为__proto__ is deprecated,而Object.create可以在任何地方工作。它已通过ES5进行了标准化,可以轻松地填充到较旧的环境中。

从ES6开始,您也可以使用Object.setPrototypeOf,但是从ES6开始,您只需编写class Child extends Father { … }

答案 1 :(得分:0)

正如评论中所写,__proto__现在不推荐使用Object.getPrototypeOf()Object.setPrototypeOf()。除此之外,还有很多关于完全覆盖构造函数原型与单独向其添加/删除属性/方法的正确性的公开讨论。两种做法都被广泛接受/实现,并且事实是,销毁prototype.constructor(或对象的所有原型)在大多数情况下没有害处。我更喜欢个人操作,因为它应该是未来的证明。请注意,编写Child.prototype = Object.create(Father.prototype)会破坏原始原型。