1. 工厂模式

2. 构造函数模式

3. 原型模式

4. 混合构造函数和原型模式

5. 动态原型模式

6. 寄生构造函数模式

7. 稳妥构造函数模式

普通模式

var obj=new Object();
   obj.name="罗桂鑫";
   obj.age=18;
   obj.run=function(){
   return this.name+"+"+this.age+"+"+"100";
   }
   alert(obj.run());

 

 

一。工厂模式

为了解决多个类似对象声明的问题,我们可以使用一种叫做工厂模式的方法,这种方法就是为了解决实例化对象产生大量重复的问题。

function show(name,age){
			  var obj=new Object();
			  obj.name=name;
			  obj.age=age;
			  obj.run=function(){
			  	return this.name+"+"+this.age+"+"+"100";
			  };
			  return obj;
			};
			var box1=show("罗桂鑫",18);
			var box2=show("罗桂鑫",20);
			alert(box1.run());
			alert(box2.run());
			alert(box1.instanceof Object);
			alert(box1.instanceof Object);//不管怎样,他们都是Object类型,返回都是true.

问题:工厂模式解决了重复实例化的问题,但还有一个问题,就是识别问题,因为根本无法搞清楚他们到底是哪个对象的实例。

二。构造函数模型

使用构造函数的方法,即解决了重复实例化的问题,又解决了对象识别的问题,但问题
是,这里并没有 new Object(),为什么可以实例化 Box(),这个是哪里来的呢?
使用了构造函数的方法,和使用工厂模式的方法他们不同之处如下:
1.构造函数方法没有显示的创建对象(new Object());
2.直接将属性和方法赋值给 this 对象;
3.没有 renturn 语句。
构造函数的方法有一些规范:
1.函数名和实例化构造名相同且大写,(PS:非强制,但这么写有助于区分构造函数和
普通函数);
2.通过构造函数创建对象,必须使用 new 运算符。

function Show(name,age){
        	this.name=name;
        	this.age=age;
        	this.run=function(){
        		return this.name+"+"+this.age+"+"+"100";
        	};
        }
        function Show2(name,age){
        	this.name=name;
        	this.age=age;
        	this.run=function(){
        		return this.name+"+"+this.age+"+"+"100";
        	};
        }
        var box1=new Show("罗桂鑫",18);//实例化
        var box2=new Show2("罗桂鑫",18);//实例化var box3=new Show2("罗桂鑫",18);//实例化
//      alert(box1.run());
//      alert(box2.run());
//      alert(box1 instanceof Show);//true
//      alert(box3 instanceof Show);//false   因为box2是Show2对象的引用,所以返回false
//      alert(box1.run()==box2.run());//true  //值相同
//       alert(box1.run==box2.run); //false   //引用地址不同

		 function Show(name,age){
        	this.name=name;
        	this.age=age;
        	this.run=run;  
       };
       function run(){         //把构造函数内部的方法通过全局来实现引用地址一致,但是外部也可以调用。所以不推荐
        		return this.name+"+"+this.age+"+"+"100";
        	};
        var box1=new Show("罗桂鑫",18);//实例化
        var box2=new Show("罗桂鑫",18);//实例化
        alert(box1.run==box2.run);//true-----------对象冒充的两种方法 
			function Show(name,age){
				this.name=name;
				this.age=age;
				this.run=function(){
					return this.name+this.age+"+"+"100";
				};
			}
		    var box1=new Show("罗桂鑫",18);//实例化
			alert(box1.run());
			var obj=new Object();
			Show.call(obj,"lee",100);  //使用call对象冒充
			alert(obj.run());
			Show.apply(obj,["tin",100]);  //使用apply对象冒充
			alert(obj.run());

三。原型模型

创建的每个函数都有一个 prototype(原型)属性,这个属性是一个对象,它的用途是
包含可以由特定类型的所有实例共享的属性和方法。逻辑上可以这么理解:prototype 通过
调用构造函数而创建的那个对象的原型对象。使用原型的好处可以让所有对象实例共享它所
包含的属性和方法。也就是说,不必在构造函数中定义对象信息,而是可以直接将这些信息
添加到原型中。

原型模式的执行流程:
1.先查找构造函数实例里的属性或方法,如果有,立刻返回,实例属性不会共享;
2.如果构造函数实例里没有,则去它的原型对象里找,如果有,就返回;

function box(){
     }
     box.prototype.name="罗桂鑫";
     box.prototype.age=18;
     box.prototype.run=function(){
     	return this.name+"+"+this.age+"+"+"100";
     };
     var box1=new box();
     var box2=new box();
     alert(box1.run()); 
     alert(box1.run==box2.run);//true
     //如果是实例方法,不同的 实例化,他们的方法地址是不一样的
     //如果是原型方法,地址是共享的

    // 判断一个对象是否指向了该构造函数的原型对象,可以使用 isPrototypeOf()方法来测试。
     alert(box.prototype.isPrototypeOf(box1)); //只要实例化对象,即都会指向   
     alert(box1.hasOwnProperty("name"));//判断实例中是否存在制定属性
	 alert("name" in box1); //无论该属性存在于实例中还是原型中。只要存在就返回true

	 function isProperty(object, property) { //判断原型中是否存在属性
		return !object.hasOwnProperty(property) && (property in object);
		}
	  alert(isProperty(box1, 'name'));

 

字面量创建的方式使用 constructor 属性不会指向实例,而会指向 Object,构造函数创建
的方式则相反。

function Box(){}
//使用字面量的方式创建原型对象,这里{}就是对象,是Object,new Object就相当于{}
Box.prototype={
constructor:Box, //强制指向Box
name:'lee',
age:100,
run:function(){
return this.name+this.age+"运行中...";
}
};

//重写了原型对象
Box.prototype={
age:200 //这里不会保留之前原型的任何信息了,把原来的原型对象和构造函数对象实例之前的关系切断了
};
var box=new Box();
alert(box.name);
alert(box.constructor==Box); //true

原型模式创建对象也有自己的缺点,它省略了构造函数传参初始化这一过程,带来的缺
点就是初始化的值都是一致的。而原型最大的缺点就是它最大的优点,那就是共享。