经过几天的学习,今天特意整理了JavaScript的面向对象的编程实现,也是一个基本问题:怎样建立对象?
其实写过Js代码的人,也已经涉及到对象的建立了,我们使用的其实是一种被称为JavaScript Object Notation(缩写 JSON)的形式,翻译为中文就是“JavaScript对象表示法"。
JSON为创建对象提供了非常简便的方法。例如,
1).创建一个没有任何属性的对象:

1
var person = {
2
name: "Angel",
3
age: 18,
4
married: false
5
};
3) . 创建一个对象并设置属性和方法:
2

3

4

5

1
var speaker =
2
{
3
text: "Hello World",
4
say: function()
5
{
6
alert(this.text);
7
}
8
};

2

3

4

5

6

7

8

4).创建一个更复杂的对象,嵌套其他对象和对象数组等:
1
var company =
2
{
3
name: "Microsoft",
4
5
product: "softwares",
6
7
chairman: {name: "Bill Gates", age: 53, Married: true},
8
9
employees: [{name: "Angel", age: 26, Married: false}, {name: "Hanson", age: 32, Marred: true}],
10
11
readme: function() {document.write(this.name + " product " + this.product);}
12
};

2

3

4

5

6

7

8

9

10

11

12

总结:
JSON 的形式就是用大括“{}”号包括起来的项目列表,每一个项目间并用逗号“,”分隔,而项目就是用冒号“:”分隔的属性名和属性值。这是典型的字典表示形式,也再次表明了 JavaScript 里的对象就是字典结构。不管多么复杂的对象,都可以被一句JSON 代码来创建并赋值。
其实,JSON 就是JavaScript 对象最好的序列化形式,它比XML 更简洁也更省空间。对象可以作为一个JSON 形式的字符串,在网络间自由传递和交换信息。而当需要将这个JSON 字符串变成一个JavaScript 对象时,只需要使用eval 函数这个强大的数码转换引擎,就立即能得到一个JavaScript 内存对象。正是由于JSON 的这种简单朴素的天生丽质,才使得她在AJAX 舞台上成为璀璨夺目的明星。
JavaScript 就是这样,把面向对象那些看似复杂的东西,用及其简洁的形式表达出来。卸下对象浮华的浓妆,还对象一个眉目清晰!
类的声明:
理解了JSON构建对象的形式,那么我们下面来用另一种形式声明一个类,并构建对象:
思想:在JavaScript 中我们可以使用new 操作符结合一个函数的形式来创建对象
1
function ClassA() //构造函数不带参数
2
{
3
var _privateProp = "privateProp"; // 通过var关键字声明一个局部变量,其作用域是该类的内部不对外公开;
4
this.p1 = "p1";
5
this.p2 = "p2";
6
this.f1 = function(){ // f1 方法
7
alert("I am f1!");
8
}
9
this.f2 = function(){ // f2 方法
10
alert("I am f2!");
11
}
12
}
13

2

3

4

5

6

7

8

9

10

11

12

13

其实,如果你愿意把函数当作“类”的话,她就是“类”,因为她本来就有“类”的那些特征。难道不是吗?她生出的儿子各个都有相同的特征,而且构造函数也与类同名嘛!
利用prototype属性还可以实现另外一种类的声明方式:
1
function ClassA() {}
2
3
ClassA.prototype = {
4
p1 : "p1";
5
p2 : "p2";
6
f1 : function() {
7
alert("f1");
8
}
9
f2 : function() {
10
alert("f2");
11
}
12
}

2

3

4

5

6

7

8

9

10

11

12

上面这种方式使用{} 的方式声明了一个匿名对象,大括号内用逗号将属性与值得列表分隔开。
可以看到,采用prototype的方式声明类,代码更加简洁明了,因此这种方式在许多Ajax开发框架中得到广泛的应用。
如:prototype框架,Dojo框架。
接下来我们来看一下 继承,即如何来实现继承?
注意:JavaScript语言本身并没有提供对于继承的语法的支持,但是仍然可以采用复制属性和对象的方式来实现继承。
下面是实现继承最直接的方式:(构建一个新的类SubClassA 去继承ClassA所有的东西,同时新设置一方法newMethod)
1
function ClassA() {}
2
3
ClassA.prototype = {
4
p1 : "p1";
5
p2 : "p2";
6
f1 : function() {
7
alert("f1");
8
}
9
f2 : function() {
10
alert("f2");
11
}
newMethod : function()
{
alert("newMethod");
}
12
}

2

3

4

5

6

7

8

9

10

11

newMethod : function()
{
alert("newMethod");
}
12

虽然这种实现方式表面上解决了问题(其实我并认为这是继承机制的概念),但是两个类声明中的代码重复书写是一个很大的隐患,因为如果ClassA类的定义改变了,那么SubClassA类也要同步进行手工修改,显然不是那么回事的。
解决方案可以这样,我们可以利用for(... in ...)语句,遍历ClassA类的所有属性和方法,将其"复制"到新声明的SunClassA类中。上面代码修改后如下:
1
function SubClassA() {}
2
3
for(p in ClassA.prototype)
4
{
5
SubClassA.protopyte[p] = ClassA.prototype[p];
6
}
7
SubClassA.prototype.newMethod = function(){
8
alert("new Method!");
9
}
10

2

3

4

5

6

7

8

9

10

SubClassA类的声明中,首先通过for(... in ...)语句将ClassA的所有原型属性和方法复制到SubClassA的prototype属性中,然后声明一个新的原型方法newMethod。
结束语
下次介绍常见的Ajax框架中的面向对象编程(Prototype/Dojo)