1. 程式人生 > >JavaScript中創建對象的幾種模式

JavaScript中創建對象的幾種模式

-c aps lang mage pen lin round property mar

代碼如下:

技術分享圖片
  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>創建對象的模式</title>
  6     <meta name="viewport" content="width=device-width, initial-scale=1">
  7     <!--<link rel="stylesheet" type="text/css" href="main.css"/>
--> 8 <!--<script src="main.js"></script>--> 9 </head> 10 <body> 11 <script> 12 //js中沒有類的概念,所以開發人員使用函數來封裝特定接口從而創建對象 13 //1.工廠模式,解決了創建多個相似對象的問題,但是沒有解決對象識別問題 14 function t1(name,age,sex){ 15 var o={}; 16 o.name=name; 17 o.age
=age; 18 o.sex=sex; 19 return o; 20 }; 21 var p1=t1(張三,21,male); 22 var p2=t1(Alice,23,female); 23 console.log(p1,p2); 24 console.log(typeof p1,typeof p2); 25 26 // 2.構造函數模式 27 function T2(name,age,sex){ 28 this.name=name; 29 this
.age=age; 30 this.sex=sex; 31 this.showInfo=function(){ 32 console.log(this.name+ +this.age+ +this.sex); 33 } 34 } 35 var p3=new T2(李四,25,male); 36 var p4=new T2(Mary,22,female); 37 //此時對象的constructor是用來標識對象類型的 38 console.log(p3,p4,p3.constructor===T2,p4.constructor===T2); 39 console.log(p3 instanceof Object,p3 instanceof T2); 40 41 //如果將構造函數作為普通函數調用,那麽屬性和方法都被添加到全局對象,這裏是window 42 T2(ww,29,male); 43 console.log(window.name,age,sex); 44 45 // 構造函數模式存在的缺陷:構造函數裏面的方法(上面指showInfo)不是共享的,即每次的showInfo不相同 46 console.log(p3.showInfo===p4.showInfo); 47 48 // 3.原型模式 49 function T3(){ 50 } 51 T3.prototype.name=Aya; 52 T3.prototype.age=100; 53 T3.prototype.showInfo=function(){ 54 console.log(this.name); 55 }; 56 57 var p5=new T3(); 58 p5.showInfo(); 59 var p6=new T3(); 60 p6.showInfo(); 61 console.log(p5.showInfo===p6.showInfo); 62 // 實例中的屬性或方法會覆蓋原型中的屬性或方法 63 p5.name=xiaoming; 64 p5.showInfo(); 65 delete p5.name; 66 p5.showInfo(); 67 // js引擎對屬性的尋找都是從下往上追溯的 68 69 // 使用hasOwnProperty()可以檢測屬性在實例上,還是在原型上 70 p6.name=nicai; 71 console.log(p6.hasOwnProperty(name)); 72 // 使用in,屬性在原型上或者實例上,均返回true 73 console.log(name in p5,name in p6); 74 75 // 所以當hasOwnProperty()返回false,而in返回true,那麽屬性位於原型上 76 if (!p5.hasOwnProperty(name) && name in p5){ 77 console.log(name屬性在原型上); 78 } 79 80 // 原型模式更直觀的可以寫為下面形式: 81 function T4(){} 82 T4.prototype={ 83 name:abc, 84 age:100, 85 sayHi:function(){ 86 console.log(this.name); 87 } 88 } 89 // 原型模式存在的問題:1.所有屬性初始值一樣;2.最大的問題,當含有引用類型時,一個實例對象的修改會導致其它實例對象也跟著修改 90 function T5(){} 91 T5.prototype={ 92 constructor:T5, 93 name:abc, 94 age:100, 95 arr:[1,2,3] 96 } 97 var p7=new T5(); 98 var p8=new T5(); 99 //所有實例對象的引用類型會相應變化 100 p7.arr.unshift(0); 101 //實例對象的基本類型倒不影響 102 p7.name=Bob; 103 console.log(p7.arr,p8.arr,p7.name,p8.name); 104 105 // 4.組合使用構造函數模式與原型模式 106 // 是目前在ECMAScript使用最廣泛、認可度最高的一種創建自定義類型的方法 107 function Person(name,age){ 108 this.name=name; 109 this.age=age; 110 this.friends=[Alice,Bob]; 111 } 112 Person.prototype={ 113 constructor:Person, 114 sayHello:function(){ 115 console.log(this.name); 116 } 117 118 }; 119 var per1=new Person(Apple,1000); 120 var per2=new Person(Blue,10); 121 per1.friends.push(cat); 122 console.log(per1.friends,per2.friends); 123 console.log(per1.sayHello===per2.sayHello); 124 125 // 5.動態原型模式 126 function Person1(name,age){ 127 this.name=name; 128 this.age=age; 129 if(typeof this.sayHello !== function){ 130 Person1.prototype.sayHello=function(){ 131 console.log(this.name); 132 } 133 } 134 } 135 var per3=new Person1(Bill,111); 136 console.log(per3); 137 138 // 6.寄生(parasitic)構造函數模式 139 // 其實與工廠模式一樣,除了使用構造函數和new操作符 140 function Person2(name,age){ 141 var o={}; 142 o.name=name; 143 o.age=age; 144 return o; 145 } 146 var per4=new Person2(Egg,100); 147 148 // 7.穩妥(durable)構造函數 149 // 與寄生構造函數模式類似,但兩處不同點:1.新創建對象的實例方法不使用this 2.不使用new 調用構造函數 150 // 穩妥構造函數適合在某些安全環境下 151 function Test3(age){ 152 var o={}; 153 o.showName=function(){ 154 console.log(age); 155 }; 156 return o; 157 } 158 var per5=Test3(100); 159 console.log(per5); 160 </script> 161 </body> 162 </html>
View Code

運行結果:

技術分享圖片

參考<<JavaScript高級程序語言設計>>

JavaScript中創建對象的幾種模式