js的工厂模式和构造函数模式

2017-9-10 15:34:36 5,295 views

创建对象

虽然Object构造函数或对象字面量都可以用来创建单个对象,这个方式的明显缺点就是使用同一个接口创建很多对象,会产生大量的重复代码。

1.1工厂模式:

这种模式抽象了创建具体对象的过程

function create(name,age,sex){
var o=new Object();
o.name=name;
o.age=age;
o.sex=sex;
o.sayName=function(){
alert(this.name);
};
return o;
}
var person=create("mike",29,"man");
var person1=create("john",22,"man");
//返回的是包括三个属性和一个方法的对象。

 
工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题。

1.2构造函数模式

function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.sayName=function(){
alert(this.name);
};
}
var person=new Person("mike",29,"man");
var person1=new Person("john",22,"man");

 
//与工厂模式的不同之处
1>没有显示地创建对象
2>直接将属性和方法赋给了this对象
3>没有return 语句
//构造函数始终都应该以一个大写字母开头,而非构造函数以小写字母开头
要创建Person新实例,必须使用new操作符,这种方式调用构造函数会经历4个步骤
1>创建一个新对象
2>将构造函数的作用域赋给新对象(this就指向了这个新对象)
3>执行构造函数中的代码(为这个新对象添加属性)
4>返回新对象
person1和person2分别保存着Person的一个不同实例,这2个对象都有一个constructor(构造函数)属性,该属性指向Person

alert(person.constructor==Person);//true person.constructor输出的是整个构造函数与Person相同
alert(person1.constructor==Person);//true

 
这个例子中创建的所有对象即是Object的实例,也是Person的实例
检测对象类型

alert(person instanceof Person);//true
alert(person instanceof Object);//true,来源于继承,所有对象均继承之Object
alert(person1 instanceof Person);//true
alert(person1 instanceof Object);//true

 
构造函数与其他函数的区别:就在与调用它们的方式不同,构造函数通过new操作符来调用
构造函数的问题
使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍
person 与person1是不同的Function实例,

function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.sayName=new Function("alert(this.name)");
}

 
//每个Person实例都包含一个不同的Function实例,这种方式创建函数,会导致不同的作用域链和标识符解析,但创建Function实例的机制仍然相同,因此不同实例上的同名函数是不同的

alert(person1.sayName==person.sayName);//false
//创建2个完成同样任务的Function实例,可以通过把函数定义转移到构造函数外部
function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.sayName=sayName;
}
function sayName(){
alert(this.name);
}
var person1=new Person("mike",29,"man");
var person2=new Person("john",29,"man");

 
//这里我们把sayName的函数定义转移到了构造函数外面,而在构造函数内部,我们把sayName属性设置成等于全局的sayName函数。由于sayName包含的是一个指向函数的指针,因此person1和person2对象就共享了在全局作用域中定义的同一个sayName函数。这样确实解决了2个函数做同一件事的问题。
新问题:在全局作用域中定义的函数实际上只能被某个对象调用,如果要定义很多方法,则要定义很多全局函数。 可以通过原型模式解决

2

分享到微信朋友圈

打开微信,点击底部的“发现”,
使用“扫一扫”即可将网页分享至朋友圈。