1、字面量方式
var obj = {
name : 'tom',
age : 20,
career : 'network',
getName : function (){
return this.name;
}
}
alert(obj.getName());
这种方式适合创建单个对象。
2、创建Object对象方式
var obj = new Ojbect();
obj.name='tom';
obj.age=20;
obj.getName=function(){
return obj.name;
}
}
alert(obj.getName());
跟第一种方式差不多,只能创建单个对象。
3、工厂模式
function createPerson(){
var per = new Object();
per.name='tom';
per.age=25;
per.getName = function(){
return this.age;
};
return per;
}
var person = createPerson();
var person1 = createPerson();
alert(person.getName()); //tom
无法识别对象类型,因为所有对象都是通过Object()创建的,类型均为Object。而且创建多个对象时会重复创建对象方法:
alert(person.getName == person1.getName) // false
4、构造方法
function Person(name,age){
var nametemp = 'tom';
var agetemp = 10;
this.name = name || nametemp;
this.age = age || agetemp;
this.getName = function(){
return this.name;
}
}
var p1 = new Person();
var p2 = new Person('Mike',13);
p1.getName(); //tom
p2.getName(); //Mike
优点:可以通过传入参数初始化对象。而且这样创建的对象有一个constructor属性,指向创建它的构造函数。
alert(p1.constructor == Person); // true;
也可以用instanceof 运算符来验证这种关系
alert(p1 instanceof Person); //true
缺点:重复创建对象方法,每次创建一个对象时,都会重复创建它的getName方法,造成一定的内存浪费。
alert(p1.getName==p2.getName); //false
5、原型模式
function person(){}
person.prototype.name='tom';
person.prototype.age=10;
person.prototype.family = ['father','mother'];
person.prototype.getName=function(){
return this.name;
}
var p1 = new person();
p1.family.push('brother');
var p2 = new person();
alert(p1.family);
alert(p2.family);
优点:属性是方法时可以被多个对象共享,不需要重复创建方法
alert(p1.getName==p2.getName); //true
缺点:当属性是一个对象时,因为共享容易出现问题。例如上例中,p1中给family属性添加了brother成员,但因为对象共享,p2中的family成员也被添加了brother。
6、混合模式(推荐使用)
function Person(name,age){
var nametemp = 'tom';
var agetemp = 10;
this.name = name || nametemp;
this.age = age || agetemp;
}
Person.prototype.getName=function(){
return this.name;
}
var p1 = new Person();
var p2 = new Person('Jack',20);
这种方式综合了构造函数方式和原型模式两种创建方法的优点。既可以保持各个对象非函数属性的独立性,又可以共享函数属性。而且可以通过构造函数参数初始化对象成员。
prototype模式的验证方法:
1、 isPrototypeOf方法验证某个原型对象是否存在于另一个对象的原型链中
alert(Person.prototype.isPrototypeOf(p1)); //true
alert(Person.prototype.isPrototypeOf(p2)); //true
2、 hasOwnProperty()判断属性是否为对象自有属性,而不是通过prototype设置的可共享属性。
alert(p1.hasOwnProperty("getName")); //false
alert(p1.hasOwnProperty("age")); //true
3、in 可用于遍历对象的所有属性,不论是通过this还是通过 prototype设置的属性
alert("name" in p1); //true
alert("getName" in p1); //true
for(var prop in p1){ //这里prop是一个字符串,代表属性名
alert(p1[prop]);
}
注意:不能直接用p1.prop来访问,prop是一个字符串,就像
可以用p1.name访问而不能用p1."name"来访问一样。
不过可以用eval(“p1.”+prop);
和p1[prop]来访问属性。这也是访问对象属性时容易出错的一点。
7、动态原型方式
function Person(name,age){
var nametemp = 'tom';
var agetemp = 10;
this.name = name || nametemp;
this.age = age || agetemp;
}
if(typeof Person.getName == "undefined"){
Person.prototype.getName=function(){
return this.name;
}
}
这样避免重复创建方法。