前言
在日常的代码开发中,我们免不了需要造轮子,对于一些常用的方法我们就希望能够复用起来。从而避免繁重的体力劳动。
今天简单聊一聊js的继承
首先我们顶一个约定的构造类,通过这个类来讲述几大继承方法
function Super(){
this.name = 'aa'
}
Super.prototype.getName = function () {
console.log(this.name)
}
Call继承
Call继承只会继承私有的属性,实例化的时候需要调用父类的构造函数
function Sub(){
Super.call(this)
}
let sub = new Sub()
console.log(sub.name)
原型继承
原型继承通过让子类的原型指向另一个类的实例,就会获得实例的私有属性,通过实例的__proto__找到上一层的原型。
function Sub(){}
Sub.prototype = new Super()
let sub = new Sub()
console.log(sub.name)
sub.__proto__.name='bb'
sub.getName()
console.log(Sub.prototype)
let sub1 = new Sub()
console.log(sub1.name)
console.log(sub1.__proto__)
如上,let sub = new Sub(); sub有了Super的私有和原型上的属性和方法。
核心思想: 通过增加sub子类和super父类之间的原型链接,让Sub的实例可以找到Super的原型和私有属性。后续在Super的原型上添加的属性和方法,sub也可以找到。
对象冒充继承
function Sub(){
let super1 = new Super
for (let key in super1) {
this[key] = super1[key]
}
super1 = null
}
let sub = new Sub()
console.log(sub.name)
sub.getName()
在实例化的时候,把父类的私有和共有的属性都遍历获取到,然后添加到子类的私有属性上,两者之间没有原型链的联系
组合继承
call继承只继承了私有的。缺少公有的,那我们就可以通过call+原型继承来实现公有属性的继承。这样做的好处是:私有的还在实例的私有属性上,每一个实例都有自己的。通过原型链也可以找到公有的属性。但缺点就是:原型上多了一份私有的属性。构造函数也执行了两次。
中间继承
function Sub(){}
Sub.prototype.__proto__ = Super.prototype
let sub = new Sub()
console.log(sub.getName)
中间继承是一种在父类和子类之间加了一层原型链的方式。但只是继承原型上的方法。
寄生组合
寄生组合综合了前面集中的继承方法,我们想实现那种 私有的属性是私有的,公有的就在原型上。只能用 组合式的继承来实现。把共享的属性、方法用原型链继承实现,独享的属性、方法用借用构造函数实现,所以组合继承几乎完美实现了js的继承.但是一个bug就是 原型上多了 私有的属性。而且让超类构造函数执行两次。
现在的ECMAscript提供了一个 方法, Object.create(proto,[propertiesObject])
返回一个对象。该对象的原型 指向 Super.prototype
function Sub() {}
Sub.prototype = Object.create(Super.prototype);
console.log(Sub.prototype);
这样子类就继承了超类 公有的方法
但是ES5 兼容性 我们需要自己写一个 Objectcreate方法
function objectCreate(o) {
function Temp() {}
Temp.prototype = o;
return new Temp();
}
function Sub() {}
Sub.prototype = objectCreate(Super.prototype);
var sub = new Sub;
console.log(sub.getName)
以上就是js中的几种继承方法,才疏学浅,表意不清还请见谅。