第一种:工厂模式
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 person1 = new Person("Greg", 27, "Doctor");
上述new操作符的作用:
(1)创建一个新对象;
(2)将构造函数的作用域赋值给新对象(因此this就指向了这个新对象);
(3)执行构造函数中的代码;
(4)返回新对象
person1和person2分别保存着Person的一个不同的实例。这两个对象都与一个construcor属性,该属性指向Person,如下:
alert(person1.constructor == Person) ; //true
alert(person2.constructor == Person) ; //true
constructor属性是用来标识对象类型,但是基本用instanceof操作符检测对象类型会更可靠。创建的所有对象既是Object的实例,同时也是Person的实例。
alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true
alert(person2 instanceof Object);// true
alert(person2 instanceof Person); //true
构造函数优点:可识别对象类型,创建的所有对象既是Object的实例,同时也是Person的实例。但工厂模式里面,所有的函数都只是Object的实例
缺点:每个方法 都要在每个实例重建一遍。
第三种:原型模式
优点:可以让所有对象实例共享它所包含的属性和方法
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();
var person2 = new Person();
注意:与构造函数模式不同的是,新对象的属性和方法都由实例共享。person1和person2访问的都是同一组属性和同一个sayName()函数。重点;掌握原型对象
上述原型模式代码可以简写如下:
function Person(){
}
Person.prototype = {
name : "Nicholas";
sayName : function(){
alert(this.name);
}
};
问题:实例的constructor属性不再指向Person
原型模式存在的缺点:
(1)为省略构造函数传递初始化参数环节,所有实例默认情况下都将取得相同的属性值,
(2)某一个实例的属性改变会影响到其他实例的属性,对于包含引用类型值的属性来说问题比较突出
第四种 组合使用构造函数模式和原型模式
用法:构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。所以,每个实例都会有字的一份实例属性的副本,但同时又共享着对方法的引用。最大限度节省了内存。
function Person(){
this.name = name;
this.age = age;
this.job = job;
this.friends = ['Shelby', 'Court'];
}
Person.prototype{
constructor : Person,
sayName : function(){
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
第五种 动态原型模式
原理:把所以信息封装到构造函数中,而通过构造函数中初始化原型。换句话说,可以同通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。
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 Person(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 friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName();
第七种 稳妥构造函数模式
几个方法:
(1)isPrototypeof():确定对象与实例是否存在的关系
(2)Object.getPrototypeof():返回对象原型
(3)hasOwnProperty():检测一个属性是否存在实例中,还是原型,如果是实例,则返回true,否则返回false