版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/fww330666557/article/details/78768983
原型模式创建对象的缺点
1、省略了构造函数传参
导致的结果就是对象初始化的值都是一样的。
2、原型的最大优点,也是其最大缺点,即共享。
特别是对于引用类型,比如一个数组,如果你通过一个实例修改了数组中的数据,那么由此原型创建的所有对象访问的都是修改后的数组数据,因为原型的数据是共享的。
function Box(){}
Box.prototype = {
constructor :Box,
name:'Lee',// 原型属性
age:100,
family:['哥哥','姐姐','妹妹'],
run :function(){
return this.name + this.age +'运行中...';
}
}
var box1 = new Box();
document.write(box1.family);
box1.family.push('弟弟');
document.write("<br/>")
document.write(box1.family);
var box2 = new Box();
document.write("<br/>")
document.write(box2.family);
输出:
哥哥,姐姐,妹妹
哥哥,姐姐,妹妹,弟弟
哥哥,姐姐,妹妹,弟弟
组合构造函数+原型模式
为了解决原型模式的缺点,我们可以采用组合构造函数+原型模式。也就是说不需要共享的部分使用构造函数,需要共享的部分使用原型。
function Box(name,age){
this.name = name;
this.age = age;
this.family = ['哥哥','姐姐','妹妹'];
}
Box.prototype = {
constructor :Box,
run :function(){
return this.name + this.age +'运行中...';
}
}
动态原型模式
组合构造函数+原型模式解决了原型模式的两个缺点,但还是有一些问题:
1、构造函数和原型分别来书写。我们更希望能封装起来。
2、原型模式中,不管你是否调用了原型中的共享方法,它都会初始化原型中的方法。
// 动态原型模式
function Box(name,age){
this.name = name;
this.age = age;
this.family = ['哥哥','姐姐','妹妹'];
if(typeof this.run != 'function'){// 仅在第一次调用时初始化
Box.prototype.run = function(){
return this.name + this.age +'运行中...';
}
}
}
// 测试代码
var box1 = new Box('Lee',100);
var box2 = new Box('Jack',200);
document.write(box1.run());
document.write("<br/>")
document.write(box2.run());
输出:
Lee100运行中...
Jack200运行中...
寄生构造函数
// 寄生构造函数
function Box(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name + this.age +'运行中...';
}
return obj;
}
// 测试代码
var box1 = new Box('Lee',100);
var box2 = new Box('Jack',200);
document.write(box1.run());
document.write("<br/>")
document.write(box2.run());
寄生构造函数模式其实就是工厂模式+构造函数,这种模式比较通用,但不能确定对象关系,所以在可以使用之前所说的模式时,不建议使用。
稳妥构造函数
在一些安全的环境中,比如禁止使用this和new,这里的this是构造函数里不使用this,这里的new是外部实例化的时候不实用new。这种方式叫做稳妥构造函数。
// 稳妥构造函数
function Box(name,age){
var obj = new Object();
obj.run = function(){
return name + age +'运行中...';// 直接使用参数
}
return obj;
}
// 测试代码
var box1 = Box('Lee',100);
var box2 = Box('Jack',200);
document.write(box1.run());
document.write("<br/>")
document.write(box2.run());