CSDN博客

img zhangboone

JavaScript程序设计——第4章 继承

发表于2008/10/1 12:00:00  181人阅读

分类: JavaScript

4.1 继承机制的实现

出于安全原因,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击。

 

4.1.1 继承的方式

1.对象冒充(Object masquerading

原理如下:构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可使ClassA的构造函数成为ClassB的方法,然后调用它。ClassB就会收到ClassA的构造函数中定义的属性和方法。例如:

function ClassA(Color) {

this.color = Color;

this.sayColor = function () {

alert(this.color);

};

}

function ClassB(Color) {

}

这个方法中,this指向的是所属的对象。这个原理把ClassA作为常规函数来建立继承机制,而不是作为构造函数。使用构造函数ClassB可实现继承机制:

function ClassB(Color) {

this.newMethod = ClassA;

this.newMethod(Color);

delete this.newMethod;

}

 

2.call()方法

该方法与经典的对象冒充方法最相似。它的第一个参数用作this的对象。其它参数都直接传递给函数自身。例如:

function sayColor(Prefix, Suffix) {

alert(Prefix + this.color + Suffix);

};

var obj = new Object();

obj.color = “red”;

//输出 “The color is red, a very nice color indeed. “

sayColor.call(obj, “The color is “, “, a very nice color indeed. “);

调用call()方法时,第一个参数是obj,说明应该赋予sayColor()函数中的this关键字值是obj。第二个和第三个参数是字符串。它们与sayColor()函数中的参数prefixsuffix匹配。

要与继承机制的对象冒充方法一起使用,只需将前三行的赋值、调用和删除代码替换即可:

function ClassB(Color, Name) {

//this.newMethod = ClassA;

//this.newMethod(Color);

//delete this.newMethod;

ClassA.call(this, Color);

}

   

3.apply()方法

该方法有两个参数,用作this的对象和要传递给函数的参数的数组。例如:

function sayColor(Prefix, Suffix) {

alert(Prefix + this.color + Suffix);

};

var obj = new Object();

obj.color = “red”;

//输出 “The color is red, a very nice color indeed. “

sayColor.apply(obj, new Array(“The color is “,”, a very nice color indeed.”));

调用apply()方法时,第一个参数仍是obj,说明应该赋予sayColor()中的this关键字值是obj。第二个参数是由两个字符串构成的数组,与prefixsuffix匹配。

同样的,该方法也可以与对象冒充方法一起使用。

 

4.原型链(Prototype chaining

利用了对象的prototype属性,可把它看成创建新对象所依赖的原型。先用空构造函数来设置类名,然后所有的属性和方法都被直接赋予prototype属性。

Prototype对象就是一个模板,要实例化的对象都以这个模板为基础,该对象的任何属性和方法都被传递给那个类的所有实例。原型链利用了这种功能来实现继承机制:

function ClassA() {

}

ClassA.prototype.color = red;

ClassA.prototype.sayColor = function () {

alert(this.color);

};

function ClassB() {

}

ClassB.prototype = new ClassA();

注意,调用ClassA的构造函数时,没有给它传递参数,这在原型链中是标准做法。要确保构造函数没有任何参数。

 

5.混合方式

对象冒充的问题是必须使用构造函数方式。如果使用原型链就无法使用带参数的构造函数。混合方式就是结合这两种方式。

用对象冒充继承构造函数的属性,用原型链继承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);

};

在此例中,继承机制由两行突出显示的代码实现。第一行代码中,在ClassB构造函数中,用对象冒充继承ClassAsColor属性。第二行代码中,用原型链继承ClassA类的方法。由于这种混合方式使用了原型链,所以instanceof运算符仍能使用。

 

4.2 小结

    介绍了ECMAScript中用对象冒充和原型链实现的继承概念,介绍了结合使用这些方式才是建立类之间继承机制的最好方式。

阅读全文
0 0

相关文章推荐

img
取 消
img