js 里的原型继承模型
JavaScript 是基于原型实现面向对象的,那么在JS中,面向对象概念中的继承自然也是基于原型。
js本质上没有类,即使是ES6里面的class,也只是语法糖,实际上是函数,class实现的继承最终转为ES5还是基于原型实现继承。
函数才是js里的一等公民。
寄生组合式继承
网上对js继承有很多方案,社区经过这么多年的发展也衍生出很多方案。但最终形成的继承方案可以描述为: 寄生组合式继承
代码实现
function createObject(o) {
function Fn() {}
Fn.prototype = o
return new Fn()
}
//核心函数(组合函数)
function inheritPrototype(SubType, SuperType) {
//createObject方法作用:创建一个新对象,将新对象的原型指向父类的原型对象
// SubType.prototype = Objec.create(SuperType.prototype)
//将子类的原型指向新创建的对象的原型对象
SubType.prototype = createObject(SuperType.prototype)
//给新创建的对象添加一个constructor属性,指向子类
Object.defineProperty(SubType.prototype, "constructor", {
enumerable: false,
configurable: true,
writable: true,
value: SubType
})
}
//定义一个Person类
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.eating = function() {
console.log(this.name + " is eating")
}
//定义一个Student类
function Student(name, age, sno, score) {
//借用父类函数,将父类的属性保存到子类对象。(可以理解为寄生)
Person.call(this, name, age)
this.sno = sno
this.score = score
}
//调用函数Student类继承Person类
inheritPrototype(Student, Person)
Student.prototype.studying = function() {
console.log(this.name + " is studying")
}
//测试
var stu = new Student("jack", 18, 9523, 150)
console.log(stu) //Student { name: 'jack', age: 18, sno: 9523, score: 150 }
stu.studying() //jack is studying
stu.eating() //jack is eating
ES6的class实现继承
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
eating() {
console.log(this.name + " is eating")
}
static staticMethod() {
console.log("PersonStaticMethod")
}
}
class Student extends Person {
constructor(name, age, sno) {
super(name, age)
this.sno = sno
}
studying() {
console.log(this.name + " is studying")
}
eating() {
console.log(this.name + " is eating")
}
// 重写静态方法
static staticMethod() {
super.staticMethod()
console.log("StudentStaticMethod")
}
}
var stu = new Student("jack", 18, 150)
console.log(stu) //Student { name: 'jack', age: 18, sno: 150 }
stu.studying() //jack is studying
stu.eating() //jack is eating