js15-4:原型的缺点和解决方法

原型模式缺点:

  1. 无法保持独立;
  2. 信息共享
  3. 无法传参
  4. 两个属性相同改变
function Box() {}

Box.prototype = {
constructor : Box,
name : 'caibaojian',
age : 100,
family : ['哥哥','姐姐','妹妹'],
run : function () {
return this.name + this.age + '运行中...'
}
};
var box1 = new Box();
alert(box1.family);
box1.family.push('弟弟'); //在第一个实例修改后引用类型,保持了共享
alert(box1.family);

var box2 = new Box();
alert(box2.family); //共享了box1添加后的引用类型的原型

解决方法:

1.组合构造函数+原型模式

function Box(name, age) { //保持独立的用构造函数
this.name = name;
this.age = age;
this.family = ['哥哥','姐姐','妹妹'];
}

Box.prototype = { //保持共享的用原型
constructor : Box,
run : function () {
return this.name + this.age + '运行中...'
}
};

var box1 = new Box('caibaojian', 100);
//alert(box1.run()); //Lee
alert(box1.family);
box1.family.push('弟弟');
alert(box1.family);

var box2 = new Box('Jack', 200);
//alert(box2.run());
alert(box2.family); //引用类型没有使用原型,所以没有共享

可以将原型封装到构造函数里

2.动态原型模式

function Box(name, age) {
this.name = name;
this.age = age;
this.family = ['哥哥','姐姐','妹妹'];

if (typeof this.run != 'function') { //判断this.run是否存在
Box.prototype.run = function() {
return this.name + this.age + '运行中...'
};
}
}

//原型的初始化,只要第一次初始化,就可以了,没必要每次构造函数实例化的时候都初始化

var box1 = new Box('Lee', 100);
box1.family.push("弟弟");
alert(box1.family); //哥哥,姐姐,妹妹,弟弟

var box2 = new Box('Jack', 200);
alert(box2.family); //哥哥,姐姐,弟弟

3.寄生构造函数 = 工厂模式+构造函数

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('caibaojian', 100);
alert(box1.run());

var box2 = new Box('Jack', 200);
alert(box2.run());

4.稳妥构造函数

在一些安全环境中,比如禁止使用this和new,这里的this是构造函数里不使用this,这里的new是在外部实例化构造函数时不适用new

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 = Box('Lee', 100);
alert(box1.run());

var box2 = Box('Jack', 200);
alert(box2.run());

关注我

我的微信公众号:前端开发博客,在后台回复以下关键字可以获取资源。

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
  • 回复「Vue脑图」获取 Vue 相关脑图
  • 回复「思维图」获取 JavaScript 相关思维图
  • 回复「简历」获取简历制作建议
  • 回复「简历模板」获取精选的简历模板
  • 回复「加群」进入500人前端精英群
  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
  • 回复「知识点」下载高清JavaScript知识点图谱

每日分享有用的前端开发知识,加我微信:caibaojian89 交流