javascript继承总结

912 阅读2分钟

前置

  • 所有的对象都是__proto__属性,指向其构造函数的原型对象
  • 所有的函数对象都有prototype属性表示原型对象,作用:共享实例对象的属性和方法.

构造函数绑定

Parent.apply(this,arguments)    // this是子类实例,调用父类,即可拿到其属性和方法

prototype模式

Child.prototype = new Parent() // 子类的原型对象是父类的实例
Child.prototype.constructor = Child // 原型对象都有constructor属性,修改prototype指向后一定要修正构造函数

直接继承prototype

Child.prototype = Parent.prototype // 子类原型对象指向父类原型对象,减少调用次数
Child.prototype.constructor = Child
  • 优点:效率高,省内存,不需要建立父类的实例
  • 缺点:父类和子类的原型对象指向同一个值,修正constructor指向的代码同时修改了父类原型对象的构造函数指向

利用空对象作为中介

function extend(Child, Parent) {
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
}
  • F是空对象,几乎不占内存

拷贝继承

  • 把父对象的所有属性和方法拷贝到子对象中
function extend2(Child, Parent) {
    var p = Parent.prototype;
    var c = Child.prototype;
    for (var i in p) {
        c[i] = p[i];
    }
    c.uber = p;
}

object()函数

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

拷贝

function deepCopy(p, c) {
    var c = c || {};
    for (var i in p) {
        if (typeof p[i] === 'object') {
            c[i] = (p[i].constructor === Array) ? [] : {};
            deepCopy(p[i], c[i]);
        } else {
            c[i] = p[i];
          }
    }
    return c;
}

ES5继承:先创造子类的实例对象this,然后再将父类的方法添加到this上面

ES6

  • class+extend+constructor+super

先创建父类实例this 通过class丶extends丶super关键字定义子类,并改变this指向,super本身是指向父类的构造函数但做函数调用后返回的是子类的实例,实际上做了父类.prototype.constructor.call(this),做对象调用时指向父类.prototype,从而实现继承。

参考链接:
Javascript面向对象编程(二):构造函数的继承
Javascript面向对象编程(三):非构造函数的继承
ES5和ES6及继承机制