ES5继承:
基本思想:利用原型链让一个引用类型继承另一个引用类型的属性和方法(即通过prototype和构造函数实现)
实质:将父类添加到子类的原型链上去
ES6继承:
基本思想:通过extend关键字实现继承,子类可以继承父类中所有的方法和属性,子类必须在construc()方法中调用super()方法,因为新建的子类没有自己的this对象,而是继承了父类的this对象;
实质:利用extend关键字继承父类,然后继承父类的属性和方法
使用:
解决代码的复用
使用extends关键字实现继承
子类可以继承父类中所有的方法和属性
子类只能继承一个父类(单继承),一个父类可以有多个子类
子类的构造方法中必须有super()来指定调用父类的构造方法,并且位于子类构造方法中的第一行
子类中如果有与父类相同的方法和属性,将会优先使用子类的(覆盖)
举例说明:
// 用户
function User(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
User.prototype.sayHello = function () {
console.log(this.firstName, this.lastName, this.age);
}
var user = new User('zhangsan', '', 35);
第一种写法--圣杯模式:
// 1. 圣杯模式 写法1
function F(){}
F.prototype = User.prototype;
vipUser.prototype = new F();
第二种写法:
// 2. 写法2
vipUser.prototype = Object.create(User.prototype);
// 记录真正的构造函数
vipUser.prototype.constructor = vipUser;
// 记录真正的超类 继承自谁
vipUser.prototype.uber = User.prototype;
// vip
function vipUser(firstName, lastName, age, money) {
// this ->{}
User.call(this, firstName, lastName, age);
this.money = money;
}
vipUser.prototype.update = function () {
this.money -= 10000;
console.log(this.money);
}
var vip = new vipUser('WU', 'XIAN', 38, '100000');
console.log(vipUser.prototype.constructor);
vip.sayHello();
vip.update();
ES5继承写法:
// 原来的继承
function Amimal(type,name,age,sex){
this.type = type;
this.name = name;
this.age = age;
this.sex = sex;
}
Amimal.prototype.print = function(){
console.log(`种类:${this.type}`)
console.log(`名字:${this.name}`)
console.log(`年龄:${this.age}`);
console.log(`性别:${this.sex}`)
}
function Dog(name,age,sex){
// 只是借助父类的构造函数,当前只是引用不能构成原型链
Amimal.call(this,"犬类",name,age,sex)
}
Object.setPrototypeOf(Dog.prototype,Amimal.prototype)//设置某个对象的隐式原型 ES5
const d = new Dog("旺财",5,"公")
console.log(d)
d.print()//原型指向object
ES6继承写法:
继承的关键字 extends 用于在类中定义
super 两种用法
1.直接当成函数使用,表示调用父类的构造器
2.当成对象使用,表示父类的原型
class Amimal {
constructor(type,name,age,sex){
this.type = type;
this.name = name;
this.age = age;
this.sex = sex;
}
print(){
console.log(`种类:${this.type}`)
console.log(`名字:${this.name}`)
console.log(`年龄:${this.age}`);
console.log(`性别:${this.sex}`)
}
}
class Dog extends Amimal{
// 如果定义了constructor 表示当前对象时子类,则必须在constrcutor第一行手动调用父类的构造函数,否则会报错
constructor(name,age,sex,loves){
super("犬类",name,age,sex)
this.loves = loves;
}
// 如果说子类不写constructor,则会有默认的构造器,自动去调用父类的构造器
print(){//子类和父类有同名的方法,先用自己的
super.print()//2
console.log(`爱好:${this.loves}`)
}
}
const d = new Dog("旺财",5,"公","吃骨头")
console.log(d)
d.print()