1、使用Object或对象字面量创建对象
(1)使用Object创建对象
var cat= new Object();
cat.name = "Tom";
cat.color= "blue";
(2)对象字面量创建对象
var cat = {
name : "Tom",
color : "blue"
};
局限性:当需要创建n个同类重复对象时,需要重复代码n次。
2、工厂模式创建对象
通过普通函数将对象的创建过程封装起来,给出特定的接口来初始化对象。
function genCat (name,color){
var obj = new Object();
obj.name=name;
obj.color=color;
return obj;
}; var cat1 = genCat("Tom","blue");
function genDog (name,color){
var obj = new Object();
obj.name=name;
obj.color=color;
return obj;
}; var dog1 = genDog("Snoopy","white");
局限性:对于这种工厂方法创建出来的对象,我们无法得知对象具体属于哪一类。如上述代码中的cat1和dog1,如果使用instanceof去检测,会发现cat1和dog1都属于Object类型。而我们的初衷是希望cat1属于Cat类,dog1属于Dog类。
3、构造函数模式创建对象
function Cat (name,color){
this.name=name;
this.color=color;
this.yell=function(){
return this.name + 'mew!';
}
}; var cat1 = new Cat("Tom","blue");
function Dog (name,color){
this.name=name;
this.color=color;
this.yell=function(){
return this.name + 'bark!';
}
}; var dog1 = genDog("Snoopy","white"); alert(cat1 instanceof Cat); //true
alert(dog1 instanceof Cat); //false
alert(cat1 instanceof Dog); //false
alert(dog1 instanceof Dog); //true
通过构造函数创建出的对象如上述代码可知,解决了对象类型归属的问题,能够明确检测对象属于哪一具体类型。
局限性:通过构造函数创建对象时,当一个构造函数被实例化n次时,构造函数中的函数也被实例化了n次,如上述代码中的this.yell(),同一类型的不同对象之间并不共用同一函数,造成了内存的浪费。
4、原型模式创建对象
我们创建的每一个函数都有一个prototype属性,该属性是一个指针,该指针指向了一个对象。对于我们创建的构造函数,该对象中包含可以由所有实例共享的属性和方法。
在默认情况下,所有原型对象会自动包含一个constructor属性,该属性也是一个指针,指向prototype所在的函数。
在调用构造函数创建新的实例时,该实例的内部会自动包含一个[[Prototype]]指针属性,该指针指便指向构造函数的原型对象。
通过在构造函数原型对象中添加属性和方法就可以实现在对象间数据的共享了。
function Cat(){
}; Cat.prototype.name="Tom";
Cat.prototype.color="blue";
Cat.prototype.yell=function(){
return this.name + "mew!";
}; var cat1= new Cat();
var cat2= new Cat();
alert(cat1.yell() == cat2.yell()); //true 两者共享同一函数
局限性:原型对象实现了对象间属性的共享,但在通常情况下我们希望不同的实例拥有自己单独的属性。所以一般情况下,我们使用构造函数模型和原型模型结合使用创建对象,就可以兼得方法的共享和属性的不共享。
//每只猫有自己的名字和颜色
function Cat(name,color){
this.name = name;
this.color = color;
}; //所有的猫都共享一个yell()方法
Cat.prototype.yell=function(){
return this.name + "mew!";
}; var cat1= new Cat("Tom","blue");
var cat2= new Cat("Garfield","yellow"); alert(cat1.yell()); //Tom mew! 实例属性
alert(cat2.yell()); //Garfield mew! 实例属性 alert(cat1.yell() == cat2.yell()); //true 两者共享同一函数