继承实现以下需求
- Student 继承Person
- Person 包含一个实例变量 name, 包含一个方法 printName
- Student 包含一个实例变量 score, 包含一个实例方法printScore
- 所有Person和Student对象之间共享一个方法
es6 实现继承
class Person {
constructor(name) {
this.name = name;
}
printName() {
console.log('This is printName');
}
commonMethods() {
console.log('我是共享方法');
}
}
class Student extends Person {
constructor(name, score) {
super(name);
// super作为函数被调用时,代表父类的构造函数,相当于Person.prototype.constructor.call(this)
this.score = score;
}
printScore() {
console.log('This is printScore');
}
}
let stu = new Student('小红', 1);
let person = new Person('小紫');
console.log(stu.commonMethods === person.commonMethods);//true
console.log('stu', stu)
核心: 使用extends表明继承自那个父类,并且在自构造函数中必须调用super. class的本质还是函数
tips
- constructor 是类的默认方法,通过new 命令生成对象实例时,会自动执行constructor。一个类必须有constructor,如果没有显示定义,一个空的constructor会被添加
- constructor的作用就是表名某个实例对象是由哪个构造函数产生的
- constructor是表示原型和实例关联关系的一个属性。所以当修改原型对象的时候,也会修改constructor。
- Star.prototype = {}给原型重新赋值,此时会丢失构造器,我们需要手动定义构造器,指回构造函数本身
组合继承
function Person(name) {
this.name = name
this.printNama = function () {
console.log('Person printNama ');
}
}
Person.prototype.commen = function () {
console.log('commenMethods')
}
function Student(name, score) {
Person.call(this, name)
this.score = score
this.printScore = function () {
console.log('Student printScore');
}
}
Student.prototype = new Person()
let person = new Person('小红', 30)
let student = new Student('小敏', 20)
console.log(Student.commen === Person.commen)
console.log('student', student)
console.log('person', person)
tips
- 组合继承,就是利用原型链来实现方法共享,利用构造函数来实现属性属性共享.通过在原型上定义方法,实现了函数的复用,又能保证每个实例有自己的属性
寄生式继承
function Person(name) {
this.name = name
this.printNama = function () {
console.log('Person printNama ');
}
}
Person.prototype.commen = function () {
console.log('commenMethods')
}
function Student(name, score) {
Person.call(this, name)
this.score = score
this.printScore = function () {
console.log('Student printScore');
}
}
Student.prototype = Object.create(Person.prototype)
let person = new Person('小红', 30)
let student = new Student('小敏', 20)
console.log(Student.commen === Person.commen)
console.log('student', student)
console.log('person', person)
「tips」
寄生式继承: 主要就是解决new两次和 执向同一个原型的问题,所以将new Person() 换成 Person.prototype。 并且使用Object.create()
对比
class 继承: 使用extends表明继承自那个父类,并且在子构造函数中调用super,进行传参。
原型链继承:由于两个构造函数,指向同一个原型对象,一个改变,另一个也会改变
构造函数继承:不能继承实例对象的方法
组合继承:继承的时候,实例化一次,自己实例化一次
寄生式继承:解决了实例化两次的问题,并且使用Object.create() 实现了 创建一个新对象,使用现有的对象来提供新创建的对象的proto
Object.create()必须接收一个对象参数,创建的新对象的原型指向接收的参数对象,new Object() 创建的新对象的原型指向的是 Object.prototype. (表述有点啰嗦,简洁点说就是前者继承指定对象, 后者继承内置对象Object)