JAVASCRIPT编入集

九、理不清的继承(续)

2018-01-02  本文已影响23人  loster
javascript编入集
新年第一篇,再来闲谈继承。
上一次说了几个属性,继承主要用的还是原型。在形式上,有多种实现,但是在实际上会有各种差异。
有些看起来是像继承的,只是通过一种捷径实现了继承的方式,但是那并不是继承,所以在这里只列取在原型上拓展即可以食用的原型继承。
检验一个是否是真的继承,首先判断一下是否可以在原型上拓展,也就是new 对象之后,是不是在父类原型上的改变直接影响到子类上的原型内容,如果不满足这一点,就不属于继承范畴。使用 instanceof 比较
首先建立父类
function Parent(name){
    this.name = name;
    this.give = function(){  console.log(this.name + ' give')}
}
Parent.prototype.handup = function(){
    console.log(this.name + 'hand up ');
}

建立好了父类。如何实现子类的继承关系。

1. 常规原型继承

使用prototype继承

function Child(name){
    this.name = name;
}
Child.prototype = new Parent('Joy');
Child.prototype.constructor = Child; // 修正prototype的指向
var child = new Child('Tom');

这样继承来的对象上

child instanceof Parent ; // true

通过对原型链的改变,实现继承。
这种继承方式的好处就是单纯的继承。写起来类似接口一样,只有共有内容,没有私有属性。因为,所有的内容都是通过prototype取值,这一种继承总体来说算是最常规继承。
这种继承的几点缺陷

  1. 单继承
  2. 无法直接调用父类的构造函数。

在js中继承使用其实是非常少的,并且对于多继承来说就更少了,可以说忽略不计。
我看到还有一种寄生组合,说是因为调用了两遍父类构造函数。

function Parent(name){
    this.name = name;
    this.give = function(){  console.log(this.name + ' give')  }
}
function Child(name){
    Parent.call(this);
    this.name = name;
}
(function(){
    var supers = function(){}
    supers.prototype = Parent.prototype;
    Child.prototype = new supers;
})();

首先,父类自身的属性和函数,属于私有范畴,并不需要继承,这里用call破坏了原有的属性值。
其次,使用自执行函数,将父类的prototype转嫁到新的对象上去,减少了一次父类的调用,但是实际上并没有减少两次new的过程,并且原型上的new只有一次,所以说调用父类两次的并不成立。
因此:不建议这种方式。因为它属于画蛇添足的方式。

Child.prototype.constructor这句话是重新修整constructor的指向。不修正时constructor指向的是原型类也就是Parent。但是如果new child.constructor() 重新 new一个该对象时,需要正确指向它的构造函数。

2. 其他继承实现方式

很抱歉,暂时没找着

上一篇下一篇

猜你喜欢

热点阅读