深入javascript function对象(三)
原型对象和继承
上一篇中我们已经知道,用构造函数把方法赋予他要初始化的对象,效率非常的低。如果我们这么做,那么构造函数创建的每一个对象都会有相同的方法属性的副本。有一种更有效的方式可以用来声明方法。
一、
原型对象
javascript对象都“继承”原型对象的属性。一个对象的原型是由创建并初始化该对象构造函数定义的。javascript中的所有函数都有prototype属性。它引用一个对象。虽然原型对象初始化时是空的。但是你在其中定义的任何属性都会被该构造函数创建的所有对象继承。
注意:继承是在查询一个属性值时自动发生的。理解这点很重要。属性并非从原型对象直接复制到新的对象的。他们只不过看起来像是那些对象的属性。这其中有两点重要的含义。
1. 使用原型对象可以大量减少每个对象对内存的需求量。因为对象可以继承许多的属性。
2. 即使属性在对象被创建之后才添加到它的原型对象中,对象也能继承这些属性。
继承是在查询一个属性值时自动发生的,如何理解这句话呢。例如:在读对象o的属性p时,javascript首先检查o是否具有一个名为p的属性。如果o没有这个属性,javascript就会再检查o的原型对象是否具有这个属性,这才使得以原型为基础的继承机制起作用。
因为原型对象的属性被一个类的所有对象共享,所以通常只用他们来定义类中所有对象的相同属性。这使得原型对象非常适用于方法的定义。另外原型对象还适用于那些具有常量值的属性定义。
二、
面向对象
这样我们根据前几篇内容来总结一下javascript中模拟的面向对象的一些概念。
1. 属性:通过在构造函数中用this.XXXX=XX 初始化的对象属性。
2. 方法:方法和属性其实非常相似,只不过他们是方法,而不是属性(在高级语言中,如java和c#,函数和方法并不想javascript中那样是数据,所以这一区别就更加明显了),每个实例共享原型对象中定义的方法。通过方法中的this,引用各自不同的要操作他们的对象。
3. 静态属性:众所周知,在面向对象中,静态属性是类的属性,而在 javascript中,通过创建构造函数的属性属性来模拟,如:Circle.PI = 3.14 。 因为在javascript中函数是对象,所以我们可以创建函数的属性,就像创建对象的属性一样。
4. 静态方法:像模拟静态函数一样,创建一个合适的函数作为构造函数的属性既可。
下面给出一例:
function Circle(radius)
{
//定义属性
this.r = radius;
}
//定义静态属性
Circle.PI = 3.14;
function Circle_area()
{
return Circle.PI * this.r * this.r;
}
//定义方法
Circle.prototype.area =
Circle_area;
function Circle_max(a, b)
{
if(a.r > b.r) return a;
else return b;
}
//定义静态方法
Circle.max = Circle_max;
//test Circle class
var c = new Circle(1.0);
c.r = 2.2;
var a = c.area();
var x =
Math.exp(Circle.PI);
var d = new Circle(1.2);
var bigger =
Circle.max(c, d);