JavaScript 中的面向对象编程(二)

继上篇《JavaScript 中的面向对象编程》,JS中的继承,单独使用原型链存在的问题是:对象实例会共享所有继承的属性和方法(包括实例属性)。因此,为解决这些问题,继承存在多种模式。

1. 借用构造函数

在子类构造函数的内部调用父类构造函数,使每个实例具有自己的属性。具体:使用call或apply方法,将父对象的构造函数绑定到子对象上,见示例

2. 组合继承

使用最多的继承模式就是组合继承,使用原型链继承共享的属性和方法,通过借用构造函数继承实例属性。

function Supertype(name){
    this.name = name;  //实例属性
    this.colors = ["red","green","blue"];  //实例属性
}
Supertype.prototype.sayName = function(){  //原型方法
    return this.name;
}
function Subtype(name, age){
    Supertype.call(this, name); //继承实例属性
    this.age  = age;  //新属性
}
Subtype.prototype.sayAge = function(){
    return this.age;
}
Subtype.prototype = new Supertype();//Subtype继承了Supertype,此时Subtype.prototype对象的constructor指向Supertype
Subtype.prototype.constructor = Subtype;//将Subtype.prototype对象的constructor指向Subtype
var instance  = new Subtype("hxj",20);
alert(instance.colors);     //"red","green","blue"
alert(instance.sayName());  //"hxj"
alert(instance.sayAge());   //20
3. 原型式继承( 非构造函数的继承

不定义构造函数,利用object()函数,对传入的对象执行浅拷贝。

function object(o){
    function F(){}   //利用空对象作为中介
    F.prototype = o; //将传入的对象作为空对象的原型
    return new F();  //返回空对象的新实例
}

使用示例:

var person = {
    name: "hxj",
    friends:["wyr","lzh"]
}
var newperson = object(person); //调用
newperson.name = "lyy";        //重新赋值
newperson.friends.push("hhh"); //重新赋值

4. 寄生式继承

类似于原型式继承,创建一个仅用于封装继承过程的函数。在函数内部,基于传入的对象创建新的对象,再增强对象(添加新属性和方法),最后返回对象。

5. 寄生组合式继承(最有效方式)

前面组合继承的缺点:会调用两次父类构造函数。

第一次: Subtype.prototype = new Supertype(); 

第二次: var instance = new subtype("hxj", 20);     =>     Supertype.call(this, name);

为解决此问题,使用寄生组合式继承:使用原型链的混成形式继承共享的属性和方法,通过借用构造函数继承实例属性。

本质是:不用为指定子类的原型而调用父类的构造函数,只需要父类原型的一个副本。

function inherit(subtype, Supertype){
    var o = object(Supertype.prototype); //创建父类的一个副本
    o.constructor = subtype;  //重新设置construct属性
    subtype.prototype = o;    //将副本赋值给子类的原型
}

换一种写法(不使用object()函数,合并为一个extend()函数):

    function extend(subtype, Supertype) {
        var F = function () { };
        F.prototype = Supertype.prototype;
        subtype.prototype = new F();
        subtype.prototype.constructor = subtype;
    }

使用示例:

function Supertype(name){
    this.name = name;  //实例属性
    this.colors = ["red","green","blue"];  //实例属性
}
Supertype.prototype.sayName = function(){  //原型方法
    return this.name;
}
function Subtype(name, age){
    Supertype.call(this, name); //继承实例属性
    this.age  = age;  //新属性
}
Subtype.prototype.sayAge = function(){
    return this.age;
}
inherit(subtype, Supertype); //调用
var instance  = new Subtype("hxj",20);
alert(instance.colors);     //"red","green","blue"
alert(instance.sayName());  //"hxj"
alert(instance.sayAge());   //20





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值