一、工廠模式 工廠模式解決了創建多個相似對象的問題,但沒有解決對象識別的問題(即怎樣知道一個對象的類型)。 二、構造函數模式 主要是利用構造函數創建對象,缺點是當需要定義很多方法是,就要定義很多全局函數,那自定義的引用類型就絲毫沒有封裝性可言了。 三、原型模式 使用原型對象的好處是可以讓所以對象實例 ...
一、工廠模式
工廠模式解決了創建多個相似對象的問題,但沒有解決對象識別的問題(即怎樣知道一個對象的類型)。
1 //工廠模式創建對象
2 function createPerson(name , age , job){
3 var o = new Object();
4 o.name = name;
5 o.job = job;
6 o.sayName = function(){
7 alert(this.name);
8 }
9 return o;
10 }
11 var person2 = new createPerson("Lily" , 21 , "Worker");
12 var person3 = new createPerson("Lulu" , 21 , "Student");
13 person2.sayName();//Lily
14 person3.sayName();//Lulu
二、構造函數模式
主要是利用構造函數創建對象,缺點是當需要定義很多方法是,就要定義很多全局函數,那自定義的引用類型就絲毫沒有封裝性可言了。
1 //構造函數模式創建對象
2 function Person(name , age , job) {
3 this.name = name;
4 this.age = age;
5 this.job = job;
6 this.sayName = sayName;//為了避免創建兩個完全同樣任務的Function實例
7 }
8 function sayName(){
9 alert(this.name);
10 }
11 var person2 = new Person("Lily" , 21 , "Worker");
12 var person3 = new Person("Lulu" , 21 , "Student");
13 person2.sayName();//Lily
14 person3.sayName();//Lulu
三、原型模式
使用原型對象的好處是可以讓所以對象實例共用它所包含的屬性和方法。
1 //原型模式創建對象
2 function Person() {
3 }
4 Person.prototype.name = "Lily";
5 Person.prototype.age = 21;
6 Person.prototype.job = "Student";
7 Person.prototype.sayName = function(){
8 alert(this.name);
9 }
10 var person2 = new Person();
11 var person3 = new Person();
12
13 person2.name = "Lulu";
14 alert(person2.name); //Lulu -- 來自實例
15 alert(person3.name); //Lily --來自原型
16 delete person2.name;
17 alert(person2.name); //Lily --來自原型
更簡單的原型語法:
1 function Person(){
2 }
3 Person.prototype = {
4 constructor: Person ,name: "lily",
5 age: 22,
6 job: "Student",
7 sayName: function(){
8 alert(this.name);
9 }
10 };
註:重寫原型對象切斷了現有原型與任何之前已經存在的對象實例之間的聯繫。
儘管原型模式看似完美,但對於引用類型值的屬性來說,問題就比較突出了,如:
1 function Person() {
2 }
3 Person.prototype.name = "Lily";
4 Person.prototype.age = 21;
5 Person.prototype.job = "Student";
6 Person.prototype.friends = ["a" , "b"];
7 Person.prototype.sayName = function(){
8 alert(this.name);
9 };
10 var person2 = new Person();
11 var person3 = new Person();
12
13 person2.friends.push("c");
14 alert(person2.friends); //a,b,c
15 alert(person3.friends); //a,b,c
問題很明顯,實例一般都是要有屬於自己的全部屬性的,但上面的結果很明顯就出現問題了。如果初衷是所有實例共用一個數組時,那這個問題便不存在了。要解決這個問題,可以利用以下的方法,即組合使用構造函數模式與原型模式。
1 function Person(name , age , job){
2 this.name = name;
3 this.age = age;
4 this.job = job;
5 this.friends = ["a" , "b"];
6 }
7 Person.prototype = {
8 constructor:Person,
9 sayName: function(){
10 alert(this.name);
11 }
12 }
13
14 var person2 = new Person("lily" , 21 , "Student");
15 var person3 = new Person("suda" , 21 , "Student");
16 person2.friends.push("c");
17 alert(person2.friends); //a,b,c
18 alert(person3.friends); //a,b
19 alert(person3.friends == person2.friends); //false
20 alert(person3.sayName == person2.sayName); //true
還有兩種模式,分別是寄生構造函數模式和穩妥構造模式,不是很常用,所以就不講了。
參考《JavaScript高級程式設計》