http://uefirst.com/bbs/simple/?t240.html
JavaScript中的原型
JavaScript中的原型(Prototype)是JavaScript最特别的地方之一。无论是实现JavaScript的面向对象还是继承,使用prototype都必不可少。
1 使用原型实现JavaScript的面向对象
“原型”表示对象的原始状态,JavaScript中的每个对象都有一个prototype属性,但是只有Function类型的prototype属性可以使用脚本直接操作。Object的prototype属于内部属性,无法直接操作。prototype属性本身是一个object类型。一个函数的prototype上所有定义的属性和方法,都会在其实例对象上存在。所以说prototype就是C#类中的实例方法和实例属性。实例方法和静态方法是不同的,静态方法是指不需要声明类的实例就可以使用的方法,实例方法是指必须要先使用"new"关键字声明一个类的实例, 然后才可以通过此实例访问的方法。
下面是两种方法的声明方式:
function staticClass() { }; //声明一个类 staticClass.staticMethod = function() { alert("static method") }; //创建一个静态方法 staticClass.prototype.instanceMethod = function() { "instance method" }; //创建一个实例方法
上面首先声明了一个类staticClass, 接着为其添加了一个静态方法staticMethod 和一个动态方法instanceMethod,区别就在于添加动态方法要使用prototype原型属性。
对于静态方法可以直接调用:
staticClass.staticMethod();
但是实例方法不能直接调用:
staticClass.instanceMethod(); //语句错误, 无法运行.
实例方法需要首先实例化后才能调用:
var instance = new staticClass();//首先实例化 instance.instanceMethod(); //在实例上可以调用实例方法
使用prototype除了可以声明实例方法,也可以声明实例属性。正因为原型有着如此强大的功能,所以能够使用原型来实现JavaScript的面向对象。目前存在着很多以面向对象的形式创建对象的方法,本书不一一详细讲解,只介绍一种最常用,最容易理解和使用的方法:动态原型方法。
假设要定义一个汽车Car类型, 具有属性color和方法showColor(),则可以使用下面的方式声明和使用:
function Car() { //声明属性 this.color = "none"; //声明方法 if (typeof Car._initialized == "undefined") { Car.prototype.showColor = function() { alert(this.color); } } Car._initialized = true; }; var car = new Car(); car.showColor(); //输出 输出为 "none" car.color = "blue"; car.showColor(); //输出 输出为 "blue"
动态原型方法的精髓在于使用prototype声明实例方法,使用this声明实例属性。除了更加接近面向对象的编程方式,这种方式特点就是简单易懂。注意充当“类定义”的function并没有带有任何参数,虽然也可以传递参数进去,但是不要这么做。这是为了下一节讲解的使用原型链实现继承机制而作的准备。
可以在创立了对象以后再为其属性赋值。虽然麻烦了一点,但是代码简单,易于理解。
2 使用原型链实现继承
除了面向对象的声明方式,在面向对象的世界中最常使用的就是对象继承。在JavaScript中可以通过prototype来实现对象的继承。继续上一节Car的例子。假设Car有两个派生类,一个是GoodCar,特点是跑得快。一个是BadCar,特点是跑得慢。但是它们和Car一样都具有color属性和showColor方法。
以GoodCar类为例,只要让GoodCar的prototype属性为Car类的一个实例,即可实现类型的继承:
GoodCar.prototype = new Car();
现在,GoodCar类已经有了Car的所有属性和方法:
var goodCar = new GoodCar(); goodCar.showColor(); //输出 "none"
实现了继承后,GoodCar还要实现自己的run()方法,同样使用prototype实现,下面是GoodCard类的完整定义:
//创建GoodCar类 function GoodCar() { } GoodCar.prototype = new Car(); GoodCar.prototype.run = function() { alert("run fast"); }
需要注意GoodCar类自身的方法一定要在实现继承语句之后定义。
为何称这种方式为原型链继承呢?因为GoodCar的prototype是Car,Car的prototype是object,也就是说GoodCar也具有object对象所有的属性和方法。这是一个“链”的结构。
使用原型可以简单快捷的实现JavaScript的面向对象和继承。