创建对象的几种方法——《JavaScript高级程序设计》笔记:
1. 工厂模式(用函数来封装以特定接口创建对象)
优点: 可以无数次调用这个函数,解决了创建多个相似对象的问题
缺点: 无法确定对象的类型(因为都是Object);创建的多个对象间没有关联
2. 构造函数模式
优点: 创建自定义的构造函数在以后的使用中可以将它的实例标识为一种认定的类型,容易方便查找原型对象。相对工厂模式要更优化。
缺点: 每创建一个实例,就另外生成一个sayName函数,该sayName函数不能共享,造成资源浪费。
于是,有了下面的构造函数优化:
优点: 把函数方法的定义转移到了函数外面,调用sayName函数的对象能共享该函数。
缺点: sayName变成了全局函数,但实际只能被某些对象调用,全局属性会被浪费;同时如果存在多个方法,就丧失了封装性。
3. 原型模式
优点: 使用同一个原型对象的实例可以共享属性和方法
缺点: 实例没有自己私有的属性和方法。原型对象一个属性的改变,会影响指向该原型对象的全部实例。
4. 组合使用构造函数模式和原型模式
优点: 组合了构造函数和原型模式的优点,最大限度的节省了内存。使用最广泛,认同度最高的一种创建自定义类型的方法
5. 动态原型模式
说明: 动态中,只有在sayName()方法不存在的情况下,才把它添加到原型中(即只在第一次实例化调用的时候执行if语句中的内容)。
6. 寄生构造函数模式
说明: 在可以使用其他模式的情况下,不要使用这种模式。
7. 稳妥构造函数模式
说明: 除了调用sayName()方法外,没有办法访问其数据成员。由于其安全性,适合于某些安全执行环境。
注意: 这种方法与寄生构造函数创建的实例对象与构造函数与原型对象没有什么关系。
1. 工厂模式(用函数来封装以特定接口创建对象)
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");
优点: 可以无数次调用这个函数,解决了创建多个相似对象的问题
缺点: 无法确定对象的类型(因为都是Object);创建的多个对象间没有关联
2. 构造函数模式
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");
优点: 创建自定义的构造函数在以后的使用中可以将它的实例标识为一种认定的类型,容易方便查找原型对象。相对工厂模式要更优化。
缺点: 每创建一个实例,就另外生成一个sayName函数,该sayName函数不能共享,造成资源浪费。
于是,有了下面的构造函数优化:
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName(){
alert(this.name);
}
优点: 把函数方法的定义转移到了函数外面,调用sayName函数的对象能共享该函数。
缺点: sayName变成了全局函数,但实际只能被某些对象调用,全局属性会被浪费;同时如果存在多个方法,就丧失了封装性。
3. 原型模式
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();
优点: 使用同一个原型对象的实例可以共享属性和方法
缺点: 实例没有自己私有的属性和方法。原型对象一个属性的改变,会影响指向该原型对象的全部实例。
4. 组合使用构造函数模式和原型模式
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby", "Court"];
}
Person.prototype = {
constructor: Person;
sayName: function(){
sayName: function(){
alert(this.name);
}
}
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
优点: 组合了构造函数和原型模式的优点,最大限度的节省了内存。使用最广泛,认同度最高的一种创建自定义类型的方法
5. 动态原型模式
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);
};
}
}
说明: 动态中,只有在sayName()方法不存在的情况下,才把它添加到原型中(即只在第一次实例化调用的时候执行if语句中的内容)。
6. 寄生构造函数模式
说明: 在可以使用其他模式的情况下,不要使用这种模式。
7. 稳妥构造函数模式
function Person(name, age, job){
var o = new Object();
o.name = "Nicholas";
o.sayName = function(){
alert(name);
};
return o;
}
说明: 除了调用sayName()方法外,没有办法访问其数据成员。由于其安全性,适合于某些安全执行环境。
注意: 这种方法与寄生构造函数创建的实例对象与构造函数与原型对象没有什么关系。