转自:http://www.cnblogs.com/WebYan/p/6066191.html#commentform
原始模式:
1 var Car = new Object; 2 3 Car.color = "blue"; 4 Car.door = 4; 5 Car.showColor = function() { 6 alert(this.color); 7 } 8 9 Car.showColor(); //"blue";
原理:声明对象,后续给对象加属性和方法
优点:可以直观的看出对象Car有属性 color,door,方法showcolor;
缺点:如果有多个类型,需要创建多个实例;
工厂模式:
1 function createCar() { 2 var Car = new Object; 3 4 Car.color = "blue"; 5 Car.door = 4; 6 Car.showColor = function() { 7 alert(this.color); 8 } 9 10 return Car; 11 12 } 13 14 var car1 = createCar(); 15 var car2 = createCar(); car1.showColor() //blue; car2.showColor() //blue;
原理:将原始方式封装到函数中,并返回这个对象
优点:同一类型同一属性可以重复调用;
缺点:同一类型不同属性值的不能调用;
工厂模式为函数传参:
function showColor() { alert(this.color); } function createCar(sColor, sDoor) { var Car = new Object; Car.color = sColor; Car.door = sDoor; Car.showColor = showColor; return Car; } var car1 = createCar("red","4"); var car2 = createCar("blue","6"); car1.showColor(); car2.showColor();
原理:工厂模式的升级版,为函数添加参数,方法调取外部的函数的指针
优点:解决了重复创建函数的问题;
缺点:不符合语义,看起来不像是对象的方法;
构造函数方式:
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.showColor = function() { alert(this.color); }; } var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25);
原理:在构造函数内使用 this 关键字,创建属性和方法。再使用 new 运算符创建实例,通过传参生成不同的实例
优点:该方式解决了以上模式所遇到的问题;
缺点:构造函数会重复生成函数,为每个对象都创建独立的函数版本;
原型方式:
function Car() { } Car.prototype.color = "blue"; Car.prototype.doors = 4; Car.prototype.mpg = 25; Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car(); var oCar2 = new Car();
原理:创建一个构造函数,再函数外为通过prototype方式添加属性和方法,最后通过new 运算符生成实例
优点:语义上,看起来所有属性都是同一个对象,解决了上两种方式所遇到的问题;
缺点:不能通过给构造函数传递参数来初始化属性的值,而且如果其中某个实例属性重新赋值,会导致其他的实例同一属性也会发生变化;
function Car() { } Car.prototype.color = "blue"; Car.prototype.doors = 4; Car.prototype.mpg = 25; //指向一个对象 Car.prototype.drivers = new Array("Mike","John"); Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car(); var oCar2 = new Car(); //为oCar1新加入 oCar1.drivers.push("Bill"); alert(oCar1.drivers); //输出 "Mike,John,Bill" alert(oCar2.drivers); //输出 "Mike,John,Bill"
上面的代码中,属性 drivers 是指向 Array 对象的指针,该数组中包含两个名字 "Mike" 和 "John"。由于 drivers 是引用值,Car 的两个实例都指向同一个数组。这意味着给 oCar1.drivers 添加值 "Bill",在 oCar2.drivers 中也能看到。输出这两个指针中的任何一个,结果都是显示字符串 "Mike,John,Bill"。
混合的构造函数/原型方式:
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.drivers = new Array("Mike","John"); } Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25); oCar1.drivers.push("Bill"); alert(oCar1.drivers); //输出 "Mike,John,Bill" alert(oCar2.drivers); //输出 "Mike,John"
原理:利用构造函数方式创建函数的不同的部分,利用原型方式来定义相同的方法和属性
优点:此种 方式即符合语义又可以扩展新的属性和方法