JavaScript創(chuàng)建對象的常用方式總結(jié)
本文實例講述了JavaScript創(chuàng)建對象的常用方式。分享給大家供大家參考,具體如下:
JS中沒有類的概念,那么怎么創(chuàng)建對象呢?下面一一來細(xì)說!
傳統(tǒng)的創(chuàng)建對象的方式:
1、創(chuàng)建Object的實例
var person = new Object(); person.name = "Alice"; person.age = 12; person.showName = function() { alert(this.name); };
2、對象字面量形式創(chuàng)建單個對象
var person = { name : "Alice"; age : 12; showName : function() { alert(person.name); } };
創(chuàng)建對象的五種設(shè)計模式
1、工廠模式
雖然Object構(gòu)造函數(shù)和對象字面量都可以用來創(chuàng)建單個對象,但這個方式有個明顯的缺點(diǎn):使用同一個接口創(chuàng)建很多對象,會產(chǎn)生大量重復(fù)的代碼。為了解決這個問題,開始使用工廠模式。
function createPerson(name, age) { var obj = new Object(); obj.name = name; obj.age = age; obj.showName = function() { alert(this.name); }; return obj; } var person1 = createPerson("Alice", 23); var person2 = createPerson("Bruce", 22);
2、構(gòu)造函數(shù)模式
工廠模式雖然解決了創(chuàng)建多個相似對象的問題,但卻沒有解決對象識別的問題(即不知道對象的類型),于是,又出現(xiàn)了構(gòu)造函數(shù)模式,自定義的構(gòu)造函數(shù)意味著將來可以把它的實例識別為一種特定的類型。這是構(gòu)造函數(shù)模式勝過工廠模式的地方。
function Person(name, age) { this.name = name; this.age = age; this.showName = function() { alert(this.name); }; } var person1 = new Person("Alice", 23); var person2 = new Person("Bruce", 22);
構(gòu)造函數(shù)模式與工廠模式的不同之處在于:
1)沒有顯式地創(chuàng)建對象;
2)直接將屬性和方法賦給了this對象;
3)沒有return
語句
構(gòu)造函數(shù)的問題:每個方法都要在每個實例上重新創(chuàng)建一遍。由于JavaScript中的函數(shù)是對象,每定義一個函數(shù),就是實例化了一個Funtion對象,因此,使用構(gòu)造函數(shù)創(chuàng)建的每個實例都有一個名為showName()
的方法,但這些方法不是同一個Function的實例。不同實例上的同名函數(shù)是不相等的,因此person1.showName == person2.showName
返回false。
可以通過把函數(shù)定義轉(zhuǎn)移到構(gòu)造函數(shù)外部來解決這個問題,如下:
function Person(name,age,job) { this.name = name; this.age = age; this.showName = showName; } function showName(){ alert(this.name); } var person1 = new Person("Alice", 23); var person2 = new Person("Bruce", 22);
這樣雖然解決了方法多次創(chuàng)建問題,但又出現(xiàn)了新的問題:
(1)在全局作用域中定義的函數(shù)實際上只能被某個對象調(diào)用,這讓全局作用域名不副實。
(2)如果對象需要定義很多方法,那么就需要定義很多個全局函數(shù),那么就毫無封裝性可言了。
這些問題可以通過使用原型模式來解決。
3、原型模式
每個函數(shù)都以一個原型prototype屬性,是一個指針,指向一個對象。
使用原型對象的好處是可以讓所有對象實例共享它所包含的屬性和方法。也就是說,不必在構(gòu)造函數(shù)中定義對象實例的信息,而是可以直接將這些信息添加到原型對象中。
function Person() { } Person.prototype.name = name; Person.prototype.age = age; Person.prototype.showName = function(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person();
使用原型模式創(chuàng)建的新對象具有相同的屬性和方法。與構(gòu)造函數(shù)模式不同的是,新對象的這些屬性和方法是由所有對象所共享的。這會導(dǎo)致所有實例默認(rèn)有一樣的屬性值,因此person1.showName == person2.showName
返回true。
讀取某個對象的某個屬性的搜索方法:
1)首先在實例中搜索,若找到指定屬性,則返回該屬性的值。
2)否則繼續(xù)搜索指針指向的原型對象。
使用delete 實例名.屬性名可以刪除實例的某一屬性。
使用hasOwnProperty()
方法可以判斷屬性是存在于實例中,還是存在于原型中。只有給定屬性存在于實例中,才會返回true。
in操作符會在通過對象能夠訪問給定屬性時返回true,無論該屬性存在于實例中還是原型中。
同時使用hasOwnProperty()
方法和in操作符,能夠確定屬性到底是存在于對象中,還是存在于原型中。
function Person () { } Person.prototype.name = "Alice"; Person.prototype.age = "22"; Person.prototype.showName = function(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); person1.name = "Bruce"; alert(person1.name);//Bruce alert(person1.hasOwnProperty("name"));//true alert("name" in person1);//true alert(person2.name);//Alice delete person1.name; alert(person1.hasOwnProperty("name"));//false alert("name" in person1);//true alert(person1.name);//Alice
原型模式更簡單的語法:以一個包含所有屬性和方法的對象字面量來創(chuàng)建原型對象。
function Person () { } Person.prototype = { name:"Alice", age : "22", showName: function(){ alert(this.name); } };
用對象字面量來創(chuàng)建原型對象的結(jié)果相同,只是constructor屬性不再指向Person。這是由于這樣已經(jīng)完全重寫了默認(rèn)的prototype對象,因此constructor屬性也就變成了新對象的constructor屬性,指向Object構(gòu)造函數(shù)但不指向Person函數(shù)。此時,instanceof操作符還能返回正確的結(jié)果但通過constructor已經(jīng)無法確定對象的類型了。
var person = new Person(); alert(person instanceof Object);//true alert(person instanceof Person);//true alert(person.constructor == Object);//true alert(person.constructor == Person);//false
如果constuctor的值很重要,可以特意將其設(shè)置回適當(dāng)?shù)闹怠?/p>
function Person () { } Person.prototype = { constructor:Person, name:"Alice", age : "22", showName: function(){ alert(this.name); } };
重寫原型對象切斷了現(xiàn)有原型與任何之前已經(jīng)存在的對象實例之間的聯(lián)系,對象實例引用的仍然是最初的原型。
function Person () { } var person = new Person(); Person.prototype = { constructor:Person, name:"Alice", age : "22", showName: function(){ alert(this.name); } }; person.showName();//報錯:person.showName is not a function
4、組合使用構(gòu)造函數(shù)模式和原型模式
原型對象的問題:最大問題是由于共享屬性導(dǎo)致的。原型中所有屬性是被實例共享的,這對于函數(shù)很合適,對那些包含基本值的屬性也還說得過去,因為可以通過在實例上添加同名屬性,隱藏原型中的對應(yīng)屬性。然而,對于包含引用值的屬性來說,問題就比較突出了,修改某個實例的引用類型的屬性也會通過原型影響到其它實例的該屬性。
創(chuàng)建自定義類型的最常見方法是組合使用構(gòu)造函數(shù)模式和原型模式,構(gòu)造函數(shù)模式用于定義實例屬性,原型模式用于定義方法和共享的屬性。
function Person(name, age) { this.name = name; this.age = age; this.friends = ["Bruce", "Cindy"]; } Person.prototype = { constructor : Person, showName : function(){ alert(this.name); } }; var person1 = new Person("Alice",23); var person2 = new Person("David",22); person1.friends.push("Vincy");//包含引用值的屬性friends alert(person1.friends);//"Bruce", "Cindy","Vincy" alert(person2.friends);//"Bruce","Cindy" alert(person1.friends == person2.friends);//false alert(person1.showName == person2.showName);//true
5、動態(tài)原型模式
動態(tài)原型模式把所有信息都封裝在了構(gòu)造函數(shù)中,而通過在構(gòu)造函數(shù)中初始化原型,又保持了同時使用構(gòu)造函數(shù)和原型的優(yōu)點(diǎn)。
可以通過檢查某個應(yīng)該存在的方法是否有效,來決定是否需要初始化原型。
如:只在showName()
方法不存在的情況下,才會將它添加到原型中,這段代碼只會在初次調(diào)用構(gòu)造函數(shù)時才會執(zhí)行。
function Person(name,age) { this.name=name; this.age=age; if(typeof this.showName!="function"){ Person.prototype.showName=function(){ alert(this.name); } } } alert(person1.hasOwnProperty("name"));//true
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對大家JavaScript程序設(shè)計有所幫助。
- js 創(chuàng)建對象的多種方式與優(yōu)缺點(diǎn)小結(jié)
- 詳解js創(chuàng)建對象的幾種方式和對象方法
- javascript面向?qū)ο髣?chuàng)建對象的方式小結(jié)
- JS中的函數(shù)與對象的創(chuàng)建方式
- JavaScript創(chuàng)建對象方式總結(jié)【工廠模式、構(gòu)造函數(shù)模式、原型模式等】
- JavaScript實現(xiàn)創(chuàng)建自定義對象的常用方式總結(jié)
- JavaScript創(chuàng)建對象的七種方式全面總結(jié)
- 基于JS對象創(chuàng)建常用方式及原理分析
- JavaScript創(chuàng)建對象的七種方式(推薦)
- JS創(chuàng)建對象的四種方式
相關(guān)文章
原生JS實現(xiàn)隱藏顯示圖片 JS實現(xiàn)點(diǎn)擊切換圖片效果
這篇文章主要為大家詳細(xì)介紹了原生JS實現(xiàn)隱藏顯示圖片,JS實現(xiàn)點(diǎn)擊切換圖片效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07JavaScript嚴(yán)格模式禁用With語句的原因
看了很多遍JavaScript嚴(yán)格模式,其中有說“禁用With語句”今天禁不住想知道為何“嚴(yán)格模式”就容不下with語句呢,如果你也表示疑惑可以看看哦2014-10-10js中實現(xiàn)字符串和數(shù)組的相互轉(zhuǎn)化詳解
這篇文章主要介紹了js中實現(xiàn)字符串和數(shù)組的相互轉(zhuǎn)化,感興趣的小伙伴們可以參考一下2016-01-01查找頁面中所有類為test的結(jié)點(diǎn)的方法
這篇文章主要介紹了查找頁面中所有類為test結(jié)點(diǎn)的方法,需要的朋友可以參考下2014-03-03JS匿名函數(shù)和匿名自執(zhí)行函數(shù)概念與用法分析
這篇文章主要介紹了JS匿名函數(shù)和匿名自執(zhí)行函數(shù)概念與用法,結(jié)合實例形式分析了匿名函數(shù)和匿名自執(zhí)行函數(shù)的概念、功能、應(yīng)用場景及相關(guān)使用技巧,需要的朋友可以參考下2018-03-03前端js實現(xiàn)文件的斷點(diǎn)續(xù)傳 后端PHP文件接收
這篇文章主要為大家詳細(xì)介紹了斷點(diǎn)續(xù)傳的簡單例子,前端文件提交,后端PHP文件接收,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10