javascript中的对象相关方法二(对象继承)

101 阅读1分钟

前言

这次想讲一些对象继承的方式,主要有原型链继承经典组合继承寄生组合继承

原型链继承

主要是通过原型链实现继承,此方法有很多弊端,不推荐

function Person() {
  this.name = "aaa"
  this.friends = [1,2]
}
Person.prototype.eating = function() { console.log(this.name + " eating~")}

function Student() {
  this.sno = 111
}
Student.prototype = new Person() // 改变子类的原型
Student.prototype.studying = function() { console.log(this.name + " studying~")}
const stu = new Student()

# 弊端
1. 打印对象时,继承的属性是看不到的
console.log(stu);  // Person { sno: 111 }
console.log(stu.name); // aaa
2. 无法传递参数
3. 属性被多个对象共享时,如果属性是一个引用类型,引用类型会共享
const stu = new Student()
const stu2 = new Student()
console.log(stu.friends);  // [ 1, 2 ]
stu2.friends[0] = 5
console.log(stu.friends);  // [ 5, 2 ]

经典组合继承

function Person(name, age, friends) {
  this.name = name
  this.age = age
  this.friends = friends
}
function Student(name, age, friends, sno) {
  Person.call(this, name, age, friends)
  this.sno = 111
}
var p = new Person()
Student.prototype = p
var stu = new Student("why", 18, ["kobe"], 111)

# 弊端
1. Person函数至少被调用了两次
2. 所有的子类对象会拥有两份父类的属性,一份在子类实例上,一份在子类的原型对象中

寄生组合继承

推荐使用的继承方法。

function inheritPrototype(SubType, SuperType) {
  SubType.prototype = Object.create(SuperType.prototype)  
  // 这一步一定要操作,constructor属性重新指回自己
  Object.defineProperty(SubType.prototype, "constructor", { 
    enumerable: false,
    configurable: true,
    writable: true,
    value: SubType
  })
}

function Person(name, age, friends) {
  this.name = name
  this.age = age
  this.friends = friends
}
Person.prototype.eating = function() { console.log("eating~")}

function Student(name, age, friends, sno, score) {
  Person.call(this, name, age, friends)
  this.sno = sno
  this.score = score
}
inheritPrototype(Student, Person)
Student.prototype.studying = function() { console.log("studying~")}

var stu = new Student("why", 18, ["kobe"], 111, 100)
stu.eating()  // eating~
console.log(Student.prototype);  // Person { studying: [Function (anonymous)] }
console.log(Student.prototype.constructor);  // [Function: Student]

总结

这几种方法都可以实现对象的继承,推荐使用最后一种寄生组合继承,这是我跟一位大佬(coderwhy王元红老师)学的。