在将继承之前先说一下ES5和ES6的构造函数语法
ES5的构造函数语法
function CreateObj1(name,age){
this.name = name;
this.age = age;
}
createObj1.prototype.fun = function(){
console.log('我是ES5语法创建的实例化对象')
}
ES6的构造函数语法
class CreateObj2{
constructor(name,age){
this.name = name;
this.age = age;
}
fun(){
console.log('我是ES6语法创建的实例化对象')
}
}
为什么要使用继承?
创建新的构造函数时,有一些属性或者方法,与之前的构造函数相同
为了节约代码,可以从之前的构造函数中,继承属性和方法
对不同的属性和方法,再重新定义
ES6继承语法
class 子类构造函数名称 extends 父类构造函数名称{}
constructor 构造器中,定义参数
参数可以是从父级继承来的,也可以是子类自己定义的
从父类继承的属性必须用 super(属性) 来定义
也可以定义子类的属性和子类的方法
父类的所有方法都会继承
ES5 的继承语法
语法1: 原型继承
语法2: 借用构造函数继承
语法3: 组合继承
1、原型继承
所谓的原型继承,就是通过 原型链 将父类构造函数 和 子类 构造函数 串联起来
所谓的原型链,本质就是通过 proto 将实例化对象,构造函数 串联起来,可以调用数据
实例化对象,通过 proto 访问 构造函数 prototype 中存储的函数方法
定义一个父类构造函数
function Father(name,age){
this.name = name;
this.age = age;
}
通过父类构造函数生成一个实例化对象
const objFather = new Father('张三',18);
定义一个子类构造函数
function Son(){}
在子类的 prototype 中 添加 父类构造函数生成的实例化对象
Son.prototype = objFather;
语法2: 借用构造函数继承
主要继承 属性
定义父类构造函数
function Father(name,age){
this.name = name;
this.age = age;
}
Father.prototype.fun1 = function(){};
Father.prototype.fun2 = function(){};
使用父类构造函数,生成一个对象
const objFather = new Father('张三' , 18);
定义子类构造函数
function Son(sex){
//调用父类构造函数,this的指向就会出现问题
//要通过 call 方法,改变this指向
//父类构造函数的this指向,应该是父类生成的实例化对象
//现在需要指向子类构造函数生成的实例化对象,也就是子类的this
//这里的this,在子类构造函数中,就是子类的this,就是指向子类构造函数生成的实例化对象
// Father()构造函数,this的指向,变成了,子类this的指向,李四和20的两个实参
//就赋值给了,子类构造函数,生成的实例化对象上了
//效果是,通过父类,给子类生成的实例化对象,定义属性和属性值
//不能继承父类的函数方法
Father.call(this , '李四' , 20);
//子类自定义的方法
this.sex = sex;
}
3: 组合继承
同时使用 原型继承和借用构造函数继承
原型继承 : 可以继承父类的方法 但是不能定义继承父类的属性
借用构造函数继承 : 可以定义继承父类的属性,但是不能继承父类的方法
// 定义父类
function Father(name,age){
this.name = name;
this.age = age;
}
Father.prototype.fun1 = function(){};
Father.prototype.fun2 = function(){};
使用父类构造函数,生成一个对象
const objFather = new Father('张三' , 18);
创建子类
function Son(sex){
// 通过借用构造函数,继承父类的属性
Father.call(this,'李四' , 20);
// 定义子类,自定义属性
this.sex = sex;
}
通过原型继承,继承父类的方法
Son.prototype = objFather;
定义子类,自定义函数方法
Son.prototype.f = function(){}