构造函数的继承方式

主要分为两部分,第一部分是ES5环境下的继承,另一部分是ES6部分的继承,首先先看ES5,如何经过构造函数的形式实现继承。

1:原型链继承
function Foo(name) { this.name = name; } Foo.prototype.age = function() { console.log('父类:' + this.name); }; function fn (name) { this.name = name; } fn.prototype = new fn(); fn.prototype.age = function() { console.log('子类:' + this.name); }; var a = new fn('lisi'); a.age();

这种方法缺点比较明显,看起来很不直观,并且子类的方法不能优先于父类方法出现,经过new调用时,不能直接调用父类的构造函数而是要调用子类。函数


2:类式继承
function Foo(name) { this.name = name; } Foo.prototype.age = function() { console.log('父类:' + this.name); }; Foo.prototype.obj = function() { console.log('hello world'); }; function fn (name) { Foo.call(this,name); } fn.prototype.age = function() { console.log('子类:' + this.name); }; var a = new fn('lisi'); a.age(); a.obj(); //TypeError: a.obj is not a function
这里经过call的方法,将this绑定在Foo构造函数上运行,可是会致使没有本身的原型对象,没法共享原型的方法和属性。

3:组合式继承
function Foo(name) { this.name = name; } Foo.prototype.age = function() { console.log('父类:' + this.name); }; Foo.prototype.obj = function() { console.log('hello world'); }; function fn (name) { Foo.call(this,name);    //第二次调用
} fn.prototype = new Foo();   //第一次调用
fn.prototype.constructor = fn; fn.prototype.age = function() { console.log('子类:' + this.name); }; fn.prototype.set = function() { console.log('set si es5'); }; var a = new fn('lisi'); a.age(); a.obj(); a.set();

这是比较经常使用的继承方法,经过调用两次实现了继承,具有了原型链继承和类式继承的优势也能够本身定制方法或者属性。
不过缺点就是第一次调用Foo函数,实际上咱们只是想获取原型,你可能在想若是经过
fn.prototype = Foo.prototype;
的方法实现,不过很惋惜,这种方法是错误的,由于这会致使,两个函数的prototype属性发生改变,这显然是没有必要的。
这也是第四种继承的由来。
4:寄生组合式继承
function Foo(name) { this.name = name; } Foo.prototype.age = function() { console.log('父类:' + this.name); }; Foo.prototype.obj = function() { console.log('hello world'); }; function fn (name) { Foo.call(this,name); } fn.prototype = Object.create(Foo.prototype); fn.prototype.constructor = fn; fn.prototype.age = function() { console.log('子类:' + this.name); }; fn.prototype.set = function() { console.log('set si es5'); }; var a = new fn('lisi'); a.age(); a.obj(); a.set();
这里使用了Object.create()方法,事实上你也能够经过这种方法本身模拟一个,使用这种方法继承,能够让Foo这个函数只执行一次。
function Create(arr) { function foo() {} foo.prototype = arr; return new foo(); }
 
 
5:多重继承(混合继承)
    function foo(name) { this.name = name; } function fn(arr) { this.age = arr; } function obj(name, age) { foo.call(this, name); fn.call(this, age); } obj.prototype = Object.create(foo.prototype); Object.assign(obj.prototype, fn.prototype); obj.prototype.constructor = obj; var a = new obj('zhangsan', 18); console.log(a); //obj {name: "zhangsan", age: 18}


class继承

class是ES6新增的,继承经过extends实现
class Foo {
    constructor(name) {
        this.name = name;
    }
    age() {
        console.log(this.name);
    }
    obj() {
        console.log('hello world');
    }
}
class fn extends Foo {
    constructor(name) {
        super(name);
    }
    age() {
        console.log(`子类调用${this.name}`);
    }
}
var a = new fn('zhangsan');
a.age();
a.obj();
 
 
参考文章:
30分钟学会js继承
相关文章
相关标签/搜索