对象的继承

2020-08-31  本文已影响0人  释梦石

构造函数继承

让一个构造函数继承另一个构造函数,是非常常见的需求。这可以分成两步实现。第一步是在子类的构造函数中,调用父类的构造函数。

function Person (name, age) {
  this.type = 'human'
  this.name = name
  this.age = age
}

function Student (name, age) {
  // 借用构造函数继承属性成员
  Person.call(this, name, age)
}

var s1 = Student('张三', 18)
console.log(s1.type, s1.name, s1.age) // => human 张三 18

this是子类的实例。在实例上调用父类的构造函数Person ,就会让子类实例具有父类实例的属性。

构造函数原型继承-拷贝继承(for-in)

function Person (name, age) {
  this.type = 'human'
  this.name = name
  this.age = age
}

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

function Student (name, age) {
  Person.call(this, name, age)
}
// 原型对象拷贝继承原型对象成员
for(var key in Person.prototype) {
  Student.prototype[key] = Person.prototype[key]
}
var s1 = Student('张三', 18)
s1.sayName() // => hello 张三

原型继承

function Person (name, age) {
  this.type = 'human'
  this.name = name
  this.age = age
}

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

function Student (name, age) {
  Person.call(this, name, age)
}
// 利用原型的特性实现继承
Student.prototype = new Person()
var s1 = Student('张三', 18)
console.log(s1.type) // => human
s1.sayName() // => hello 张三

我们需要注意的是,如果Student里边儿没有改变调用Person的this指向,那所有Student的子类的属性都是共享的,因为他们是来自Student,那修改一个类中的值,另外一个子类也会受影响。我们来看


原型继承的问题

为了避免这个问题,我们要在Student的构造函数中改变this的指向,让Student的子类在Student的构造函数中调用Person的构造函数时,this指向Student的子类。

多重继承

JavaScript 不提供多重继承功能,即不允许一个对象同时继承多个对象。但是,可以通过变通方法,实现这个功能。

function M1() {
  this.hello = 'hello';
}

function M2() {
  this.world = 'world';
}

function S() {
  M1.call(this);
  M2.call(this);
}

// 继承 M1
S.prototype = Object.create(M1.prototype);
// 继承链上加入 M2
Object.assign(S.prototype, M2.prototype);

// 指定构造函数
S.prototype.constructor = S;

var s = new S();
s.hello // 'hello'
s.world // 'world

上面代码中,子类S同时继承了父类M1和M2。这种模式又称为 Mixin(混入)。

上一篇下一篇

猜你喜欢

热点阅读