Objec构造函数
通过Object构造函数创建对象是最简单的方法。
var person = new Object();
person.name = "Jack";
person.age = 29;
person.sayName = function(){
alert(this.name);
};
对象字面量
对象字面量成为创建这种对象的首选模式。
var person = {
name:"Mike",
age:29,
sayName:function() {
alert(this.name);
}
};
以上两种方法的缺点
使用同一个接口创建很多对象,会产生大量的重复代码。
工厂方法
因为ECMAScript无法创建类,所以就用函数来封装以特定接口对象的细节。
function createPerson(name, age){
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPerson("Nicholas", 29);
var person2 = createPerson("Greg", 27);
工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。
构造函数模式
可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。
function Person(name, age){
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person("Nicholas", 29);
var person2 = new Person("Greg", 27);
要创建 Person 的新实例,必须使用 new 操作符。以这种方式调用构造函数实际上会经历以下 4个步骤:
- 创建一个新对象;
- 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);
- 执行构造函数中的代码(为这个新对象添加属性);
- 返回新对象。
之前创建的自定义的构造函数,可以通过下列任何一种方式来调用:
// 当作构造函数使用
var person = new Person("Nicholas", 29);
person.sayName(); //"Nicholas"
// 作为普通函数调用
Person("Greg", 27); // 添加到 window
window.sayName(); //"Greg"
// 在另一个对象的作用域中调用
var o = new Object();
Person.call(o, "Kristen", 25);
o.sayName(); //"Kristen"
当作为普通函数调用时,其属性和方法就被添加到windows对象上,所以就需要windows来调用。
构造函数主要缺点就是每个方法都要在实例上重新创建一遍。
上面构造函数中函数与this.sayName= new function("alert (this.name)");
等价。以这种方式创建函数,会导致不同的作用域链和标识符解析,但创建 Function 新实例的机制仍然是相同的。因此,不同实例上的同名函数是不相等的。
alert(person1.sayName == person2.say