原文地址:http://www.excelib.com/article/243/show
概述
继承是Java、c++等基于类的语言中的一个术语,他的含义是子类的对象可以调用父类的属性和方法。而基于对象的ES语言其实是没有类的概念,当然也就不存在基于类的那种继承的方式了,不过他可以通过prototype属性来达到类似于继承的效果。
prototype是ES中function类型对象的一个特殊属性,每个function类型的对象都有prototype属性,prototype属性的值是object类型的对象。在FireBug中可以看到Object(Object本身是function类型对象)的prototype属性类型如下图1所示
图1
prototype属性简介
function对象中prototype属性对象的作用是这样的:在function对象创建出的object类型对象实例中可以直接调用function对象的prototype属性对象中的属性(包括方法属性),比如下面的例子
1 2 3 4 5 6 7 8 9 | function Car(color, displacement){ this .color = color; this .displacement = displacement; } Car.prototype.logMessage = function (){ console.log( this .color+ ", " + this .displacement); } var car = new Car( "black" , "2.4T" ); car.logMessage(); //black, 2.4T*/ |
这个例子中我们给Car的prototype属性对象添加了logMessage方法属性,这样使用Car创建出来的car对象就可以直接调用logMessage方法了。不过这里虽然可以使用car调用logMessage方法,但是car对象中本身并不会添加这个方法,只是可以调用而已。
prototype属性只可调用不可修改
function创建出来的实例对象在调用属性时会首先在自己的属性中查找,如果找不到就会到function的prototype属性对象中去查找,不过创建出来的对象只是可以调用prototype中的属性但是并不会实际拥有那些属性,而且也不可以对他们进行修改。当创建出来的实例对象定义了同名的属性后会覆盖prototype中的属性,但是prototype中的属性本身并不会发生变化,而且当创建出来的对象删除了添加的属性后原来prototype中的属性还可以调用,我们来看个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function Car(color, displacement){ this .color = color; this .displacement = displacement; } Car.prototype.logMessage = function (){ console.log( this .color+ "," + this .displacement); } var car = new Car( "black" , "2.4T" ); car.logMessage(); //black,2.4T car.logMessage = function () { console.log( this .color); } car.logMessage(); //black delete car.logMessage; car.logMessage(); //black,2.4T |
这里使用Car直接创建的car对象并没有logMessage属性方法,所以第一次调用logMessage方法会调用Car的prototype属性对象中的logMessage方法,接着我们给car定义了logMessage方法,这时再调用logMessage方法就会调用car自己的logMessage方法了,最后我们又删除了car的logMessage方法,这时再调用logMessage方法时又会调用了Car的prototype属性对象中的logMessage方法了,而且Car的prototype属性对象中的logMessage方法的内容也没有发生变化。代码执行后输出的结果如下
1 2 3 | black,2.4T black black,2.4T |
我们可以通过FireBug将整个过程看的更加清楚,在增加断点后可以看到下图2的结构
car对象添加logMessage方法前
car对象添加logMessage方法后
car对象删除logMessage方法后
图2
从图中可以看出Car的prototype属性并没有发生变化,而是在car对象自己的属性中先添加然后又删除了logMessage属性方法。