# javascript 继承
我们知道js是弱类型,半面向对象语言,在实现继承时并没有那些面向对象语言那样方便 下面我们总结几种js实现继承的方法,并总结他们的优缺点。
# 原型赋值发
function Per(name){
this.name = name || '码不停息';
}
Per.prototype.say = function(){
console.log(this.name)
}
function Sun(){}
Sun.prototype = new Per();
const sun = new Sun();
console.log(sun.name) // 码不停息
这种方法是直接new 了一个父类的实例,然后赋给子类的原型。这样也就相当于直接将父类原型中的方法属性以及挂在this上的各种方法属性全赋给了子类的原型,简单粗暴!
因为简单粗暴,所以弊端很多
- new实例的时候不能给父类传参数
如上个例子所示,Sun 函数里面什么都没有,我们new的时候还怎么传参数,即使Sun函数体里面有值,他也不能和Per函数建立联系
- 自己的prototype被占用
为了继承父类的实例直接赋值给了Sun.prototype,那Sun还怎么用自己的prototype
# 调用构造函数方式
function Per(name){
this.name = name || '码不停息';
}
Per.prototype.say = function(){
console.log(this.name)
}
function Sun(){
Per.apply(this.arguments)
}
const sun = new Sun();
console.log(sun.name) // 码不停息
sun.say() // sun.say is not a function
在子类的在构造函数里用子类实例的this去调用父类的构造函数(改变this指向),从而达到继承父类属性的效果
但是这种方法却不能继承父类的prototype,所有sun调用不到say方法
# 组合继承
上面两种方法各有缺点,那能不能互补一下呢?
function Per(name){
this.name = name || '码不停息';
}
Per.prototype.say = function(){
console.log(this.name)
}
function Sun(){
Per.apply(this.arguments)
}
Sun.prototype = new Per();
const sun = new Sun();
console.log(sun.name) // 码不停息
sun.say(); // 码不停息
看似很完美,父类的属性和方法都可以访问到,还可以给父类传递参数

这是什么情况? name即出现了sun里面也出现了sun的__proto__里面。
看来组合方式把两种方式都有的也叠加了一切,实在是太不优雅
# 寄生组合继承
这是目前es5中主流的继承方式
function Per(name){
this.name = name || '码不停息';
}
Per.prototype.say = function(){
console.log(this.name)
}
function Sun(){
Per.apply(this.arguments)
}
Sun.prototype = Object.create(Pre.prototype);
const sun = new Sun();
console.log(sun.name) // 码不停息
sun.say(); // 码不停息
这里用到了Object.creat(obj)方法,该方法会对传入的obj对象进行浅拷贝。和上面组合继承的主要区别就是:将父类的原型复制给了子类原型。这种做法很清晰
但是也有一点小小弊端就是Per和Sun的constructor都指向了Pre,大部分情况下使用这种继承方式没问题,但是如果要使用constructor的话, 我们要加上这样一句话
Sun.prototype.constructor = Sun
可以说,ES6之前实现继承确实不是一件容易的事,特别和强类型语言对比来说,Javascript实现继承只能用'另类'来说
但是现在,我们可以说Javascript站起啦!
# ES6实现继承
class Per{
constructor(name){
this.name = name || '码不停息';
}
say(){
console.log(this.name)
}
}
class Sun extends Per {
constructor(name){
super(name);
this.age = 16;
}
}
const sun = new Sun('lyh');
console.log(sun) //{name: "lyh" , age: 16}
只能用两个字来形容 优雅