参考整理:http://www.cnblogs.com/seewood/archive/2005/06/24/180740.html
大部分的Javascript的编写者,都只是把它做为简单的脚本引擎,来创建动态的Web页面。同时Web设计人员开始使用在IE浏览器中定义的对象模型,来处理Web页面的内容。但是大多数的开发者并没有认识到Javascript在其自身就具有强大的面向对象的功能。当不使用强类型的时候(变量不必先声明后使用),这种解析性的语言,可以巧妙的达成面向对象(object-oriented)的功能,包括:
接下来将会阐述对象在Javascript中,对象是如何被使用,并且如何实现面向对象的。
1.基本概念
在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,那么Javascript是否具备这样的功能呢?
是的,Javascript也具有对象的概念,但是它和Java这样面向对象的语言还是有一定的区别的。
2.创建对象
创建对象有很多种方法:
(1)Object
在Javascript中,最简单的可构建的对象,就是机制内建的Object对象。在Javascript中,对象是指定名称的属性(property)的集合。做为解析性语言,Javascript允许给一个对象创建任意个属性,在任何时间(不像C++,它的属性是可以在任何时间添加给对象。它们并不需要事先在对象的声明(definition)或者构造(constructor)中,进行定义)。
所以,举例来说,我们可以创建一个对象,然后添加一系列的属性给它,就像这样:
obj = new Object();
obj.x = 1 ;
obj.y = 2 ;
这里,Javascript对象,可以用图形表示成这样的结构:
obj | |
x | 1 |
y | 2 |
prototype properties | |
constructor | function Object |
另外需要注意的是,我们创建的x和y属性, 我们的对象默认有一个属性constructor他指向一个Javascript内部对象函数(funciton)。(prototype,原型在后文会有进一步的说明)
(2)function (构造函数法)
编写一个构造函数,并通过new方式来创建对象,构造函数本可以带有构造参数:
function Obj(){
}
var obj = new Obj();
alert( typeof obj); // 显示 "object"
那么我们再看一下,带公共实例属性的对象,
function Obj(){
this .x = 1 ;
this .y = 2 ;
}
obj = new Obj();
可以用图形表示成这样的结构:
obj | |
x | 1 |
y | 2 |
prototype properties | |
constructor | function Obj |
我们还可以在构造函数中传入参数:
function Obj(a,b){
this .x = a;
this .y = b;
}
obj = new Obj( 1 , 2 );
alert(obj.x); // 1
alert(obj.y); // 2
obj2 = new Obj( 3 , 4 );
alert(obj2.x); // 3
alert(obj2.y); // 4
可以用图形表示成我们创建的对象:
obj | |
x | 1 |
y | 2 |
prototype properties | |
constructor | function Obj(a,b) |
obj1 | |
x | 3 |
y | 4 |
prototype properties | |
constructor | function Obj(a,b) |
为了封装对象的行为功能,向调用者隐藏执行过程,我们需要给对象创建方法(method)。Javascript允许你将任意一个函数(function)分配给对象的一个属性。当我们使用 obj.Function 的语法调用函数的时候,将把函数原来定义this的指向,当前这个对象(就像它在构造函数中的那样)。
function Obj(){
this .x = 1 ;
this .y = 2 ;
this .Bar = MyMethod;
}
function MyMethod(z){
this .x += z;
}
obj = new Obj();
obj | |
x | 1 |
y | 2 |
Bar | function MyMethod |
prototype properties | |
constructor | function Obj |
现在,我们简单的调用一下,做为对象的方法的Bar函数:
obj.Bar( 3 );
obj | |
x | 4 |
y | 2 |
Bar | function MyMethod |
prototype properties | |
constructor | function Obj |
所以,你可以方便的给对象定义构造函数和方法,使其对调用者而言,隐藏它的实现过程。同样的,因为,Javascript不是强类型的,所以,我们可以通过定义有相同名字的方法的对象,来简单的实现多态性(polymorphism)。
(3)prototype
试想一下,这是很笨的办法,每次我们都要创建名称没有使用意义的方法函数,然后在构造函数里,把它们分配给每个方法属性。其实,我发现使用Javascript的原型(prototype)机制,是更为直接的方法。
每个对象,可以参照一个原型对象,原型对象包含有自己的属性。它就好比是一个对象定义的备份。当代码,引用一个属性的时候,它并不存在于对象本身里,那么Javascript将会自动的在原型的定义中查找这个属性。而且,事实上,一个对象的原型对象又可以参照另外一个原型对象,就这样以链式最终关联到基类对象的构造函数。(对于DOM对象等系统的对象,原型对象可以修改,但是不可以赋值改变的,只有自定义对象可以。)这是template模型(模板方法,《设计模式》中行为模式的一种),它可以简化我们对方法的定义,同时也可以产生强大的继承机制。
在Javascript中,原型对象是被分配给构造函数的。所以,为了修改对象的原型,必须首先修改构造函数的原型对象的成员。然后,当对象从构造函数被构造的时候,对象将会引用到构造函数的原型。
function Foo(){
this .x = 1 ;
}
Foo.prototype.y = 2 ;
obj = new Foo;
document.write( ' obj.y = ' + obj.y);
obj.y = 2 ;
obj | |||||
x | 1 | ||||
prototype properties | |||||
constructor | function Foo
|
||||
y | 2 |
即使我们并没有直接的把y属性分配给obj,obj对象仍然有一个y属性。当我们引用obj.y的时候,Javascript实际返回obj.constructor.prototype.y的引用。我们可以肯定的是,原型的值的改变,也将会反映到对象中。
Foo.prototype.y = 3 ;
document.write( ' obj.y = ' + obj.y);
obj.y = 3
obj | |||||
x | 1 | ||||
prototype properties | |||||
constructor | function Foo
|
||||
y | 3 |
我们也可以发现,一旦我们初始化一个属性的“私有”(private )的值,存放在原型中的值并不会收到影响:
obj.y = 4 ;
Foo.prototype.y = 3 ;
obj | |||||
x | 1 | ||||
y | 4 | ||||
prototype properties | |||||
constructor | function Foo
|
原型方法的命名(Prototype Method Naming)
function Foo(){
this .x = 1 ;
}
function Foo.prototype.DoIt(){
this .x ++ ;
}
obj = new Foo;
obj.DoIt();
obj | |||||
x | 2 | ||||
prototype properties | |||||
constructor | function Foo
|
||||
DoIt | function Foo.prototype.DoIt |
(4)对象直接量创建对象(json)
JSON(JavaScript Object Notation)是一种优美的JavaScript对象创建方法。JSON也是一种轻量级数据交换格式。JSON非常易于人阅读与编写,同时利于机器解析与生成。JSON是在AJAX中代替XML交换数据的更佳方案。
JSON定义法类似于直接定义法,JSON定义法就是将直接定义法定义的函数与属性放到大括号中,并且去掉属性与函数签名的对象名,把等于号改为了冒号,每行后面改为逗号!
var jsonobject =
{
// 对象内的属性语法(属性名与属性值是成对出现的)
propertyname:value,
// 对象内的函数语法(函数名与函数内容是成对出现的)
functionname: function (){...;}
};
引用网址: http://www.dreamdu.com/javascript/json/
var site =
{
URL : " www.dreamdu.com " ,
name : " 梦之都 " ,
englishname : " dreamdu " ,
author : " 可爱的猴子 " ,
summary : " 免费的网页设计教程 " ,
pagescount : 100 ,
isOK : true ,
startdate : new Date( 2005 , 12 ),
say : function (){document.write( this .englishname + "say : hello world! " )},
age : function (){document.write( this .name + " 已经 " +(( new Date().getFullYear()) - this .startdate.getFullYear()) + " 岁了! " )}
};
嵌套JSON对象定义
var sites =
{
count: 2 ,
language: " chinese " ,
baidu:
{
URL: " www.baidu.com " ,
name: " 百度 " ,
author: " baidu " ,
say : function (){document.write( this .name +" say hello " )}
},
dreamdu:
{
URL: " www.dreamdu.com " ,
name: " 梦之都 " ,
author: " monkey " ,
say : function (){document.write( this .name +" say hello " )}
}
};
实例见: http://www.dreamdu.com/javascript/exe_json/
3.对象属性
(1)JS中可以为对象定义三种类型的属性:私有属性、实例属性和类属性,
与Java类似,私有属性只能在对象内部使用,实例属性必须通过对象的实例进行引用,而类属性可以直接通过类名进行引用。
(2)私有属性
私有属性只能在构造函数内部定义与使用。
语法格式:var propertyName=value;
例如:
function User(age){
this .age = age;
var isChild = age < 12 ;
this .isLittleChild = isChild;
}
var user = new User( 15 );
alert(user.isLittleChild); // 正确的方式
alert(user.isChild); // 报错:对象不支持此属性或方法
(3)实例属性,存在两种方式:
prototype方式,语法格式:functionName.prototype.propertyName=value
this方式,语法格式:this.propertyName=value,注意后面例子中this使用的位置
上面中value可以是字符串、数字和对象。
例如:
function User(){ }
User.prototype.name = “user1”;
User.prototype.age = 18 ;
var user = new User();
alert(user.age);function User(name,age,job){
—————————————–
this.name=“user1”;
this.age=18;
this.job=job;
}
alert(user.age);
(4)类属性
语法格式:functionName.propertyName=value
例如:
function User(){ }
User.MAX_AGE = 200 ;
User.MIN_AGE = 0 ;
alert(User.MAX_AGE);
参考JS标准对象的类属性:
Number.MAX_VALUE //最大数值 Math.PI //圆周率