一、工厂模式

  工厂模式解决了创建多个相似对象的问题,但没有解决对象识别的问题(即怎样知道一个对象的类型)。

 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高级程序设计》

 

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!

相关课程