面向对象与原型2
2015-03-22 23:06
113 查看
原型模式创建对象也有自己的缺点,它省略了构造函数传参初始化这一过程,带来的缺
点就是初始化的值都是一致的。而原型最大的缺点就是它最大的优点,那就是共享。
原型中所有属性是被很多实例共享的,共享对于函数非常合适,对于包含基本值的属性
也还可以。但如果属性包含引用类型,就存在一定的问题:(传参)
PS:数据共享的缘故,导致很多开发者放弃使用原型,因为每次实例化出的数据需要保留自己的特性,而不能共享。
五、组合构造函数+原型模式
原型模式,不管你是否调用了原型中的共享方法,它都会初始化原型中的方法,并且在
声明一个对象时,构造函数+原型部分让人感觉又很怪异,最好就是把构造函数和原型封装
到一起。为了解决这个问题,我们可以使用动态原型模式。--封装
六、动态原型模型
当第一次调用构造函数时,run()方法发现不存在,然后初始化原型。当第二次调用,就
不会初始化,并且第二次创建新对象,原型也不会再初始化了。这样及得到了封装,又实现
了原型方法共享,并且属性都保持独立。
PS:使用动态原型模式,要注意一点,不可以再使用字面量的方式重写原型,因为会
切断实例和新原型之间的联系。
七、寄生构造函数,其实就是工厂模式+构造函数模式
八、稳妥构造函数
在一些安全的环境中,比如禁止使用this 和new,这里的this 是构造函数里不使用this,
这里的new 是在外部实例化构造函数时不使用new。这种创建方式叫做稳妥构造函数。
点就是初始化的值都是一致的。而原型最大的缺点就是它最大的优点,那就是共享。
原型中所有属性是被很多实例共享的,共享对于函数非常合适,对于包含基本值的属性
也还可以。但如果属性包含引用类型,就存在一定的问题:(传参)
//原型的缺点 function Box() {}; Box.prototype = { constructor : Box, name : 'Lee', age : 100, family : ['父亲', '母亲', '妹妹'], //添加了一个数组属性 run : function () { return this.name + this.age + this.family; } }; var box1 = new Box();
box1.family.push('哥哥'); //在实例中添加'哥哥'//在第一个修改后引用类型,保持了共享 alert(box1.run()); var box2 = new Box(); alert(box2.run()); //共享带来的麻烦,也有'哥哥'了//共享了box1添加后的引用类型的原型
PS:数据共享的缘故,导致很多开发者放弃使用原型,因为每次实例化出的数据需要保留自己的特性,而不能共享。
五、组合构造函数+原型模式
function Box(name, age) { //不共享的使用构造函数 this.name = name; this.age = age; this.family = ['父亲', '母亲', '妹妹']; }; Box.prototype = { //共享的使用原型模式 constructor : Box, run : function () { return this.name + this.age + this.family; } };var box1 = new Box(); var box1 = new Box('Lee', 100); //alert(box1.run()); alert(box1.family); box1.family.push('弟弟'); alert(box1.family); var box2 = new Box('Jack', 200); //alert(box2.run()); alert(box2.family); //引用类型没有使用原型,所以没有共享
原型模式,不管你是否调用了原型中的共享方法,它都会初始化原型中的方法,并且在
声明一个对象时,构造函数+原型部分让人感觉又很怪异,最好就是把构造函数和原型封装
到一起。为了解决这个问题,我们可以使用动态原型模式。--封装
六、动态原型模型
当第一次调用构造函数时,run()方法发现不存在,然后初始化原型。当第二次调用,就
不会初始化,并且第二次创建新对象,原型也不会再初始化了。这样及得到了封装,又实现
了原型方法共享,并且属性都保持独立。
//可以将原型封装到构造函数里 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); var box2 = new Box('Jack', 200);
PS:使用动态原型模式,要注意一点,不可以再使用字面量的方式重写原型,因为会
切断实例和新原型之间的联系。
七、寄生构造函数,其实就是工厂模式+构造函数模式
//寄生构造函数 = 工厂模式 + 构造函数 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); alert(box1.run()); var box2 = new Box('Jack', 200); alert(box2.run());
八、稳妥构造函数
在一些安全的环境中,比如禁止使用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());
相关文章推荐
- 深刻理解JavaScript基于原型的面向对象
- 面向对象与原型02
- 面向对象与原型03
- 面向对象与原型04
- 面向对象与原型05
- 面向对象之原型链
- 月影MM对面向对象,原型,函数式的理解
- 18--26 面向对象程序设计22(创建一个原生的原型)
- 面向对象的程序设计-原型模式
- JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
- 面向对象之原型——challenge
- 简析面向对象中的继承,原型链,闭包之原型链 3ff8
- javascript 面向对象全新理练之原型继承
- 面向对象与原型
- JavaScript 面向对象思想以及原型、继承
- 面向对象与原型02
- 面向对象与原型03
- 面向对象与原型04
- 面向对象与原型05
- Javascript 面向对象原型