js中創(chuàng)建對象的幾種方式示例介紹
更新時間:2014年01月26日 15:27:48 作者:
JavaScript中的所有事物都是對象,本文為大家介紹下JS中創(chuàng)建對象的幾種方式,如原始方法、工廠方法等等
JavaScript中的所有事物都是對象:字符串、數(shù)組、數(shù)值、函數(shù)等。JS中并沒有類的概念,
但我們可以利用JS的語法特征,以類的思想來創(chuàng)建對象。
原始方法
<script type="text/javascript">
var obj = new Object();
obj.name = "Koji"; //為對象添加屬性
obj.age = 21;
obj.showName = function(){ //為對象添加方法
alert(this.name);
}
obj.showAge = function(){
alert(this.age);
}
obj.showName(); //Koji
obj.showAge(); //21
</script>
上面的方式通過new關(guān)鍵字生成一個對象,然后根據(jù)JS是動態(tài)語言的特性添加屬性和方法,構(gòu)
造一個對象。其中的this是表示調(diào)用該方法的對象。
這種方式的問題是如果需要多次創(chuàng)建對象,則需要重復(fù)代碼多次,不利于代碼的復(fù)用。
工廠方法
<script type="text/javascript">
function createObj(){
var obj = new Object(); //創(chuàng)建對象
obj.name = "Koji";
obj.age = 21;
obj.showName = function(){
alert(this.name);
}
obj.showAge = function(){
alert(this.age);
}
return obj; //返回對象
}
var obj1 = createObj();
var obj2 = createObj();
obj1.showName(); //Koji
obj2.showAge(); //21
</script>
這種方式提高了代碼重用率,還可以改變工廠方法,傳入?yún)?shù)賦值。
<script type="text/javascript">
function createObj(name, age){ //構(gòu)造對象時可以傳入初始化參數(shù)
var obj = new Object(); //創(chuàng)建對象
obj.name = name;
obj.age = age;
obj.showName = function(){
alert(this.name);
}
obj.showAge = function(){
alert(this.age);
}
return obj; //返回對象
}
var obj1 = createObj("Koji", 22);
var obj2 = createObj("Luo", 21);
obj1.showName(); //Koji
obj1.showAge(); //22
obj2.showName(); //Luo
obj2.showAge(); //21
</script>
上面的方式雖然可以提高代碼的復(fù)用率,但和面向?qū)ο笾蓄惖母拍钕啾扔幸粋€很大的缺陷。面
相對象強調(diào)對象的屬性私有,而對象的方法是共享的。而上面的工廠方法創(chuàng)建對象的時候要為每個
對象創(chuàng)建各自私有的方法。同時由于為每個對象都創(chuàng)建邏輯相同的方法,浪費內(nèi)存。改進如下
<span style="font-size:14px;"><script type="text/javascript">
function createObj(name, age){
var obj = new Object(); //創(chuàng)建對象
obj.name = name;
obj.age = age;
obj.showName = showName;
obj.showAge = showAge;
return obj; //返回對象
}
function showName(){ //函數(shù)也是一個對象
alert(this.name);
}
function showAge(){
alert(this.age);
}
var obj1 = createObj("Koji", 22);
var obj2 = createObj("Luo", 21);
obj1.showName(); //Koji
obj1.showAge(); //22
obj2.showName(); //Luo
obj2.showAge(); //21
</script></span>
上面通過定義連個函數(shù)對象,解決了不同對象持有函數(shù)對象的私有問題?,F(xiàn)在所有對象的方法都
持有上面兩個函數(shù)的引用。但這么一來的話,對象的函數(shù)又和對象成了相互獨立,不相干的了。這和
面向?qū)ο笾刑囟ǚ椒▽儆谔囟惖乃枷氩环稀?
構(gòu)造函數(shù)方式
<script type="text/javascript">
//定義一個構(gòu)造函數(shù),用來生成對應(yīng)的對象,可以類比Java中的構(gòu)造函數(shù)
function Person(name, age){
//當調(diào)用new Person的時候,在執(zhí)行第一行代碼前,先生成一個Person對象,并將對象在內(nèi)存中的
//索引賦值給this關(guān)鍵字,此時可以通過this關(guān)鍵字操作新生成的對象,如下面的添加屬性或方法
this.name = name; //this關(guān)鍵字不能少。為當前對象,即this關(guān)鍵字引用的對象的name屬性賦值
//,實際相當于為當前對象添加name屬性后,再為其name屬性賦值。
this.age = age;
this.showName = function(){ //為當前對象添加方法
alert(this.name);
}
this.showAge = function(){
alert(this.age);
}
//將當前對象返回給賦值符號左邊的變量(不必明確使用return)
}
var obj1 = new Person("Koji", 22); //生成一個Person對象
var obj2 = new Person("Luo", 21);
obj1.showName(); //Koji
obj1.showAge(); //22
obj2.showName(); //Luo
obj2.showAge(); //21
</script>
構(gòu)造函數(shù)的方式和工廠方式一樣,會為每個對象創(chuàng)建獨享的函數(shù)對象。當然也可以將這些函數(shù)
對象定義在構(gòu)造函數(shù)外面,這樣又有了對象和方法相互獨立的問題。
原型方法:該方法利用的對象的prototype屬性
script type="text/javascript">
function Person(){} //定義一個空構(gòu)造函數(shù),且不能傳遞參數(shù)
//將所有的屬性的方法都賦予prototype屬性
Person.prototype.name = "Koji"; //添加屬性
Person.prototype.age = 22;
Person.prototype.showName = function(){ //添加方法
alert(this.name);
}
Person.prototype.showAge = function(){
alert(this.age);
}
var obj1 = new Person(); //生成一個Person對象
var obj2 = new Person();
obj1.showName(); //Koji
obj1.showAge(); //22
obj2.showName(); //Koji
obj2.showAge(); //22
</script>
當生成Person對象的時候prototype的屬性都賦值給了新的對象。那么屬性和方法是共享的。
該方法的問題首先是構(gòu)造函數(shù)不能傳參,每個新生成的對象都有默認值。其次,方法共享沒有
任何問題,但是屬性共享就有問題,當屬性是可改變狀態(tài)的對象的時候。
<script type="text/javascript">
function Person(){} //定義一個空構(gòu)造函數(shù),且不能傳遞參數(shù)
Person.prototype.age = 22;
Person.prototype.array = new Array("Koji", "Luo");
Person.prototype.showAge = function(){
alert(this.age);
}
Person.prototype.showArray = function(){
alert(this.array);
}
var obj1 = new Person(); //生成一個Person對象
var obj2 = new Person();
obj1.array.push("Kyo"); //向obj1的array屬性添加一個元素
obj1.showArray(); //Koji,Luo,Kyo
obj2.showArray(); //Koji,Luo,Kyo
</script>
上面的代碼通過obj1向obj1的屬性array添加元素的時候,obj2的arra屬性的元素也跟著受到
影響,原因就在于obj1和obj2對象的array屬性引用的是同一個Array對象,那么改變這個Array
對象,另一引用該Array對象的屬性自然也會受到影響
混合的構(gòu)造函數(shù)/原型方式
使用構(gòu)造函數(shù)定義對象的屬性,使用原型(prototype)定義對象的方法,這樣就可以做到屬性
私有,而方法共享。
<script type="text/javascript">
function Person(name, age) {
this.name = name;
this.age = age;
this.array = new Array("Koji", "Luo");
}
Person.prototype.showName = function() {
alert(this.name);
}
Person.prototype.showArray = function() {
alert(this.array);
}
var obj1 = new Person("Koji", 22); //生成一個Person對象
var obj2 = new Person("Luo", 21);
obj1.array.push("Kyo"); //向obj1的array屬性添加一個元素
obj1.showArray(); //Koji,Luo,Kyo
obj1.showName(); //Koji
obj2.showArray(); //Koji,Luo
obj2.showName(); //Luo
</script>
屬性私有后,改變各自的屬性不會影響別的對象。同時,方法也是由各個對象共享。在語義上,
這符合了面相對象編程的要求。
動態(tài)原型方法
<script type="text/javascript">
function Person(name, age) {
this.name = name;
this.age = age;
this.array = new Array("Koji", "Luo");
//如果Person對象中的_initialized為undefined,表明還沒有為Person的原型添加方法
if (typeof Person._initialized == "undefined")
{
Person.prototype.showName = function() {
alert(this.name);
}
Person.prototype.showArray = function() {
alert(this.array);
}
Person._initialized = true; //設(shè)置為true,不必再為prototype添加方法
}
}
var obj1 = new Person("Koji", 22); //生成一個Person對象
var obj2 = new Person("Luo", 21);
obj1.array.push("Kyo"); //向obj1的array屬性添加一個元素
obj1.showArray(); //Koji,Luo,Kyo
obj1.showName(); //Koji
obj2.showArray(); //Koji,Luo
obj2.showName(); //Luo
</script>
這種方法和構(gòu)造函數(shù)/原型方式大同小異。只是將方法的添加放到了構(gòu)造函數(shù)之中,同時在構(gòu)造
函數(shù)Person上添加了一個屬性用來保證if語句只能成功執(zhí)行一次
在實際應(yīng)用中采用最廣泛的是構(gòu)造函數(shù)/原型方法。動態(tài)原型方法也很流行,它在功能上和構(gòu)造
函數(shù)/原型方法是等價的。不要單獨使用構(gòu)造函數(shù)或原型方法。
但我們可以利用JS的語法特征,以類的思想來創(chuàng)建對象。
原始方法
復(fù)制代碼 代碼如下:
<script type="text/javascript">
var obj = new Object();
obj.name = "Koji"; //為對象添加屬性
obj.age = 21;
obj.showName = function(){ //為對象添加方法
alert(this.name);
}
obj.showAge = function(){
alert(this.age);
}
obj.showName(); //Koji
obj.showAge(); //21
</script>
上面的方式通過new關(guān)鍵字生成一個對象,然后根據(jù)JS是動態(tài)語言的特性添加屬性和方法,構(gòu)
造一個對象。其中的this是表示調(diào)用該方法的對象。
這種方式的問題是如果需要多次創(chuàng)建對象,則需要重復(fù)代碼多次,不利于代碼的復(fù)用。
工廠方法
復(fù)制代碼 代碼如下:
<script type="text/javascript">
function createObj(){
var obj = new Object(); //創(chuàng)建對象
obj.name = "Koji";
obj.age = 21;
obj.showName = function(){
alert(this.name);
}
obj.showAge = function(){
alert(this.age);
}
return obj; //返回對象
}
var obj1 = createObj();
var obj2 = createObj();
obj1.showName(); //Koji
obj2.showAge(); //21
</script>
這種方式提高了代碼重用率,還可以改變工廠方法,傳入?yún)?shù)賦值。
復(fù)制代碼 代碼如下:
<script type="text/javascript">
function createObj(name, age){ //構(gòu)造對象時可以傳入初始化參數(shù)
var obj = new Object(); //創(chuàng)建對象
obj.name = name;
obj.age = age;
obj.showName = function(){
alert(this.name);
}
obj.showAge = function(){
alert(this.age);
}
return obj; //返回對象
}
var obj1 = createObj("Koji", 22);
var obj2 = createObj("Luo", 21);
obj1.showName(); //Koji
obj1.showAge(); //22
obj2.showName(); //Luo
obj2.showAge(); //21
</script>
上面的方式雖然可以提高代碼的復(fù)用率,但和面向?qū)ο笾蓄惖母拍钕啾扔幸粋€很大的缺陷。面
相對象強調(diào)對象的屬性私有,而對象的方法是共享的。而上面的工廠方法創(chuàng)建對象的時候要為每個
對象創(chuàng)建各自私有的方法。同時由于為每個對象都創(chuàng)建邏輯相同的方法,浪費內(nèi)存。改進如下
復(fù)制代碼 代碼如下:
<span style="font-size:14px;"><script type="text/javascript">
function createObj(name, age){
var obj = new Object(); //創(chuàng)建對象
obj.name = name;
obj.age = age;
obj.showName = showName;
obj.showAge = showAge;
return obj; //返回對象
}
function showName(){ //函數(shù)也是一個對象
alert(this.name);
}
function showAge(){
alert(this.age);
}
var obj1 = createObj("Koji", 22);
var obj2 = createObj("Luo", 21);
obj1.showName(); //Koji
obj1.showAge(); //22
obj2.showName(); //Luo
obj2.showAge(); //21
</script></span>
上面通過定義連個函數(shù)對象,解決了不同對象持有函數(shù)對象的私有問題?,F(xiàn)在所有對象的方法都
持有上面兩個函數(shù)的引用。但這么一來的話,對象的函數(shù)又和對象成了相互獨立,不相干的了。這和
面向?qū)ο笾刑囟ǚ椒▽儆谔囟惖乃枷氩环稀?
構(gòu)造函數(shù)方式
復(fù)制代碼 代碼如下:
<script type="text/javascript">
//定義一個構(gòu)造函數(shù),用來生成對應(yīng)的對象,可以類比Java中的構(gòu)造函數(shù)
function Person(name, age){
//當調(diào)用new Person的時候,在執(zhí)行第一行代碼前,先生成一個Person對象,并將對象在內(nèi)存中的
//索引賦值給this關(guān)鍵字,此時可以通過this關(guān)鍵字操作新生成的對象,如下面的添加屬性或方法
this.name = name; //this關(guān)鍵字不能少。為當前對象,即this關(guān)鍵字引用的對象的name屬性賦值
//,實際相當于為當前對象添加name屬性后,再為其name屬性賦值。
this.age = age;
this.showName = function(){ //為當前對象添加方法
alert(this.name);
}
this.showAge = function(){
alert(this.age);
}
//將當前對象返回給賦值符號左邊的變量(不必明確使用return)
}
var obj1 = new Person("Koji", 22); //生成一個Person對象
var obj2 = new Person("Luo", 21);
obj1.showName(); //Koji
obj1.showAge(); //22
obj2.showName(); //Luo
obj2.showAge(); //21
</script>
構(gòu)造函數(shù)的方式和工廠方式一樣,會為每個對象創(chuàng)建獨享的函數(shù)對象。當然也可以將這些函數(shù)
對象定義在構(gòu)造函數(shù)外面,這樣又有了對象和方法相互獨立的問題。
原型方法:該方法利用的對象的prototype屬性
復(fù)制代碼 代碼如下:
script type="text/javascript">
function Person(){} //定義一個空構(gòu)造函數(shù),且不能傳遞參數(shù)
//將所有的屬性的方法都賦予prototype屬性
Person.prototype.name = "Koji"; //添加屬性
Person.prototype.age = 22;
Person.prototype.showName = function(){ //添加方法
alert(this.name);
}
Person.prototype.showAge = function(){
alert(this.age);
}
var obj1 = new Person(); //生成一個Person對象
var obj2 = new Person();
obj1.showName(); //Koji
obj1.showAge(); //22
obj2.showName(); //Koji
obj2.showAge(); //22
</script>
當生成Person對象的時候prototype的屬性都賦值給了新的對象。那么屬性和方法是共享的。
該方法的問題首先是構(gòu)造函數(shù)不能傳參,每個新生成的對象都有默認值。其次,方法共享沒有
任何問題,但是屬性共享就有問題,當屬性是可改變狀態(tài)的對象的時候。
復(fù)制代碼 代碼如下:
<script type="text/javascript">
function Person(){} //定義一個空構(gòu)造函數(shù),且不能傳遞參數(shù)
Person.prototype.age = 22;
Person.prototype.array = new Array("Koji", "Luo");
Person.prototype.showAge = function(){
alert(this.age);
}
Person.prototype.showArray = function(){
alert(this.array);
}
var obj1 = new Person(); //生成一個Person對象
var obj2 = new Person();
obj1.array.push("Kyo"); //向obj1的array屬性添加一個元素
obj1.showArray(); //Koji,Luo,Kyo
obj2.showArray(); //Koji,Luo,Kyo
</script>
上面的代碼通過obj1向obj1的屬性array添加元素的時候,obj2的arra屬性的元素也跟著受到
影響,原因就在于obj1和obj2對象的array屬性引用的是同一個Array對象,那么改變這個Array
對象,另一引用該Array對象的屬性自然也會受到影響
混合的構(gòu)造函數(shù)/原型方式
使用構(gòu)造函數(shù)定義對象的屬性,使用原型(prototype)定義對象的方法,這樣就可以做到屬性
私有,而方法共享。
復(fù)制代碼 代碼如下:
<script type="text/javascript">
function Person(name, age) {
this.name = name;
this.age = age;
this.array = new Array("Koji", "Luo");
}
Person.prototype.showName = function() {
alert(this.name);
}
Person.prototype.showArray = function() {
alert(this.array);
}
var obj1 = new Person("Koji", 22); //生成一個Person對象
var obj2 = new Person("Luo", 21);
obj1.array.push("Kyo"); //向obj1的array屬性添加一個元素
obj1.showArray(); //Koji,Luo,Kyo
obj1.showName(); //Koji
obj2.showArray(); //Koji,Luo
obj2.showName(); //Luo
</script>
屬性私有后,改變各自的屬性不會影響別的對象。同時,方法也是由各個對象共享。在語義上,
這符合了面相對象編程的要求。
動態(tài)原型方法
復(fù)制代碼 代碼如下:
<script type="text/javascript">
function Person(name, age) {
this.name = name;
this.age = age;
this.array = new Array("Koji", "Luo");
//如果Person對象中的_initialized為undefined,表明還沒有為Person的原型添加方法
if (typeof Person._initialized == "undefined")
{
Person.prototype.showName = function() {
alert(this.name);
}
Person.prototype.showArray = function() {
alert(this.array);
}
Person._initialized = true; //設(shè)置為true,不必再為prototype添加方法
}
}
var obj1 = new Person("Koji", 22); //生成一個Person對象
var obj2 = new Person("Luo", 21);
obj1.array.push("Kyo"); //向obj1的array屬性添加一個元素
obj1.showArray(); //Koji,Luo,Kyo
obj1.showName(); //Koji
obj2.showArray(); //Koji,Luo
obj2.showName(); //Luo
</script>
這種方法和構(gòu)造函數(shù)/原型方式大同小異。只是將方法的添加放到了構(gòu)造函數(shù)之中,同時在構(gòu)造
函數(shù)Person上添加了一個屬性用來保證if語句只能成功執(zhí)行一次
在實際應(yīng)用中采用最廣泛的是構(gòu)造函數(shù)/原型方法。動態(tài)原型方法也很流行,它在功能上和構(gòu)造
函數(shù)/原型方法是等價的。不要單獨使用構(gòu)造函數(shù)或原型方法。
相關(guān)文章
JavaScript中本地存儲(LocalStorage)和會話存儲(SessionStorage)的使用
本地存儲和會話存儲是比較常用的方法,你知道兩者的區(qū)別嗎,本文詳細的介紹了JavaScript中本地存儲(LocalStorage)和會話存儲(SessionStorage)的使用,具有一定的參考價值,感興趣的可以了解一下2022-03-03JavaScript實現(xiàn)窮舉排列(permutation)算法謎題解答
這篇文章主要介紹了JavaScript實現(xiàn)窮舉排列(permutation)算法謎題解答,窮舉排列是指窮舉一個數(shù)組中各個元素的排列,需要的朋友可以參考下2014-12-12JS數(shù)據(jù)結(jié)構(gòu)與算法中的隊列結(jié)構(gòu)詳解
隊列指的是一種受限的線性表,先進先出,今天通過本文帶領(lǐng)大家認識隊列及隊列的應(yīng)用,對JS數(shù)據(jù)結(jié)構(gòu)與算法-隊列結(jié)構(gòu)相關(guān)知識感興趣的朋友一起看看吧2022-11-11JavaScript Set與Map數(shù)據(jù)結(jié)構(gòu)詳細分析
大家心里是否產(chǎn)生過這樣的疑問,JS中既然已經(jīng)有對象這種數(shù)據(jù)結(jié)構(gòu),我們?yōu)槭裁催€要再單獨去使用Set或者Map呢?下面這篇文章主要給大家介紹了關(guān)于ES6中Set和Map數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下2022-11-11.net JS模擬Repeater控件的實現(xiàn)代碼
一個模板控件規(guī)定了它的模板語法和js api,這是一個repeater控件的JS實現(xiàn):2013-06-06基于javascript實現(xiàn)判斷移動終端瀏覽器版本信息
這篇文章主要介紹了基于javascript實現(xiàn)判斷移動終端瀏覽器版本信息,需要的朋友可以參考下2014-12-12仿iPhone通訊錄制作小程序自定義選擇組件的實現(xiàn)
這篇文章主要介紹了仿iPhone通訊錄制作小程序自定義選擇組件的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05