学习了解js的继承

40 阅读3分钟

前言

在日常的代码开发中,我们免不了需要造轮子,对于一些常用的方法我们就希望能够复用起来。从而避免繁重的体力劳动。
今天简单聊一聊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中的几种继承方法,才疏学浅,表意不清还请见谅。