一、工厂模式
用函数来封装以特定接口创建对象的细节
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("Nicholas",29,"Software Engineer");
var person2=createPerson("Greg",27,"Doctor");
二、构造函数模式
ECMAScript中可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
console.log(this.name);
};
}
var person1=new Person("Nicholas",29,"Software Engineer");
var person2=new Person("Greg",27,"Doctor");
注意:构造函数模式与工厂模式的不同之处:
1.没有显式的创建对象;
2.直接将属性和方法赋给this对象
3.没有return语句‘
4.创建实例时,必须使用new操作符
5.函数名始终以一个大写字母开头,便于区分ECMAScript中的其他函数。
对象的constructor(构造函数)属性
用来标识对象类型
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
console.log(this.name);
};
}
var person1=new Person("Nicholas",29,"Software Engineer");
var person2=new Person("Greg",27,"Doctor");
console.log(person1.constructor==Person);//true
console.log(person1 instanceof Person);//true
console.log(person2.constructor==Person);//true
console.log(person2 instanceof Person);//true
胜于工厂模式之处:
可以将它的实例标识为一种特定的类型。
将构造函数当做函数
任何函数,只要通过new操作符来调用,那它就可以作为构造函数;而任何函数,如果不通过new操作符来调用,那它跟普通函数也不会有什么两样
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
console.log(this.name);
};
}
var person1=new Person("Nicholas",29,"Software Engineer");
var person2=new Person("Greg",27,"Doctor");
Person("yangyuqing",21,"student");
window.sayName();//yangyuqing
var o=new Object();
o.name="yyq";
Person.call(o,"yangyuqing",21,"student");
o.sayName();//yangyuqing
构造函数的问题
以上面的方式创建函数,每个Person实例都包含一个不同的function函数。
console.log(person1.sayName==person2.sayName);//false
通过把函数定义转移到构造函数外部来解决这个问题。
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=sayName;
}
function sayName(){
console.log(this.name);
}
var person1=new Person("Nicholas",29,"Software Engineer");
var person2=new Person("Greg",27,"Doctor");
console.log(person1.sayName==person2.sayName);//true
新问题
如果对象需要定义很多方法,那么就要定义很多个全局函数,于是我们自定义的引用类型就毫无封装性而言。
三、原型模式
解决构造函数模式下的问题。不必再在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。实例可共享这个对象的属性和方法。
function Person(){
}
//每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向函数的原型对象
Person.prototype.name="Nicholas";
Person.prototype.age=29;
Person.prototype.job="SoftWare Engineer";
Person.prototype.sayName=function(){
console.log(this.name);
};
var person1=new Person();
person1.sayName();//Nicholas
var person2=new Person();
person2.sayName();//Nicholas
console.log(person1.sayName==person2.sayName);//true