JS继承机制

 1. 对象冒充

    a. 直接实现 例:
function ClassA(sColor) ...{
    this.color = sColor;
    this.sayColor = function () ...{
        alert(this.color);
    };
}

function ClassB(sColor, sName) ...{
    this.newMethod = ClassA;
    this.newMethod(sColor);
    delete this.newMethod;
  
    this.name = sName;
    this.sayName = function () ...{
        alert(this.name);
    };   
}

var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();

所有的新属性和新方法都必须在删除了新方法的代码行后定义,否则可能会覆盖超类的相关属性和方法

b. 用Call()方法实现
function ClassA(sColor) ...{
    this.color = sColor;
    this.sayColor = function () ...{
        alert(this.color);
    };
}

function ClassB(sColor, sName) ...{
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.call(this, sColor);

    this.name = sName;
    this.sayName = function () ...{
        alert(this.name);
    };
}

var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();

c. 用Apply()方法实现
function ClassA(sColor) ...{
    this.color = sColor;
    this.sayColor = function () ...{
        alert(this.color);
    };
}

function ClassB(sColor, sName) ...{
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.apply(this, arguments);

    this.name = sName;
    this.sayName = function () ...{
        alert(this.name);
    };
}

var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();

call()有点类似于java中的反射机制,b.call(a,c)用汉语描述可以这样理解:对象a调用b方法,c是b方法的参数。apply类似,不过apply第二个参数是一个数组。

2. 原型链
第二种继承方式是原型方式,所谓原型方式的继承,是指利用了prototype或者说以某种方式覆盖了prototype,从而达到属性方法复制的目的。例
function ClassA() ...{
}

ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function () ...{
    alert(this.color);
};

function ClassB() ...{
}

ClassB.prototype = new ClassA();

ClassB.prototype.name = "";
ClassB.prototype.sayName = function () ...{
    alert(this.name);
};

var objA = new ClassA();
var objB = new ClassB();
objA.color = "red";
objB.color = "blue";
objB.name = "Nicholas";
objA.sayColor();
objB.sayColor();
objB.sayName();

子类的所有属性和方法都必须出现在prototype属性被赋值后,因为在它之前赋值的所有方法都会被删除,因为prototype属性被替换成了新对象,添加了新方法的原始对象将删除。原型链不支持多重继承。记住,原型链会用另一类型的对象重写类的prototype属性。

上面两种方法的缺点:

对象冒充的缺点是:构造对象时必须使用构造函数方式,构造函数方式的缺点是:为所有的对象的所有属性和方法都建立一个副本,为对象的属性建立副本是没问题的,但为所有的方法也建立副本就没必要,这样会浪费内存,一个类的所有对象共享一个 方法的副本就行了。

原型链的缺点是:建立对象是必须使用无参的构造函数,不能使用带参的构造函数。因为对子类prototype域的修改是在声明子类对象之后才能进行,用子类构造函数的参数去初始化父类属性是无法实现的。

3. 混合方式

混合方式类似于前面文章javascript对象类型的混合方式,用对象冒充继承构造函数的属性,用原型链继承prototype对象的方法。例
function ClassA(sColor) ...{
    this.color = sColor;
}

ClassA.prototype.sayColor = function () ...{
    alert(this.color);
};

function ClassB(sColor, sName) ...{
    ClassA.call(this, sColor);
    this.name = sName;
}

ClassB.prototype = new ClassA();

ClassB.prototype.sayName = function () ...{
    alert(this.name);
};


var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值