??? 最近在閱讀《
JavaScript
高級程序設計》,未免遺忘讀過的內容,就打算以博客的形式做些讀書筆記。今天介紹的是
JavaScript
中的四種定義對象的方法,除了這四種方法,還有工廠方法來定義對象,但考慮到其簡單性及非正規(guī)性,這里就不做介紹。和
Java
這樣的面向對象語言相比,
JavaScript
更像是函數(shù)式語言,其并沒有類的概念,蓋之以對象定義的概念,而具體創(chuàng)建的對象叫做對象的實例。
??? 1)構造函數(shù)方式定義對象。
這種方式是在構造函數(shù)內定義屬性和方法。這里舉個簡單的例子:
??? function?Animal(name){
????????this.name?=?name;
????????this.introduceSelf?=?function(){
????????????window.alert("I?am?a?"?+?this.name+"!");
????????};
}
??? 對象的實例化如下:
var?dog?=?new?Animal("dog");
dog.?introduceSelf();
??? 當然,
也可以將對象的方法在構造函數(shù)外定義,如下所示:
function?introduceSelf(){
????window.alert("I?am?a?"?+?this.name+"!");
}
????function?Animal(name){
????this.name?=?name;
????this.introduceSelf?=?introduceSelf();
}
??
這種在構造函數(shù)內定義所有的屬性和方法的方式,使得構造函數(shù)相當于
Java
中類的概念。而將方法的具體定義獨立地放在構造函數(shù)外,會使得對象的定義和方法的定義并不緊密,如果在一個文件中這樣的方法和對象定義多的話,就會看起來凌亂許多。
??? 2)
原型方式。
該方式利用對象的
prototype
屬性,可以將其看成創(chuàng)建新對象所依賴的原型(關于
prototype
的詳細信息,可以百度一下,這方面的資料還是很多的)。這種方式將構造函數(shù)做成空構造函數(shù),然后將所有的屬性和方法被直接賦予
prototype
屬性,還是前面的例子,重寫如下:
??? function?Animal(){
????
}
Animal.prototype.name?=?"animal";
Animal.prototype.introduceSelf?=?function(){
????window.alert("I?am?a?"?+?this.name+"!");
};
//對象的實例如下:
var?dog?=?new?Animal();
dog.name?=?"dog";
dog.introductSelf();
??
這種方式的缺點是顯而易見的,就是不能在構造函數(shù)中對屬性進行賦值操作。還有一點是,對于引用類型的屬性(如
Array
實例),實例化的多個對象將共享一個引用。正因為這么多的問題,這種對象定義的方式并不可取。
??? 3)
構造函數(shù)、原型混合方式。
這種方式是最為流行的對象定義方式。它結合了構造函數(shù)及原型方式。這種方式用構造函數(shù)定義對象的所有非函數(shù)屬性,用原型方式定義對象的函數(shù)屬性(方法)。重寫前面的例子:
function?Animal(name){
????this.name?=?name;
}
Animal.prototype.introduceSelf?=?function(){
????window.alert("I?am?a?"?+?this.name+"!");
};
???
??? 4)
動態(tài)原型方式。
和構造函數(shù)、原型混合方式相比,動態(tài)原型方式只是在函數(shù)屬性定義的位置上有所不同。重寫前面的例子:
???
function
?Animal(name){
????
this
.name?
=
?name;
????
if
(
typeof
?Animal._initialized?
==
?'undefined'){
????????Animal.prototype.introduceSelf?
=
?
function
(){
????????????window.alert(
"
I?am?a?
"
?
+
?
this
.name
+
"
!
"
);
????????};
????????Animal._initialized?
=
?
true
;
????}
}
? ??? 其中_initialized是Animal的全局私有屬性(JavaScript中沒有私有屬性的概念,所有的屬性都是共有的,但為了表明一些屬性的私有特性,人們習慣在屬性名前加上“_”。),當?shù)谝淮螌嵗?/span>Animal時,if條件就為真,這樣就會定義Animal中的函數(shù)屬性。由于“Animal._initialized = true;”的存在,函數(shù)的定義調用一次而無論實例化多少個對象。