javascript中創建對象的方式

/*javascript中創建對象的方式(js中沒有類的概念)*/

//1.基於已有對象擴充器屬性和方法

var object=new Object();
object.name="zhangsan";
object.setName=function(name){//這種方式有弊端: 在創建另一個對象時,其它的對象不能使用該方法,需要重新定義
       this.name=name;
}
object.getName=function(){
       return this.name;
}
alert(object.name);//zhangsan
object.setName("zhanfei");
alert(object.name);//zhangfei
alert(object.getName());

//2.工廠方式創建對象:(類似於java中的靜態工廠方法)
function createObject(username,password){//調用方法時爲屬性賦值
       var object=new Object();
       object.username=username;
       object.password=password;//在java中: 一個類有屬性有方法,不管定義了多少個方法,不管生成多少個對象,方法只有一份,會被多個對象共享,在對象調用方法時會隱含的傳一個this的引用表示是誰調用的這個方法
       object.getUsername=function(){//我們期望,不管創建多少個對象,方法只有一份,屬性有多份---改成多個對象共享一個方法
              return this.username;
       }
       object.getPassword=function(){
              return this.password;
       }
       object.setUsername=function(name){
              this.username=name;
       }
       object.setPassword=function(pwd){
              this.password=pwd;
       }
       return object;
}

//var object=createObject();
//alert("username: "+object.username+", password: "+object.password);
//object.setUsername("lisi");
//object.setPassword("234");
//alert("username: "+object.username+", password: "+object.password);
var object=createObject("wangwu","123");
alert(object.getUsername()+","+object.getPassword());//在調用一個對象的方法時,如果沒有寫小括號就會把該方法的定義以字符串的形式顯示出來
object.setUsername("lisi");
object.setPassword("234");
alert(object.getUsername()+","+object.getPassword());

//改成多個對象共享同一個方法的方式:(上面那種方式創建對象的方法會爲每一個對象都創建方法)
//創建共享方法對象  --缺點:對象的定義與方法的定義分離,容易造成誤解
function getUsername(){
       return this.username;
}
function getPassword(){
       return this.password;
}
function setUsername(name){
       this.username=name;
}
function setPassword(pwd){
       this.password=pwd;
}

function createObject(username,password){//調用方法時爲屬性賦值
       var object=new Object();
       object.username=username;
       object.password=password;//在java中: 一個類有屬性有方法,不管定義了多少個方法,不管生成多少個對象,方法只有一份,會被多個對象共享,在對象調用方法時會隱含的傳一個this的引用表示是誰調用的這個方法
       object.getUsername=getUsername;//我們期望,不管創建多少個對象,方法只有一份,屬性有多份---改成多個對象共享一個方法
       object.getPassword=getPassword;//------------將對象的方法指向外部創建的方法,這樣就可以實現方法的共享


       object.setUsername=setUsername;
       object.setPassword=setPassword
       return object;
}


var object=createObject("wangwu","123");
alert(object.getUsername()+","+object.getPassword());//在調用一個對象的方法時,如果沒有寫小括號就會把該方法的定義以字符串的形式顯示出來
object.setUsername("lisi");
object.setPassword("234");
alert(object.getUsername()+","+object.getPassword());

//3.構造函數方式:
function Person(username,password){//只有在使用new來創建該對象時,下面註釋中的解釋才成立,直接調用Person方法則不會有註釋中的情況發生
//1.在執行第一行代碼前,js引擎會爲我們生成一個對象(this)
       this.username=username;
       this.password=password;
       this.getInfo=function(){
              alert(this.username+", "+this.password);
       }
//2.此處有一個隱藏的return語句,用於將之前生成的對象返回
}
var person=new Person("zhangsan","123");
person.getInfo();

//4.原型("prototype")方式(prototype是object中的一個屬性對象,所以每一個對象都會擁有該屬性)
function Person(){//空對象

}
Person.prototype.username="zhangsan";//給Person的prototype屬性附加username屬性,此時我們就宣稱Person對象也就擁有了username這個屬性
//給一個對象的原型屬性附加的任何內容,都會直接的被對象訪問到
//我們可以根據一個對象的原型給它賦上屬性,方法 原型所屬的對象就宣稱它擁有了這些屬性也擁有了這些方法
Person.prototype.password="123";
Person.prototype.getInfo=function(){
       alert(this.username+", "+this.password);
}
var person=new Person();
var person2=new Person();
person.username="lisi";//改變person對象的username屬性,對person2沒任何影響,實際上是我們使用了字符串造成的巧合而已,對於字符串來說在java中是不變的,對於javascript來說字符串也是不變的(它也是個常量)
person.getInfo();
person2.getInfo();
//---------------------
function Person(){//空對象

}
Person.prototype.username=new Array();
Person.prototype.password="123";
Person.prototype.getInfo=function(){
       alert(this.username+", "+this.password);
}
var person=new Person();
var person2=new Person();
person.username.push("lisi");
person.username.push("zhangsan");//改變person對象的username屬性,對person2沒任何影響,實際上是我們使用了字符串造成的巧合而已,對於字符串來說在java中是不變的,對於
person.password="456";
person2.password="000";
person.getInfo();
person2.getInfo();
//--結果 在爲person對象push元素時也改變了person2對象的username屬性
//單純的使用原型這種方式有兩個很重要的問題:
//1. 無法在構造函數中爲屬性賦初始值,只能在生成對象後再去改變屬性的值
//2. 會導致程序錯誤,如果使用原型方式對象,那麼生成的所有對象會共享原型中的屬性,這樣一個對象改變了該屬性也會反應到其他對象中
//--對於字符串對象js和java是一樣的(都是不變的),一旦改變一個字符串對象,實際上會把引用指向新的字符串對象

//5.使用原型+構造函數方式來定義對象(將屬性定義在構造方法中[不共享],將方法定義在原型中[共享])
function Person(username,password){//把屬性定義在構造方法中----每個對象都會獨立的擁有各自的屬性
       this.username=username;
       this.password=password;
}
Person.prototype.getInfo=function(){//把方法定義在原型當中----對於所有對象都會共享該方法
       alert(this.username+", "+this.password);
}
var person=new Person("張三","123");
person.getInfo();


//6.動態原型方式 :在構造函數中通過標誌量讓所有對象共享一個方法,而每個對象都擁有自己的屬性

function Person(){
       this.username="zhangsan";
       this.password="123";
       if(typeof Person.flag == "undefined"){//flag標識
              alert("invoked");//只生成一個方法對象,所以這裏只執行一次
              Person.prototype.getInfo=function(){
              alert(this.username+", "+this.password);
              }
              Person.flag=true;
       }
}
var person=new Person();
person.getInfo();
var person2=new Person();
person2.getInfo();


發佈了38 篇原創文章 · 獲贊 6 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章