参考整理:http://www.cnblogs.com/seewood/archive/2005/06/24/180740.html

 

     大部分的Javascript的编写者,都只是把它做为简单的脚本引擎,来创建动态的Web页面。同时Web设计人员开始使用在IE浏览器中定义的对象模型,来处理Web页面的内容。但是大多数的开发者并没有认识到Javascript在其自身就具有强大的面向对象的功能。当不使用强类型的时候(变量不必先声明后使用),这种解析性的语言,可以巧妙的达成面向对象(object-oriented)的功能,包括:

  • 封装 (Encapsulation)
  • 多态 (Polymorphism )
  • 继承 (Inheritance)

   接下来将会阐述对象在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
prototype
y 2
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
prototype
y 3
y 3

我们也可以发现,一旦我们初始化一个属性的“私有”(private )的值,存放在原型中的值并不会收到影响:

 

obj.y = 4;

Foo.prototype.y
= 3;

 

obj
x 1
y 4
prototype properties
constructor function Foo
prototype
y 3


原型方法的命名(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
prototype
DoIt function Foo.prototype.DoIt
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(){...;}
};

 

  • jsonobject -- JSON对象名称
  • propertyname -- 属性名称
  • functionname -- 函数名称
  • 一对大括号,括起多个"名称/值"的集合
  • JSON使用"名称/值"对的集合表示,也可以被理解为数组(Array)
  • 属性名或函数名可以是任意字符串,甚至是空字符串(见下面示例)
  • 逗号用于隔开每对"名称/值"对

引用网址: 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 //圆周率