深入javascript function对象(二)
Javascript中的类
在 上一篇 中我们了解了 function 对象,下面我们来看看如何运用function对象实现面向对象。
1.
对象
什么是对象?
在js中,对象是一种复合数据类型,他们将多个数据值集中在一个单元中,而且允许使用名字来存取这些值。
怎么创建对象?
对象是由运算符new创建的。
在这个运算符之后必须有用于初始化对象的构造函数名。例如:
var o = new Object(); //创建一个空对象,即没有属性的对象。
js还支持内部构造函数,例如:
var now = new Date(); //当前日期和时间
通过对象直接量创建对象。
对象直接量提供了另一种创建并初始化新对象的方式。对象直接量由属性说明列表构成,列表包含在大括号中,其中属性说明由逗号隔开,对象直接量中的每个属性都是由属性名加上冒号和属性值构成。例如:
var circle = {x:0, y:0, radius:2};
var coder = {
name:”huchen”,
age:22,
sex:”mail”,
email:” vs2010.net@gmail.com”
};
变量的读取
这个相信就不用在啰嗦了吧,如:coder.name;
如果要读取一个不存在的属性(即还没有被赋值的属性)的值,那么得到的结果将是undefined。
删除属性:
delete coder.sex;
删除一个属性不仅仅是把该属性设置为undefined,而是真正从对象中移除该属性。
2.
构造函数
从上一篇中我们知道,在javascript中,使用new运算符以及预定义的构造函数(如Object(),Date()等)可以创建并初始化一个新对象。在许多实例中,这些预定义的构造函数和他们创建的内部对象类型都很有用。但是,在面向对象的程序设计中,使用由程序定义的自定义对象类型也是很普遍的。例如如果你想编写一个操作矩形的程序,那么可以用一个特殊类型或者对象类来表示矩形。这个矩形类的每个对象都有一个width属性和一个height属性,因为他们定义矩形的本质特征。
要创建已经定义了的带有属性的对象,需要编写一个构造 函数在新的对象中创建并初始化这些属性。构造函数是具有两个特性的javascript函数:
l
它由new运算符调用。
l
传递给他的是一个对新创建的空对象的引用,将该引用作为关键字this的值,而且它还要对新创建的对象进行适当的初始化。
例:
function Rectangle(w, h)
{
this.width = w;
this.height = h;
}
var rect1 = new
Rectangle(2,5);
var rect2 = new
Rectangle(3,7);
学过面向对象编程的都知道面向对象通过属性和方法描述现实世界中的类型。
那个有了属性,自然就应该有方法。
3.
方法
在javascript中,可以借助可以讲函数赋给任何变量这个特性。我们可以把函数赋给一个对象属性。如果有一个函数f和一个对象o,就可以适应如下代码定义一个名为m方法:
o.m = f;
定义了之后可以采用下面方式调用:
o.m();
方法有一个非常重要的属性,就是在方法主体内部,关键字this可以引用当前调用该方法的对象。那么有了这些概念我们来看个例子:
function compute_area()
{
return this.width * this.height;
}
var page = new
Rectangle(4, 5);
//通过吧函数赋予对象的属性,来定义一个方法。
page.area = compute_area;
//调用方法
var a = page.area();
在这个例子中有一个明显的缺点,就是在调用对象rect的方法area()之前,必须先将该方法赋给rect对象的一个属性,虽然可以调用名为page的特定对象的area()方法,但是在没有将该方法赋给其他的Rectangle对象之前,我们就不能调用任何Rectangle对象的area()方法。这很就会使你感到繁琐。
对此我们可以用这种方法解决:
例:
//首先定义一函数,它们将被用作方法。
function
Rectangle_area(){return this.width * this.height;}
function
Rectangle_perimeter(){return 2*this.width + 2*this.height;}
function Rectangle_set_size(w,h){this.width
= w; this.height = h;}
function Rectangle_enlarge(){this.widht
*= 2; this.height *= 2;}
function
Rectangle_shrink(){this.width /= 2; this.height /= 2;}
function Rectangle(w, h)
{
this.width = w;
this.height = h;
//在构造函数中定义对象方法
this.area = Rectangle_area;
this.perimeter = Rectangle_perimeter;
this.set_size = Rectangle_set_size;
this.enlarge = Rectangle_enlarge;
this.shrink = Rectangle_shrink;
}
var r = new Rectangle(2,
3);
//现在,一但创建了一个Rectangle对象,就可以直接调用它的方法了。
var a = r.area();
r.enlarge();
var p = r.perimeter();
虽然这种方法不用对每个实例化的对象属性赋予方法。但是还是有缺点,在这个例子中,构造函数Rectangle()对它所要初始化的Rectangle对象的7个属性都进行了设置,即使其中5项属性的值都是常量,每个矩形对象的这5项都是相同的。由于每个属性都占用了一定的内存空间,所以给Rectangle类添加方法,就会使每个Rectangle对象占用的内存为原来的3倍。幸运的是javascript引入了一种解决该问题的方法,即它允许一个对象继承原型对象的属性。