js之实现继承的几种方式

118 阅读2分钟

原型式继承

原型式继承利用了原型链的特点,当你在当前对象中找不到内容的时候,就会去它的原型对象上找,这样就可以实现继承的效果。

Object.create实现继承

let obj = {
  name: "wjj",
  age: 10,
  sayName() {
    console.log(this.name);
  },
};
function protoExtendObj(o) {
  // Object.create方法的作用是,创建一个对象,这个对象的原型指向传入的对象
  return Object.create(o);
}

let newObj = protoExtendObj(obj);
console.log(newObj.__proto__ === obj);  //true
newObj.name = "wjj2";
newObj.sayName();  //wjj2

Object.setProrotypeOf也能实现原型式继承

let obj = {
  name: "wjj",
  age: 10,
  sayName() {
    console.log(this.name);
  },
};
function protoExtendObj(o) {
  //setPrototypeOf的作用是,将第一个参数的原型指向第二个参数
  let obj = {}
  Object.setPrototypeOf(obj,o)
  return obj
}

let newObj = protoExtendObj(obj);
console.log(newObj.__proto__ === obj);  //true
newObj.name = "wjj2";
newObj.sayName();  //wjj2

寄生式继承

但是上述继承方式有个缺点,就是给构建出来的对象添加自定义属性时,每个对象都要手动添加,于是我们可以将这个过程封装到工厂函数中


let obj = {
  name: "wjj",
  age: 10,
  sayName() {
    console.log(this.name);
  },
};
function protoExtendObj(o, name, age) {
  let res = Object.create(o);
  //在工厂函数中对传入的参数进行注册(其实就是类似于new方法里面要做的事情)
  res.name = name;
  res.age = age;
  return res;
}

let newObj = protoExtendObj(obj, "jzsp", 20);
console.log(newObj.__proto__ === obj); //true
newObj.sayName(); //jzsp

寄生组合式继承

上面两种继承方式都是继承另一个对象,其实真正的继承是类与类之间的继承。es5中是没有类的概念的,顶多就只有构造函数的概念。那么我们怎么实现形如类与类继承的效果呢?

假设我们有一个person构造函数和student构造函数,希望student继承person

image.png

function person(name, age) {
  this.name = name;
  this.age = age;
}
person.prototype.eating = function () {
  console.log(this.name + "is eating");
};


function student(name, age, sto) {
  //借用构造函数
  person.call(this, name, age);
  this.sto = sto;
}
// 利用原型,继承方法
student.prototype = Object.create(person.prototype)
student.prorotype.constructor = student

const stu = new student('wjj',20,123456)
console.log(stu)
stu.eating()

image.png

es6实现继承

在es6引入了class的概念之后,实现继承就非常的简单了,还是上面person和student的案例


class person{
  name
  age
  constructor(name,age){
    this.name = name 
    this.age = age
  }
  eating(){
    console.log(this.name + 'is eating')
  }
}

class student extends person{
  sto
  constructor(name,age,sto){
    //在构造函数中,利用super调用构造方法
    super(name,age)
    this.sto = sto
  }
}

const stu = new student('wjj',20,123456)
console.log(stu)
stu.eating()

image.png