JavaScript的继承机制
JavaScript 不包含传统的类继承模型,而是使用 prototype 原型模型,虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大。实现传统的类继承模型是很简单,但是实现 JavaScript 中的原型继承则要困难的多。由于 JavaScript 是唯一一个被广泛使用的基于原型继承的语言,所以理解两种继承模式的差异是需要一定时间的,今天我们就来了解一下原型和原型链。
一个关于继承和实例化的例子
function Shape(){
this.x = 0;
this.y = 0;
}
Shape.prototype.area = function(){
...
}
function Circle(){
this.radius = 1;
}
Circle.prototype = new Shape();
Circle.prototype.area = function(){
...
}
Circle.prototype.constructor = Circle;
var cir = new Circle();
我的理解
JavaScript用function模拟class,一个function对象会自带prototype属性,这个属性是JS实现面向对象的关键。
Circle是Shape的子类,是通过在Circle的prototype中放置一个Shape的实例来实现功能传递的。
通过new来创建实例,实例是object类型,无prototype属性。Circle的所有实例都会共享同一份prototype,该prototype中包含Shape的一个实例,一处更改,处处更改。
注意将Circle的构造器指回Circle。
原型链 如果按目录的形式来展开原型链,如下,cir作为主目录包含下面所有的内容。
~cir
~~radius
~~Circle.prototype(new Shape() & area)
~~~{x y area}
~~~Shape.prototype
~~~~area
~~~~Object.prototype
~~~~~{toString ...}
属性查找
当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止,到查找到达原型链的顶部,也就是 Object.prototype,但是仍然没有找到指定的属性,就会返回 undefined。属性在查找的时候是先查找自身的属性,如果没有再查找原型,再没有,再往上走,一直插到Object的原型上,所以在某种层面上说,用 for in语句遍历属性的时候,效率也是个问题。
hasOwnProperty
hasOwnProperty是Object.prototype的一个方法,他能判断一个对象的某个属性是否是自有属性,而且hasOwnProperty是JavaScript中唯一一个在处理属性时不查找原型链的函数。
但是hasOwnProperty可能会被轻易的覆盖,所以有时为了保险起见,要用Object的该方法,当然如果Object的方法也被更改就没办法了。