记录JavaScript中创建对象的几种方法。
工厂模式
工厂模式是一种设计模式,抽象创建具体对象的过程,用函数来封装特定接口并创建对象的细节。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| /* 工厂模式 */ 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");
console.log(person1); console.log(person2);
|
优点:
解决创建多个相似对象。
缺点:
没有解决对象识别的问题。
构造函数模式
构造函数模式,通过创建自定义的构造函数,定义自定义对象类型的属性和方法。
构造函数,函数名开头使用大写字母。0
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| // 构造函数 function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function() { alert(this.name); }; }
var person1 = new Person("Perry", 27, "FE"); var person2 = new Person("Kobe", 33, "Player");
console.log(person1); console.log(person2);
|
优点:
1、不需要显示的创建对象。
2、它的实例可以标识为一种特定的类型。
缺点:
1、每个方法要在每个实例上重新创建一遍。
原型模式
通过函数的prototype属性进行所有实例共享来添加属性和方法。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // 原型模式 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();
var person2 = new Person(); person2.sayName();
console.log(person1.sayName == person2.sayName);
|
优点:
各实例之间可共享属性和方法。
缺点:
引用类型的属性,实例无法拥有自己的数据。
组合使用构造函数模式和原型模式
组合使用,构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性。
1 2 3 4 5 6 7 8 9 10 11 12 13
| function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; }
Person.prototype = { constructor: Person, sayName: function() { console.log(this.name); } };
|
优点:
方法可由所有实例共享,引用类型数据可保持独立。
使用广泛。
缺点:
无
动态原型模式
所有的信息都封装在构造函数中。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| // 动态原型模式 function Person(name, age, job) { this.name = name; this.age = age; this.job = job;
if (typeof this.sayName != "function") { Person.prototype.sayName = function() { console.log(this.name); } } }
var friend = new Person("Nicholas", 29, "Software Engineer"); friend.sayName();
|
优点:
封装性好。
缺点:
不能使用对象字面量重新原型。
寄生构造函数模式
通过函数封装创建对象的代码,并返回新创建的对象。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| // 寄生构造函数模式 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"); console.log(colors.toPipedString());
|
优点:
其他模式不适用的情况下使用。
缺点:
无法使用instanceof来确定对象的类型。
尽量不使用此模式。
稳妥构造函数模式
新创建对象的实例方法不引用this;不使用new操作符调用构造函数。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| // 稳妥构造函数模式 function Person(name, age, job) { var o = new Object();
o.sayName = function() { console.log(name); }
return o; }
var friend = Person("Nicholas", 29, "Software Engineer"); friend.sayName();
|
优点:
提供安全性,只用通过调用方法访问数据成员。
缺点:
无法确定对象类型。