《JavaScript高级程序设计》中“创建对象”的的归纳,只为方便对比而已
一、工厂模式
function createPerson(name, age, job) {
var o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function() {
alert(this.name)
}
return o
}
var person1 = createPerson("Nicholas", 29, "Software Engineer")
var person2 = createPerson("Greg", 27, "Doctor")
优点:解决了创建多个相似对象的问题
缺点:无法解决对象识别问题
二、构造函数模式
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = function() {
alert(this.name)
}
}
var person1 = new Person("Nicholas", 29, "Software Engineer")
var person2 = new Person("Greg", 27, "Doctor")
// 当作构造函数使用
var person = new Person("Greg", 27, "Doctor")
person.sayName() // Greg
// 当作普通函数调用
Person("Greg", 27, "Doctor")
window.sayName() // Greg
// 在另一个对象的作用域中调用
var o = new Object()
Person.call(o, "Kristen", 25, "Nurse")
o.sayName() // Kristen
优点:创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型
缺点:每个方法都要在每个实例上重新创建一遍
三、原型模式
function Person = {}
Person.prototype.name = "Nicholas"
Person.prototype.age = 29
Person.prototype.job ="Software Engineer"
Person.prototype.sayName = function() {
alert(this.name)
}
var person1 = new Person()
person1.sayName() // Nicholas
var person2 = new Person()
person2.sayName() // Nicholas
alert(person1.sayName == person2.sayName) // true
优点:让所有对象实例共享它所包含的属性和方法
四、组合使用构造函数模式和原型模式
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby", "Court"]
}
Person.prototype = {
constructor: Person,
sayName: function() {
alert(this.name);
}
}
PS:使用最广泛、认同度最高的一种创建自定义类型的方法。可以说这是用来定义类型引用的一种默认模式。
五、动态原型模式
通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。
function Person(name, age, job) {
// 属性
this.name = name;
this.age = age;
this.job = job;
// 方法
if(typeof this.sayName != "function") {
Person.prototype.sayName = function() {
alert(this.name);
}
}
}
六、寄生构造函数模式
创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后在返回新创建的对象。跟工厂模式一模一样
function SpecialArray() {
var values = new Array();
values.push.apply(values, arguments);
values.toPipedString = function() {
return this.join("|");
}
return values;
}
var colors = new SpecialArray("red", "blue", "green");
alert(colors.toPipedString());
- 返回的对象与构造函数或者与构造函数的原型属性之间没有关系,也就是说,构造函数返回的对象与在狗仔函数外部创建的对象没有什么不同。
- 不能依赖instanceof操作符来确定对象类型。
七、稳妥构造函数模式
没有公共属性,而且其方法也并不引用this的对象
function Person(name, age, job) {
var o = new Object()
o.sayName = function() {
alert(name);
}
return o;
}