1.工厂模式
function createPerson(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
console.log(this.name);
}
return o;
}
var person1 = createPerson('zxx', 28, 'Software Engineer');
var person2 = createPerson('li', 25, 'Doctor');
2. 构造函数模式
function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name);
}
}
var person1 = new Person('zxx', 28);
var person2 = new Person('li', 25);
该方法主要问题,就是每个方法都有在每个实例上重新创建一遍。
我们注意到person1和person2都有一个sayName的方法,但这两个方法不是同一个Function的实例。(ECMAScript中的函数是对象,因此每定义一个函数,就是实例化了一个对象。)
我们可以通过把函数定义转移到构造函数外部来解决:
function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = sayName;
}
function sayName(){
console.log(this.name);
}
var person1 = new Person('zxx', 28);
var person2 = new Person('li', 25);
此时person1和person2对象共享了在全局作用域中定义的同一个sayName函数。但如果对象需要定义很多方法,那么就要定义多个全局函数,这个自定义引用类型就无封装性了。
3. 原型模式
function Person() {
}
Person.prototype.name = 'zxx';
Person.prototype.age = '28';
Person.prototype.sayName = function(){
console.log(this.name);
}
var person1 = new Person();
person1.sayName(); // zxx
var person2 = new Person();
person2.sayName(); // zxx
person1.sayName == person2.sayName; // true
缺点是新对象的这些属性和方法都是由所有实例共享的。
function Person(name) {
}
Person.prototype = {
constructor: Person,
name: 'zxx',
getName: function () {
console.log(this.name);
}
};
var person1 = new Person();
优点:实例可以通过constructor属性找到所属构造函数
4. 组合模式
构造函数模式与原型模式双剑合璧
function Person(name) {
this.name = name;
}
Person.prototype = {
constructor: Person,
getName: function () {
console.log(this.name);
}
};
var person1 = new Person();