第一种模式,工厂模式:是用函数来封装以特定接口创建对象的细节。、
优点:解决了创建多个对象相似的问题
缺点:没有解决对象的识别问题(即怎样知道一个对象的类型)
1 function creatPerson(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 console.log(this.name); 8 }; 9 return o; 10 } 11 12 var person1 = creatPerson("jiangjie",20,"student"); 13 var person2 = creatPerson("lukexin",20,"student");
第二种模式,构造函数模式:
优点:解决了工厂模式不能识别对象的问题
缺点:每个方法都要在每个实例上重建一遍
1 function Person(name,age,job){//构造器 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 this.sayName = function(){ 6 console.log(this.name); 7 } 8 } 9 var person1 = new Person('jiangjie',20,'student'); 10 var person2 = new Person('likexin',20,'student');
第三种模式,原型模式:原型模式的知识点是最多的,通过代码先简单的介绍两个
1 function Person(){} 2 3 Person.prototype.name = "jiangjie"; 4 Person.prototype.age = 20; 5 Person.prototype.job = "student"; 6 Person.prototype.sayName = function(){ 7 console.log(this.name); 8 } 9 10 var person1 = new Person(); 11 var person2 = new Person(); 12 13 person1.name = "lukexin"; 14 console.log(person1.name);//lulexin 来自实例 15 console.log(person2.name);//jiangjie 来自原型 16 17 delete person1.name; 18 console.log(person1.name);//jiangjie 来自原型
当需要某个属性时,搜索会从实例本身开始,如果在实例中找到了这个属性,那么搜索结束,如果没有找到,会继续搜索指针指向的原型,在原型中搜索该属性;上方代码形象的解释了这个问题;
1 function Person(){} 2 3 Person.prototype = { 4 name:"jiangjie", 5 age:20, 6 job:"student", 7 sayName:function(){ 8 console.log(this.name); 9 } 10 }; 11 12 Object.defineProperty(Person.prototype,'constructor',{ 13 enumerable:false, 14 value:Person 15 }); 16 17 var person1 = new Person();
3到9行介绍了一种更加简单的原型语法,但是也产生了很多问题,这样的语法等于把Person.prototype设置为一个以字面量形式保存的新对象,这时他的constructor是指向了Object(这是因为用一个对象给原型赋值导致的!),如果想让constructor指向当初的构造器,就要手动改constructor属性,上方代码给出的方法是使用了object.defineProperty方法,当然还可以在字面对象中加上一条 constructor=Person解决,但是如果这样的话,会导致constructor属性的enumerable的值被设为true,也就是可以被for-in 枚举,但是通过上方的方法可以设定为不能枚举。
第四种模式,构造函数和原型模式,也是最常见的模式,构造函数模式用于定义实例属性,原型模式用于定义方法属性,这样就可以随自己所想,设定哪些东西是共享的,那些东西是自己独立的
1 function Person(name,age,job){ 2 this.name = name, 3 this.age = age, 4 this.job = job, 5 this.friend = ["zz","xx"]; 6 } 7 8 Person.prototype = { 9 sayName : function(){ 10 console.log(this.name); 11 } 12 } 13 14 Object.defineProperty(Person.prototype,"constructor",{ 15 enumerable:false, 16 value:Person 17 }); 18 19 var person1 = new Person('jaingjie',20,'student'); 20 var person2 = new Person('lukexin',20,'student');
第五种模式,动态原型模式:继承了构造函数和原型模式的优点,而且写法简单
1 function Person(name,age,job){ 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 if(typeof this.sayName != "function"){ 6 Person.prototype.sayName = function(){ 7 console.log(this.name); 8 }; 9 } 10 } 11 12 var person = new Person("jiangjie",20,"student");
第六种模式,寄生构造器模式:书中给出了需要使用这种模式的例子,首先给出这种模式的形式:
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 console.log(this.name); 8 }; 9 return o; 10 } 11 12 var person = new Person("jiangjie",20,"student");
看起来非常像工厂模式,但是多了new;
下面是使用的例子:
1 function SpecialArray(){ 2 var values = new Array(); 3 values.push.apply(values,arguments); 4 values.toPidString = function(){ 5 return this.join('|'); 6 }; 7 return values; 8 } 9 10 var color = new SpecialArray('red','green','gray');
第七种模式,稳妥构造函数模式,为了防止数据被其他应用程序改动时使用,总之是为了安全吧
1 function Person(name,age,job){ 2 var o = new Object(); 3 4 //在这定义私有变量或者函数 5 6 o.sayName = function(){ 7 console.log(o.name); 8 }; 9 return o; 10 } 11 12 var person = Person("jiangjie",20,"student");