1.Object 模式
var o1 = {};//字面量的表现形式
var o2 = new Object;
2.工厂模式
function createCar(name,age){
var oTemp = new Object();
oTemp.name = name;//直接给对象添加属性,每个对象都有直接的属性
oTemp.age = age;
oTemp.showName = function () {
alert(this.name);
};//每个对象都有一个 showName 方法版本
return oTemp;
}
createCar("tom").showName();
减少了重复代码,但是不能够识别对象,所有实例都是object类型的。
3.构造器模式
function Car(sColor,iDoors){ //声明为构造器时需要将函数名首字母大写
this.color = sColor; //构造器内直接声明属性
this.doors = iDoors;
this.showColor = function(){
return this.color;
};//每个 Car 对象都有自己的 showColor方法版本
this.showDoor = function () {
return this.doors;
}
}
每个方法在每个实例上都要重新实现一遍,一是耗资源,二是创建两个或者多个完成同样任务的Function没有必要,三是有this在,没必要在代码执行前就把函数绑定到特定对象上。
4.prototype模式
function Person(){}
Person.prototype.name="lxy";
Person.prototype.age=22;
Person.prototype.job="Software Engineer";
Person.prototype.sayName=function(){
alert(this.name);
}
var lxy=new Person();
lxy.sayName();
原型也有它本身的问题,共享的属性值如果是引用类型,一个实例对该属性的修改会影响到其他实例。
5.构造器方式与原型方式的混合模式
//每个对象有专属的属性不会与其他对象共享
function Car(sColor,iDoors){
this._color = sColor;//私有属性变量名称头加下划线标识
this._doors = iDoors;
this.drivers = new Array("Mike","John");//公有属性标识
}
//所有对象共享一个方法版本,减少内存浪费
Car.prototype.showColor = function () {
alert(this._color);
};
var car = new Car("red",4);
这种构造函数与原型混合模式,是目前使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。其实原型就是为构造函数服务的,配合它来创建对象,想要只通过原型一劳永逸的创建对象是不可取的,因为它只管创建共享的属性和方法,剩下的就交给构造函数来完成。
6.动态原型模式
function Car(sColor,iDoors,iMpg){
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
//使用标志(_initialized)来判断是否已给原型赋予了任何方法,保证方法永远只被创建并赋值一次
if(typeof Car._initialized == "undefined"){//因为这里的标记是附加在类上,故如果后期直接对其进行修改,还是有可能出现再次创建的情况
Car.prototype.showColor = function () {//为Car添加一个存放在 prototype 域的方法
alert(this.color);
};
Car._initialized = true;//设置一个静态属性
}
}
var car = new Car("red",3,25);
使用动态原型时,不能使用对象字面量重写原型。如果在已经创建了实例的情况下重写原型,那么就会切断现有实例与新原型之间的联系。
7.混合工厂模式
function Car(){
var oTempCar = new Object;
oTempCar.color = "blue";
oTempCar.doors = 4;
oTempCar.showColor = function () {
alert(this.color);
};
return oTempCar;
}
var car = new Car();
由于在 Car6()构造函数内部调用了 new 运算符,所以将忽略第二个 new 运算符(位于构造函数之外),
附:new操作符具体干了什么呢?
1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。
//等价于下面代码
var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);