前言
js中的继承有很多种方式,后面的方案的提出也是为了弥补前面方案的缺点,这篇文章对其做一个总结。
正文
1. 原型链继承
原型链继承的例子如下:
//原型链继承
Parent.prototype.say = function () {
console.log('hello');
}
function Parent() {
this.name = 'Jerry'
}
Son.prototype = new Parent()
function Son() {
this.age=18
}
let s1 = new Son()
console.log(s1.name); //Jerry
console.log(s1.say()); //hello
我们可以看到打印,说明子类能继承到父类的所有属性和方法
如果我要实现子类给父类传参呢?我们更改下代码:
Parent.prototype.say = function () {
console.log('hello');
}
function Parent(name) {
this.name = name
}
Son.prototype = new Parent()
function Son() {
this.age=18
}
let s1 = new Son('Jerry')
console.log(s1.name); //undefined
发现打印出来却是undefined,这说明子类是无法给父类传参的,这就引出了经典继承的方案了。
2. 经典继承
经典继承利用了call来将parent的this指向son,且将name这个参数传给parent,让子类继承到父类实例属性
//经典继承
Parent.prototype.say = function () {
console.log('hello');
}
function Parent(name) {
this.name = name
}
function Son(name) {
Parent.call(this,name) //this.name = name
this.age=18
}
let s1= new Son('Jerry')
console.log(s1.name); //Jerry
console.log(s1.say()); //TypeError: s1.say is not a function
可以看到经典继承弥补了原型链继承中子类不能给父类传参的缺点,但是子类只能继承到父类实例上的属性,无法继承到父类原型上的属性。
3. 组合继承
组合继承可以说是前两种方案的结合,这样就可以使子类继承到父类实例上的属性和父类原型上的属性,且子类能给父类传参。
//组合继承
Parent.prototype.say = function () {
console.log('hello');
}
function Parent(name) {
this.name = name
}
Son.prototype = Object.create(Parent.prototype) //继承到父类原型
function Son(name) {
Parent.call(this, name) //继承到父类实例属性
this.age = 18
}
let s1 = new Son('Jerry')
console.log(s1.name); //Jerry
console.log(s1.say()); //hello
但是,这个方案还是有些缺陷,我们放到浏览器运行并输出s1,发现s1的原型居然是parent?不应该是son吗?这就是这种方案的问题所在了。
4. 寄生组合继承
为了解决组合继承的问题所在,我们直接修改子类的原型就解决了:
Parent.prototype.say = function () {
console.log('hello');
}
function Parent(name) {
this.name = name
}
let proto= Object.create(Parent.prototype) //继承到父类原型
proto.constructor =Son //往proto对象上挂属性
Son.prototype=Object.assign(proto,Son.prototype) //将子类的原型与父类的原型合并
function Son(name) {
Parent.call(this, name) //this.name = name 继承到父类实例属性
this.age = 18
}
let s1 = new Son('Jerry')
console.log(s1.name); //Jerry
console.log(s1.say()); //hello
5. 类继承(ES6)
类中的继承只需用extends就能实现继承,实现方式更为优雅
class Parent {
constructor (value) {
this.val = value
}
getValue() {
console.log(this.val);
}
}
class Child extends Parent {
constructor (value) {
super(value)
//super(); this.val = value
}
}
let c = new Child(1)
c.getValue()
// console.log(c);
结
给继承做一个简单的小总结了
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END