原型模式缺点:
- 无法保持独立;
- 信息共享
- 无法传参
- 两个属性相同改变
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());