原型(prototype)和继承(inherit)

在class之前,如何实现类似的特性,还是使用函数(function)

function Foo(name) {
  this.name = name
}
function Bar(name, avatar) {
  Foo.call(this, name) // 调用Foo来继承
  this.avatar = avatar
}
const o = new Bar('Bt', 'pic')
console.log(o.name) // 'Bt'
console.log(o.avatar) // 'pic'

在Foo的prototype属性上添加方法,这样Foo的实例都可以调用

Foo.prototype.hello = function() {
  console.log(this.name + ' hello')
}

o.hello() // o.hello is not a function 

但是出现一个问题,Bar并没有继承此方法,所以我们需要在Bar的prototype属性上面添加此方法,也就是从Foo的prototype属性上继承,那如何书写呢?

我们可以把prototype看作一个对象,使用Object.create来创建一个新的对象,这个对象里面包含的其实就是Foo.prototype的内容,代码如下:

Bar.prototype = Object.create(Foo.prototype) // 此代码一定要放在实例的前面,不然会报错

我们可以通过console.log(Bar.prototype)验证下,返回的是Foo.prototype对象, 里面包含了hello方法(在chrome调试下)

我们在调用o.hello,就不会报错了,但是当我们再查看刚刚返回的Foo.prototype对象,里面的constructor属性对应的是 Foo(name)函数,这个不符合预期,我们希望Bar的constructor属性对应的是

Bar(name, avatar)函数,所以需要修改下Bar.prototype对象中的属性constructor,如何修改呢?我们可以使用Object.defineProperty方法,代码如下:

Object.defineProperty(Bar.prototype, 'constructor', {
  value: Bar,
  enumerable: false,
  writable: true
 })
console.log(Bar.prototype.constructor) // Bar(name, avatar)

还需完善修改...

引用

原文地址:https://www.cnblogs.com/re-doc/p/14088972.html