因为最近面试的原因,有的面试官会问到”实现继承的几种方式”,我便到网上查了这个问题的答案。我认为网上说的几种继承方式都有一定的问题,我想在这里说一下我的观点。

首先,我认为,继承是类的继承,不存在所谓的对象的继承。但是我好像记得在《javascript语言精粹》一书中dc大神提过所谓对象继承,但那本书毕竟是多年前的书了,那时候js还没有类的概念,书中可能是说的原型链的关系,而且翻译也有可能有问题。总之我认为说对象的继承是不正确的,可以说对象的“扩展”,或者把对象作为原型链构造新的对象。

类的继承只有一种实现方法,那就是ES6的extend。ES5中也可以实现这中继承,省去细节,最关键的就是两句:(可以参考我以前的博客:babel类的继承实现分析

SubClass=function(...args){
// 继承原型链
SubClass.prototype=Object.create(superClass.prototype,{constructior:{value:subClass}});
// 执行构造函数
SubperClass.call(this,...args);
};

分析网上的几种错误继承

1.原型链继承

function SuperClass(){}
function SubClass(){}
SubClass.prototype=new SuperClass();

看似实现了继承,但是,问题:
* 父类中this上添加的属性方法一股脑给搞到了原型上。
* 原型上的constructor属性没了。
* 父类中对this的操作可能不能完全反映在子类this上。

2.借用构造函数继承

function SuperClass(){}
function SubClass(){
    SuperClass.call(this)
}

原型链呢?

3.组合继承

function SuperClass(){}
function SubClass(){
    SuperClass.call(this)
}
// ???
SubClass.prototype=new SuperClass();
SubClass.prototype.constructor=SubClass;

这个把前两种结合了起来,但是还是不对。只是把第一种方式原型上的constructor属性问题解决了,但是其他问题还是存在。关键在于SuperClass不应该在创建SubClass时调用new,而是只在SubClass实例化时调用new,而上面的代码它调用了两遍。

4.原型式继承

这里就开始所谓对象继承了

function object(o){
 function F(){}
 F.prototype = o;
 return new F();
}

你直接使用Object.create不好吗?黑人问号脸:)

5.寄生式继承

function createAnother(original) {
    var clone = object(original);
    clone.sayHi = function() {
        alert("hi");
    };
    return clone;
}

在第四种上又新写了一个方法。。。。。。

6.寄生组合式继承

function object(o) {
    function F(){}
    F.prototype = o;
    return new F();
}

function inheritPrototype(superClass, subClass) {
    var prototype = object(superClass.prototype);
    prototype.constructor = subClass;
    subClass.prototype = prototype;
}

function SuperClass(name) {}
function SubClass(name, age) {
    SuperClass.call(this, name);
}

inheritPrototype(SuperClass, SubClass);

这个终于好像没什么毛病了。但是还是没有什么必要多写一个object函数。

分类: javascript

1 条评论

Oxefmw · 2021年1月14日 上午3:51

us cialis sales http://erectileprop.com/ ed solutions Gbncpn dpmlvl

Oxefmw进行回复 取消回复

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据