构造函数的继承方式


主要分为两部分,第一部分是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继承

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM