这两天有个前同事总在问我Javascript面向对象的东西,所以,索性写篇文章让他看去吧,这里这篇文章主要想从一个整体的角度来说明一下Javascript的面向对象的编程。(成文比较仓促,应该有不准确或是有误的地方,请大家批评指正) 
另,这篇文章主要基于 ECMAScript 5, 旨在介绍新技术。关于兼容性的东西,请看最后一节。 
初探 
我们知道Javascript中的变量定义基本如下: 
复制代码 代码如下:
 
var name = 'Chen Hao';; 
var email = 'haoel(@)hotmail.com'; 
var website = 'http://jb51.net'; 
如果要用对象来写的话,就是下面这个样子:
复制代码 代码如下:
 
var chenhao = { 
name :'Chen Hao', 
email : 'haoel(@)hotmail.com', 
website : 'http://jb51.net' 
}; 
于是,我就可以这样访问:
复制代码 代码如下:
 
//以成员的方式 
chenhao.name; 
chenhao.email; 
chenhao.website; 
//以hash map的方式 
chenhao["name"]; 
chenhao["email"]; 
chenhao["website"]; 
关于函数,我们知道Javascript的函数是这样的:
复制代码 代码如下:
var doSomething = function(){ 
alert('Hello World.'); 
}; 
于是,我们可以这么干:
复制代码 代码如下:
var sayHello = function(){ 
var hello = "Hello, I'm "+ this.name 
+ ", my email is: " + this.email 
+ ", my website is: " + this.website; 
alert(hello); 
}; 
//直接赋值,这里很像C/C++的函数指针 
chenhao.Hello = sayHello; 
chenhao.Hello(); 
相信这些东西都比较简单,大家都明白了。 可以看到javascript对象函数是直接声明,直接赋值,直接就用了。runtime的动态语言。
还有一种比较规范的写法是:
复制代码 代码如下:
 
//我们可以看到, 其用function来做class。 
var Person = function(name, email, website){ 
this.name = name; 
this.email = email; 
this.website = website; 
this.sayHello = function(){ 
var hello = "Hello, I'm "+ this.name + ", \n" + 
"my email is: " + this.email + ", \n" + 
"my website is: " + this.website; 
alert(hello); 
}; 
}; 
var chenhao = new Person("Chen Hao", "haoel@hotmail.com", 
"http://jb51.net"); 
chenhao.sayHello(); 
顺便说一下,要删除对象的属性,很简单:
1 delete chenhao['email']
上面的这些例子,我们可以看到这样几点:
Javascript的数据和成员封装很简单。没有类完全是对象操作。纯动态!
Javascript function中的this指针很关键,如果没有的话,那就是局部变量或局部函数。
Javascript对象成员函数可以在使用时临时声明,并把一个全局函数直接赋过去就好了。
Javascript的成员函数可以在实例上进行修改,也就是说不同实例相同函数名的行为不一定一样。
属性配置 – Object.defineProperty
先看下面的代码:
复制代码 代码如下:
//创建对象 
var chenhao = Object.create(null); 
//设置一个属性 
Object.defineProperty( chenhao, 
'name', { value: 'Chen Hao', 
writable: true, 
configurable: true, 
enumerable: true }); 
//设置多个属性 
Object.defineProperties( chenhao, 
{ 
'email' : { value: 'haoel@hotmail.com', 
writable: true, 
configurable: true, 
enumerable: true }, 
'website': { value: 'http://jb51.net', 
writable: true, 
configurable: true, 
enumerable: true } 
} 
); 
下面就说说这些属性配置是什么意思。
writable:这个属性的值是否可以改。
configurable:这个属性的配置是否可以改。
enumerable:这个属性是否能在for…in循环中遍历出来或在Object.keys中列举出来。
value:属性值。
get()/set(_value):get和set访问器。
Get/Set 访问器
关于get/set访问器,它的意思就是用get/set来取代value(其不能和value一起使用),示例如下:
复制代码 代码如下:
var age = 0; 
Object.defineProperty( chenhao, 
'age', { 
get: function() {return age+1;}, 
set: function(value) {age = value;} 
enumerable : true, 
configurable : true 
} 
); 
chenhao.age = 100; //调用set 
alert(chenhao.age); //调用get 输出101(get中+1了); 
我们再看一个更为实用的例子——利用已有的属性(age)通过get和set构造新的属性(birth_year):
复制代码 代码如下:
 
Object.defineProperty( chenhao, 
'birth_year', 
{ 
get: function() { 
var d = new Date(); 
var y = d.getFullYear(); 
return ( y - this.age ); 
}, 
set: function(year) { 
var d = new Date(); 
var y = d.getFullYear(); 
this.age = y - year; 
} 
} 
); 
alert(chenhao.birth_year); 
chenhao.birth_year = 2000; 
alert(chenhao.age); 
这样做好像有点麻烦,你说,我为什么不写成下面这个样子:
复制代码 代码如下:
