1、创建对象方法
var box =new Object();
box.name='Lee';
box.age=100;
box.run=function(){
return this.name+this.age+'运行中...';
}
alert(box.run());
alert(box.name);
小结:创建一个类似对象,需要编写大量代码。
2、工厂模板创建对象
function createObject(name,age){
var obj=new Object();
obj.name=age;
obj.age=age;
obj.run=function(){
return this.name+this.age+'运行中...';
}
return obj;
}
var box1=createObject('Lee',100);
var box2=createObject('Jack',200);
alert(box1.run());
alert(box2.run();
小结:解决了重复实例化的问题,但无法搞清楚他们到底是哪个对象的实例(都是Objct类型)
3、构造函数模式
function Box(name,age){
this.name=name;
this.age=age;
box.run=function(){
return this.name+this.age+'运行中...';
}
}
var box1=new Box('Lee',100);
小结:以上方法会造成每次实例时,方法都会生成一次占用内存。改进如下:
function Box(name,age){
this.name=name;
this.age=age;
box.run=run;
}
function run(){
return this.name+this.age+'运行中...';
}
小结:使用全局函数run()解决了保证引用地址一致的问题,但函数run当普通函数时,其this在单独调用时又表示的是window
4、原型
function Box(){};
Box.prototype.name='Lee'; //在原型中添加属性
Box.prototype.age=100;
Box.prototype.run=function(){ //在原型中添加方法
return this.name+this.age+'运行中...';
};
小结:不怎么体现封装的效果,输入代码太多改进如下
function Box(){};
Box.prototype={
name:'Lee',
age:100,
run:function(){
return this.name+this.age+'运行中...';
}
};
小结:原型模式创建对象也有自己的缺点,它活力了构造函数值参初始化这一过程,带来的缺点就是初始化的值都是一致的。而最大的缺点就是共享,原型中所有属性是被很多实例共享的,共享对于函数非常合适,对于包含基本值的属性也还可能。但如果属性包含引用类型,就存在一定问题。
function Box(){};
Box.prototype={
name:'Lee',
age:100,
family:['父亲','母亲','妹妹']
run:function(){
return this.name+this.age+'运行中...';
}
};
var box1=new Box();
box1.family.push('弟弟');
alert(box1.family);
var box2=new Box(();
alert(box1.family); //理论值应为['父亲','母亲','妹妹'],实际输出值为['父亲','母亲','妹妹','弟弟']
小结:为了解决构造函数传参和共享问题,可以组合构造函数+原型模式
5、构造函数+原型模式[推荐]
function Box(name,age){
this.name='Lee';
this.age=100;
this.family:['父亲','母亲','妹妹'];
};
Box.prototype={ //共享的使用原型模式
constructor:Box,
run:function(){
return this.name+this.age+'运行中...';
}
};
小结:原型模式,不管你是否调用了原型中的共享方法,它都会初始原型中的方法,并且在声明一个对象,构造函数+原型部分让人感觉又很怪异,最好就是把构造函数和原型封装到一起。为了解决这个问题,我们可以使用动态原型模式。
6、动态原型模式
function Box(name,age){
this.name='Lee';
this.age=100;
this.family:['父亲','母亲','妹妹'];
alert('原型初始化开始')
Box.prototype.run=function(){ //共享的使用原型模式
return this.name+this.age+'运行中...';
};
alert('原型初始化结束')
};
var box1=new BOx('Lee',100);
var box2=new BOx('Jack',200);
PS:会发现原型方法被实例(调用)了两次,原型方法仅在第一次调用时实例就可以。改进如下:
function Box(name,age){
this.name='Lee';
this.age=100;
this.family:['父亲','母亲','妹妹'];
if (typeof this.run!='function'){ //判断run是否存在
alert('原型初始化开始')
Box.prototype.run=function(){ //共享的使用原型模式
return this.name+this.age+'运行中...';
};
alert('原型初始化结束')
}
};
var box1=new BOx('Lee',100);
var box2=new BOx('Jack',200);
7、寄生构造模式(工厂模式+构造函数模式)
function Box(name,age){
var obj=new Object();
obj.name=name;
obj.age=age;
obj.run=function(){
return this.name+this.age+'运行中...';
};
return obj;
}
小结:不能确定对象关系,不建议使用此模式
8、稳妥构造函数(禁用使用this,new)
function Box(name,age){
var obj=new Object();
obj.run=function(){
return name+age+'运行中...';
}
return obj;
}
var box=Box('Lee',100);
alert(box.run());