Javascript实现面向对象继承方式个人小结

最近重新看了下Javascript的OO编程,这里总结主流的几种方式:

第一种 构造函数绑定

function Person() {
    this.species = "人类";
}
function Asian(name, age) {
    Person.apply(this, arguments);
    this.name = name;
    this.age = age;
}
var anAsian = new Asian("亚洲人", 23);

第二种 prototype模式

function Person() {
    this.species = "人类";
}
function Asian(name, age) {
    this.name = name;
    this.age = age;
}
// prototype模式的好处就是所有的实例继承的属性都指向一个地址,节省了内存 
Asian.prototype = new Person(); 
// 注意这里是为了保持好的编码习惯,还是让实例对象的constructor指向自己的构造函数 
// 很多时候为了将实例的构造器的原型对象暴露出来,比如你写了一个插件,别人得到的都是你实例化的对象,如果别人想扩展下对象,就可以用instance.constructor.prototype去修改或扩展原型对象
Asian.prototype.constructor = Asian;

第三种 直接继承prototype

// 先将Person对象改写 
function Person() {
}
Person.prototype.species = "人类";
// 利用空对象做为中介,不能直接让Asian构造函数的prototype等于Person构造函数的prototype,不然修改Asian的prototype也会修改Person构造函数的prototype 
var F = function () {
};
F.prototype = Person.prototype;
Asian.prototype = new F();
Asian.prototype.constructor = Asian;
// 可以将上面的方法封装成一个函数 
function extend(Child, Parent) {
    var F = function () {
    };
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    // 可以直接调用父对象的方法 
    Child.uber = parent.prototype;
}

第四种 非构造函数的继承(将子对象的prototype指向父对象)

var Person = {species: '人类'}
/* var Asian = { name:'亚洲人' } */
function object(o) {
    function F() {
    }

    F.prototype = o;
    return new F();
}
var Asian = object(Person);
Asian.name = '亚洲人';

第五种 非构造函数的继承(深复制)

var Person = {species: '人类'}
/* * var Asian = { name:'亚洲人' } */
var Asian = deepCopy(Person);
Asian.name = '亚洲人';
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;
}

参考:

Javascript 面向对象编程(一):封装

Javascript面向对象编程(二):构造函数的继承

Javascript面向对象编程(三):非构造函数的继承

Show Comments