亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > JavaScript > 正文

跟我學習javascript創建對象(類)的8種方法

2024-05-06 16:25:10
字體:
來源:轉載
供稿:網友

跟我學習javascript創建對象(類)的8種方法,每一種方法都有詳細的介紹,不知道javascript如何創建對象的朋友,不要錯過這篇文章。

8中javascript創建對象(類)的方法,依依介紹給大家,希望大家喜歡。

1. 使用Object構造函數來創建一個對象

下面代碼創建了一個person對象,并用兩種方式打印出了Name的屬性值。

 

 
  1. var person = new Object(); 
  2. person.name="kevin"
  3. person.age=31; 
  4. alert(person.name); 
  5. alert(person["name"]) 

上述寫法的另外一種表現形式是使用對象字面量創建一個對象,不要奇怪person[“5”],這里是合法的;另外使用這種加括號的方式字段之間是可以有空格的如person[“my age”].

 

  1. var person =  
  2. name:"Kevin"
  3. age:31, 
  4. 5:"Test" 
  5. }; 
  6. alert(person.name); 
  7. alert(person["5"]); 

雖然Object 構造函數或對象字面量都可以用來創建單個對象,但這些方式有個明顯的缺點:使用同一個接口創建很多對象,會產生大量的重復代碼。為解決這個問題,人們開始使用工廠模式的一種變體。

2、工廠模式

工廠模式是軟件工程領域一種廣為人知的設計模式,這種模式抽象了創建具體對象的過程,考慮到在ECMAScript 中無法創建類,開發人員就發明了一種函數,用函數來封裝以特定接口創建對象的細節,如下面的例子所示。

 

 
  1. function createPerson(name, age, job){ 
  2. var o = new Object(); 
  3. o.name = name; 
  4. o.age = age; 
  5. o.job = job; 
  6. o.sayName = function(){ 
  7. alert(this.name); 
  8. }; 
  9. return o; 
  10. var person1 = createPerson("Nicholas", 29, "Software Engineer"); 
  11. var person2 = createPerson("Greg", 27, "Doctor"); 

工廠模式雖然解決了創建多個相似對象的問題,但卻沒有解決對象識別的問題(即怎樣知道一個對象的類型)。隨著JavaScript

的發展,又一個新模式出現了。

3. 構造函數模式

像Object 和Array 這樣構造函數,在運行時會自動出現在執行環境中。此外,也可以創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。例如,可以使用構造函數模式將前面的例子重寫如下。

 

 
  1. function Person(name, age, job){ 
  2. this.name = name; 
  3. this.age = age; 
  4. this.job = job; 
  5. this.sayName = function(){ 
  6. alert(this.name); 
  7. }; 
  8. var person1 = new Person("Nicholas", 29, "Software Engineer"); 
  9. var person2 = new Person("Greg", 27, "Doctor"); 

在這個例子中,Person()函數取代了createPerson()函數。我們注意到,Person()中的代碼除了與createPerson()中相同的部分外,還存在以下不同之處:

沒有顯式地創建對象;

直接將屬性和方法賦給了this 對象;

沒有return 語句。

4個步驟:

要創建Person 的新實例,必須使用new 操作符。以這種方式調用構造函數實際上會經歷以下

(1) 創建一個新對象;

(2) 將構造函數的作用域賦給新對象(因此this 就指向了這個新對象);

(3) 執行構造函數中的代碼(為這個新對象添加屬性);

(4) 返回新對象。

在前面例子的最后,person1 和person2 分別保存著Person 的一個不同的實例。這兩個對象都有一個constructor(構造函數)屬性,該屬性指向Person,如下所示。

 

 
  1. alert(person1.constructor == Person); //true 
  2. alert(person2.constructor == Person); //true 

對象的constructor 屬性最初是用來標識對象類型的。但是,提到檢測對象類型,還是instanceof操作符要更可靠一些。我們在這個例子中創建的所有對象既是Object 的實例,同時也是Person的實例,這一點通過instanceof 操作符可以得到驗證。

 

 
  1. alert(person1 instanceof Object); //true 
  2. alert(person1 instanceof Person); //true 
  3. alert(person2 instanceof Object); //true 
  4. alert(person2 instanceof Person); //true 

創建自定義的構造函數意味著將來可以將它的實例標識為一種特定的類型;而這正是構造函數模式勝過工廠模式的地方。在這個例子中,person1 和person2 之所以同時是Object 的實例,是因為所有對象均繼承自Object。

構造函數的問題

構造函數模式雖然好用,但也并非沒有缺點。使用構造函數的主要問題,就是每個方法都要在每個實例上重新創建一遍。

ECMAScript 中的函數是對象,因此每定義一個函數,也就是實例化了一個對象。從邏輯角度講,此時的構造函數也可以這樣定義。

 

 
  1. function Person(name, age, job){ 
  2. this.name = name; 
  3. this.age = age; 
  4. this.job = job; 
  5. this.sayName = new Function("alert(this.name)"); // 與聲明函數在邏輯上是等價的 

從這個角度上來看構造函數,更容易明白每個Person 實例都包含一個不同的Function 實例(以顯示name 屬性)的本質。說明白些,以這種方式創建函數,會導致不同的作用域鏈和標識符解析,但創建Function 新實例的機制仍然是相同的。因此,不同實例上的同名函數是不相等的,以下代碼可以證明這一點。

 

 
  1. alert(person1.sayName == person2.sayName); //false 

然而,創建兩個完成同樣任務的Function 實例的確沒有必要;況且有this 對象在,根本不用在執行代碼前就把函數綁定到特定對象上面。因此,大可像下面這樣,通過把函數定義轉移到構造函數外部來解決這個問題。

 

 
  1. function Person(name, age, job){ 
  2. this.name = name; 
  3. this.age = age; 
  4. this.job = job; 
  5. this.sayName = sayName; 
  6. function sayName(){ 
  7. alert(this.name); 
  8. var person1 = new Person("Nicholas", 29, "Software Engineer"); 
  9. var person2 = new Person("Greg", 27, "Doctor"); 

如果對象需要定義很多方法,那么就要定義很多個全局函數,于是我們這個自定義的引用類型就絲毫沒有封裝性可言了。好在,這些問題可以通過使用原型模式來解決。

4、原型模式

 

 
  1. function Person(){ 
  2. Person.prototype.name = "Nicholas"
  3. Person.prototype.age = 29; 
  4. Person.prototype.job = "Software Engineer"
  5. Person.prototype.sayName = function(){ 
  6. alert(this.name); 
  7. }; 
  8. var person1 = new Person(); 
  9. person1.sayName(); //"Nicholas" 
  10. var person2 = new Person(); 
  11. person2.sayName(); //"Nicholas" 
  12. alert(person1.sayName == person2.sayName); //true 

要理解原型對象,可見我的另一篇博客:JavaScript prototype詳解

前面例子中每添加一個屬性和方法就要敲一遍Person.prototype。為減少不必要的輸入,也為了從視覺上更好地封裝原型的功能,更常見的做法是用一個包含所有屬性和方法的對象字面量來重寫整個原型對象,如下面的例子所示。

 

 
  1. function Person(){ 
  2. Person.prototype = { 
  3. name : "Nicholas"
  4. age : 29, 
  5. job: "Software Engineer"
  6. sayName : function () { 
  7. alert(this.name); 
  8. }; 

在上面的代碼中,我們將Person.prototype 設置為等于一個以對象字面量形式創建的新對象。最終結果相同,但有一個例外:constructor 屬性不再指向Person 了。前面曾經介紹過,每創建一個函數,就會同時創建它的prototype 對象,這個對象也會自動獲得constructor 屬性。而我們在這里使用的語法,本質上完全重寫了默認的prototype 對象,因此constructor 屬性也就變成了新對象的constructor 屬性(指向Object 構造函數),不再指向Person 函數。此時,盡管instanceof操作符還能返回正確的結果,但通過constructor 已經無法確定對象的類型了,如下所示。

 

 
  1. var friend = new Person(); 
  2. alert(friend instanceof Object); //true 
  3. alert(friend instanceof Person); //true 
  4. alert(friend.constructor == Person); //false 
  5. alert(friend.constructor == Object); //true 

在此,用instanceof 操作符測試Object 和Person 仍然返回true,但constructor 屬性則等于Object 而不等于Person 了。如果constructor 的值真的很重要,可以像下面這樣特意將它設置回適當的值。

 

 
  1. function Person(){ 
  2. Person.prototype = { 
  3. constructor : Person, 
  4. name : "Nicholas"
  5. age : 29, 
  6. job: "Software Engineer"
  7. sayName : function () { 
  8. alert(this.name); 
  9. }; 

需要注意一點就是:實例中的指針僅指向原型,而不指向構造函數。

原型對象的問題:原型模式也不是沒有缺點。首先,它省略了為構造函數傳遞初始化參數這一環節,結果所有實例在默認情況下都將取得相同的屬性值。雖然這會在某種程度上帶來一些不方便,但還不是原型的最大問題。原型模式的最大問題是由其共享的本性所導致的。

 

 
  1. function Person(){ 
  2. Person.prototype = { 
  3. constructor: Person, 
  4. name : "Nicholas"
  5. age : 29, 
  6. job : "Software Engineer"
  7. friends : ["Shelby""Court"], 
  8. sayName : function () { 
  9. alert(this.name); 
  10. }; 
  11. var person1 = new Person(); 
  12. var person2 = new Person(); 
  13. person1.friends.push("Van"); 
  14. alert(person1.friends); //"Shelby,Court,Van" 
  15. alert(person2.friends); //"Shelby,Court,Van" 
  16. alert(person1.friends === person2.friends); //true 

5、組合使用構造函數模式和原型模式(最常用)

創建自定義類型的最常見方式,就是組合使用構造函數模式與原型模式。構造函數模式用于定義實例屬性,而原型模式用于定義方法和共享的屬性。結果,每個實例都會有自己的一份實例屬性的副本,但同時又共享著對方法的引用,最大限度地節省了內存。另外,這種混成模式還支持向構造函數傳遞參數;可謂是集兩種模式之長。

 

  1. function Person(name, age, job){ 
  2. this.name = name; 
  3. this.age = age; 
  4. this.job = job; 
  5. this.friends = ["Shelby""Court"]; 
  6.  
  7. Person.prototype = { 
  8. constructor : Person, 
  9. sayName : function(){ 
  10. alert(this.name); 
  11. var person1 = new Person("Nicholas", 29, "Software Engineer"); 
  12. var person2 = new Person("Greg", 27, "Doctor"); 
  13. person1.friends.push("Van"); 
  14. alert(person1.friends); //"Shelby,Count,Van" 
  15. alert(person2.friends); //"Shelby,Count" 
  16. alert(person1.friends === person2.friends); //false 
  17. alert(person1.sayName === person2.sayName); //true 

6、動態原型模式

有其他OO 語言經驗的開發人員在看到獨立的構造函數和原型時,很可能會感到非常困惑。動態原型模式正是致力于解決這個問題的一個方案,它把所有信息都封裝在了構造函數中,而通過在構造函數中初始化原型(僅在必要的情況下),又保持了同時使用構造函數和原型的優點。換句話說,可以通過檢查某個應該存在的方法是否有效,來決定是否需要初始化原型。來看一個例子。

 

 
  1. function Person(name, age, job){ 
  2. //屬性 
  3. this.name = name; 
  4. this.age = age; 
  5. this.job = job; 
  6. //方法 
  7. --------------------------------------------- 
  8. if (typeof this.sayName != "function"){ 
  9. Person.prototype.sayName = function(){ 
  10. alert(this.name); 
  11. }; 
  12. --------------------------------------------  
  13. var friend = new Person("Nicholas", 29, "Software Engineer"); 
  14. friend.sayName(); 

7、寄生構造函數模式

通常,在前述的幾種模式都不適用的情況下,可以使用寄生(parasitic)構造函數模式。這種模式的基本思想是創建一個函數,該函數的作用僅僅是封裝創建對象的代碼,然后再返回新創建的對象;但從表面上看,這個函數又很像是典型的構造函數。下面是一個例子。

 

  1. function Person(name, age, job){ 
  2. var o = new Object(); 
  3. o.name = name; 
  4. o.age = age; 
  5. o.job = job; 
  6. o.sayName = function(){ 
  7. alert(this.name); 
  8. }; 
  9. return o; 
  10. var friend = new Person("Nicholas", 29, "Software Engineer"); 
  11. friend.sayName(); //"Nicholas" 

在這個例子中,Person 函數創建了一個新對象,并以相應的屬性和方法初始化該對象,然后又返回了這個對象。除了使用new 操作符并把使用的包裝函數叫做構造函數之外,這個模式跟工廠模式其實是一模一樣的。構造函數在不返回值的情況下,默認會返回新對象實例。

8、穩妥構造函數模式

所謂穩妥對象,指的是沒有公共屬性,而且其方法也不引用this 的對象。穩妥對象最適合在一些安全的環境中(這些環境中會禁止使用this 和new),或者在防止數據被其他應用程序(如Mashup程序)改動時使用。穩妥構造函數遵循與寄生構造函數類似的模式,但有兩點不同:一是新創建對象的實例方法不引用this;二是不使用new 操作符調用構造函數。按照穩妥構造函數的要求,可以將前面的Person 構造函數重寫如下。

 

 
  1. function Person(name, age, job){ 
  2. //創建要返回的對象 
  3. var o = new Object(); 
  4. //可以在這里定義私有變量和函數 
  5. //添加方法 
  6. o.sayName = function(){ 
  7. alert(name); 
  8. }; 
  9. //返回對象 
  10. return o; 

以上javascript創建對象(類)的8種方法大家有沒有學會,希望對大家的學習有所幫助。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲综合日韩中文字幕v在线| 韩国v欧美v日本v亚洲| 亚洲第一精品夜夜躁人人躁| 欧美日韩在线观看视频小说| 精品久久久精品| 成人国产精品色哟哟| 成人福利在线视频| 久久久久久久国产精品视频| 欧美成人精品在线播放| 亚洲精品乱码久久久久久按摩观| 韩国日本不卡在线| 亚州av一区二区| 福利一区福利二区微拍刺激| 亚洲最新av在线| 国产97在线|亚洲| 欧美日韩亚洲精品一区二区三区| 亚洲激情中文字幕| 欧洲成人午夜免费大片| 久久中文字幕在线视频| 一区二区亚洲欧洲国产日韩| 日韩av手机在线观看| 日韩精品视频在线观看网址| 日韩欧美国产视频| 久久91亚洲精品中文字幕奶水| 国产主播精品在线| 精品国内产的精品视频在线观看| 26uuu日韩精品一区二区| 亚洲精品国产精品国产自| 最新国产精品拍自在线播放| 九九久久久久久久久激情| 国产97在线|日韩| 国产日韩av在线| 欧美成人亚洲成人| 久久久久国产精品www| 国产精品精品视频一区二区三区| 久久欧美在线电影| 国产伦精品一区二区三区精品视频| 欧美一区二区三区……| 欧美精品国产精品日韩精品| 亚洲欧美一区二区激情| 韩国一区二区电影| 日韩精品在线电影| 最近中文字幕mv在线一区二区三区四区| 亚洲精品免费av| 免费91在线视频| 91久久久久久国产精品| 久久av中文字幕| 91香蕉嫩草神马影院在线观看| 成人在线免费观看视视频| 亚洲美女动态图120秒| 66m—66摸成人免费视频| 亚洲精品资源美女情侣酒店| 久久男人资源视频| 国语自产精品视频在线看| 国产亚洲aⅴaaaaaa毛片| 久久午夜a级毛片| 欧美激情第99页| 欧美日韩第一视频| 57pao国产精品一区| 69久久夜色精品国产69| 91夜夜未满十八勿入爽爽影院| 欧美一级高清免费播放| 91社影院在线观看| 精品激情国产视频| 欧美亚洲国产成人精品| 久久精品国产成人精品| 亚洲成**性毛茸茸| 日韩精品一二三四区| 2020国产精品视频| 日本免费久久高清视频| 国产精品入口夜色视频大尺度| 日本久久久久亚洲中字幕| 亚洲人成欧美中文字幕| 久久久国产一区二区三区| 日韩不卡在线观看| 国产欧美日韩精品专区| 午夜欧美不卡精品aaaaa| 国内精品久久久| 日本成人激情视频| 欧美中文字幕第一页| 丝袜美腿精品国产二区| 欧美性生交xxxxxdddd| 亚洲欧美日韩一区二区在线| 国内精品伊人久久| 精品视频在线播放色网色视频| 青青草精品毛片| 精品亚洲国产视频| 亚洲男人av电影| 亚洲第一页中文字幕| 中文字幕久热精品视频在线| 黄色一区二区在线观看| 成人精品视频99在线观看免费| 97国产一区二区精品久久呦| 久久精品视频在线| 亚洲天堂免费观看| 亚洲国模精品私拍| 久久久久久综合网天天| 国产有码一区二区| 国产精品视频999| 亚洲aⅴ男人的天堂在线观看| 欧美与欧洲交xxxx免费观看| 久久成人国产精品| 永久免费看mv网站入口亚洲| 一本色道久久综合狠狠躁篇的优点| www.亚洲免费视频| 亚洲国产精品美女| 国产成人精品在线观看| 亚洲图中文字幕| 美女精品久久久| 黑人极品videos精品欧美裸| 日韩中文字幕第一页| 国产精品成人观看视频国产奇米| 久久久久成人精品| 国产精品一二三视频| 国产精品伦子伦免费视频| 高清欧美性猛交xxxx黑人猛交| 欧美专区在线观看| 日韩经典一区二区三区| 九色精品美女在线| 亚洲性猛交xxxxwww| 欧美成人免费视频| 国产亚洲成精品久久| 欧美午夜美女看片| 国产一区二区精品丝袜| 久久九九热免费视频| 欧美日韩免费在线| 亚洲精品中文字幕有码专区| 欧美最猛性xxxxx免费| 91亚洲国产精品| 69精品小视频| 懂色aⅴ精品一区二区三区蜜月| 在线成人中文字幕| 欧美国产日韩精品| 国产一区二区黄| 国产亚洲精品久久久久久777| 久久成人综合视频| 亚洲欧美中文日韩在线| 欧美孕妇与黑人孕交| 日韩高清免费观看| 亚洲三级 欧美三级| 国产一区二区三区18| 在线视频欧美日韩精品| 欧美激情在线一区| 91精品在线观看视频| 日韩在线中文字幕| 亚洲免费精彩视频| 久久成人精品一区二区三区| 欧美精品www在线观看| 欧美成人午夜免费视在线看片| 国产精品视频一区国模私拍| 国外成人在线直播| 欧美精品videosex极品1| 91亚洲精品一区| 奇米影视亚洲狠狠色| 久久免费在线观看| 中文字幕久久亚洲| 两个人的视频www国产精品| 波霸ol色综合久久| 一区二区三区四区视频| 亚洲最大福利视频| 亚洲国产精品va在线看黑人动漫| 欧美—级a级欧美特级ar全黄| 国产99视频精品免视看7| 最近2019中文字幕一页二页|