1、可以使用Object构造函数或对象字面量创建对象,但也有缺点:使用同一个接口创建很多对象时,会有很多的重复代码
2、工厂模式
优点:在创建多个同类型对象时,不用写大量的重复的代码了
缺点:不能解决对象识别的问题,也就是没法确定对象类型(因为内部是通过Object构造函数实现的)
eg:
//创建对象的工厂函数
function createPerson(name){
var o = new Object();
o.name = name;
o.sayName = function(){
alert(this.name);
}
return o;
}
//使用工厂函数创建对象
var person1 = createPerson("nico");
var person2 = createPerson("licl");
3、构造函数模式
优点:
(1)、创建多个相同类型的对象时,不用写太多的重复代码
(2)、可以识别对象类型
缺点:
(1)、每个方法在每个函数上都要重新创建一遍(导致不同实例的同名函数不是相等的,即指向不是同一个对象)
(2)、也可以将构造函数的方法,指向全局环境里定义的函数,这样可以解决重复创建的问题,但这样的代码没有丝毫的封装性
eg:
//创建一个person类构造函数
function Person(name){
this.name = name;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person(“nico”);
var person2 = new Person(“licl”);
注:
(1)、以上创建对象实例,会经历以下4个步骤
创建一个新对象
将构造函数的作用域赋值给新对象(即this指向了这个新对象)
执行构造函数中的代码(为新对象添加属性)
返回新对象
(2)、以上使用构造函数创建的对象,都有一个constructor(构造函数)属性,这个属性指向构造函数,即Person
(3)、检测对象类型,instanceof操作符更可靠
(以上创建的实例person1和person2及时Object的实例,也是Person的实例)
(4)、构造函数本质还是个函数,可以直接调用,当函数使用
person(“licl”);//这时函数中的this指的是当前所在执行环境的环境变量(在全局环境中,就是window)
var o = new Object();
person.call(o,”licl”);//可以使用call()或apply(),设置作用域,这样可修改this指向,使其在某个特殊作用域中被调用
4、原型模式
优点:让所有对象的实例共享它所包含的属性和方法
缺点:
(1)、省去初始化参数,所有实例在默认情况下,都取相同的属性值
(2)、由于其共享属性的特性,当一个实例修改属性值时,会影响到其他实例的值(这问问题也是很少单独使用原型模式的原因所在)
eg:
//定义类
function Person(){}
Person.prototype.name = "licl";
Person.prototype.sayName = function(){
alert(this.name);
}
//实例化
var person1 = new Person();
person1.sayName();//"licl"
var person2 = new Person();
person2.sayName();//"licl"
alert(person1.sayName == person2.sayName);//true
注:
(1)、每个函数都有一个prototype(原型)属性,
(2)、原型属性是个指针,指向一个对象,这个对象包含有特定类型的所有实例对象共享的属性和方法
5、组合使用构造函数模式和原型模式(这种混合模式使用最广泛的)
function Person(name){
this.name = name
}
Person.prototype = {
constructor:Person,
sayName:function(){
alert(this.name);
}
}
var person1 = new Person("licl");
var Person2 = new Person("lichemnglogn");
6、动态原型模式
7、寄生构造函数模式
8、稳妥构造函数模式