初涉JavaScript模式 (7) : 原型模式 【三】
组合使用构造函数模式和原型模式
上篇,我们提到了原型模式的缺点,就是每个实例不能拥有自己的属性,因为纯原型模式所有的属性都是公开给每个实例的,故我们可以组合使用构造函数模式和原型模式。构造函数用来定义实例的属性,而原型模式用来定义方法和公用属性。这样的话,每个实例都有自己的属性副本(而不是指向原型的引用),同时它也共享原型上方法的引用。而且,这种混合模式还支持对构造函数传参,所以可以说是结合了两种模式的优点。示例如下:
```javascript
function Animal(name,type){
this.name = name;
this.type = type;
}
Animal.prototype = {
constructor: Animal,
sayName : function(){
console.log("oh ~~~~我的名字叫"+this.name);
}
};
var tom = new Animal("tom","Cat");
var jerry = new Animal("jerry","Mouse");
console.log(tom.name === jerry.name); //false
console.log(tom.sayName === jerry.sayName); //true
```
上面的例子中,实例属性都都是在构造函数中定义的,故每个实例的属性都是私有的副本,不会互相影响。而在原型中定义的方法,每个实例的引用都是指向同一个方法(原型上的)。这种组合模式是在JS中使用最广的一种创建自定义类型的方法,推荐使用。
动态原型模式
动态原型模式是用来解决原型和构造函数独立的问题。很多情况下,构造函数和原型都是相互独立的,这有的时候不太美观,而为了解决这么一批对代码有洁癖的程序猿(例如我),在JS中衍生了一种奇葩的解决方案。这种方案就是动态原型模式,他把所有的信息都封装在构造函数中,而通过在构造函数中初始化原型(仅在必要情况下),这样就不仅保留了构造函数模式和原型模式的优点,而且单独的相对独立也得到了解决。
而仅在必要情况下初始化原型,可以通过检查某个应该存在的方法是否有效来判断。代码如下:
```javascript
function Animal(name,type){
this.name = name;
this.type = type;
if(typeof this.sayName != "function"){
Animal.prototype.sayName = function(){
console.log("oh~~~my name is "+this.name);
}
}
}
var tom = new Animal("tom","Cat");
var jerry = new Animal("jerry","Mouse");
console.log(tom.name === jerry.name); //false
console.log(tom.sayName === jerry.sayName); //true
```
以上代码会检查原型是否初始化完成,如果没有就对原型进行初始化。要注意的是使用动态原型模式时,不能以字面量的形式重写原型对象,因为这样就切断了已有实例和新原型的关系。不过虽然这种方法很好用,但是我觉得这种方式(以if判断)容易造成代码的混淆,而且把原型init放在构造函数中也不是一个很好的方法,所以最后我还是选择了独立原型和构造函数,只不过我对原型和构造函数上面再做了一层封装。(个人喜好,要喷请轻点。。。)
总结
通过这三篇(这一篇算是收尾),对原型模式做了大体的归纳,由于经验和阅历的关系,没有办法面面俱到。文章内容参考了高程,设计模式,编程模式等,在写的过程中,也对自己的知识体系进行了一遍梳理,收获很大。
后记
如果你在文中发现有什么错误或则疑惑,我们可以共同讨论。群 239147101(N多JS大神)。
初涉JavaScript模式 (7) : 原型模式 【三】的更多相关文章
- 初涉JavaScript模式 (5) : 原型模式 【一】
什么是原型模式? 原型模式(prototype)是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象.--引自JavaScript设计模式 我们创建的每一个函数都有一个prototype ...
- javascript创建对象之原型模式(三)
少废话,先上代码: function Human() { } Human.prototype.name = "成吉思汗"; Human.prototype.sex = " ...
- 理解javascript中的原型模式
一.为什么要用原型模式. 早期采用工厂模式或构造函数模式的缺点: 1.工厂模式:函数creatPerson根据接受的参数来构建一个包含所有必要信息的person对象,这个函数可以被无数次的调用,工厂 ...
- javascript 面向对象编程(工厂模式、构造函数模式、原型模式)
javascript 面向对象编程(工厂模式.构造函数模式.原型模式) CreateTime--2018年3月29日17:09:38 Author:Marydon 一.工厂模式 /** * 工厂模 ...
- 浅谈JavaScript中的原型模式
在JavaScript中创建对象由很多种方式,如工厂模式.构造函数模式.原型模式等: <pre name="code" class="html">/ ...
- [19/04/24-星期三] GOF23_创建型模式(建造者模式、原型模式)
一.建造者模式 本质:分离了对象子组件的单独构造(由Builder负责)和装配的分离(由Director负责),从而可以构建出复杂的对象,这个模式适用于:某个对象的构建过程十分复杂 好处:由于构建和装 ...
- JavaScript之面向对象学习六原型模式创建对象的问题,组合使用构造函数模式和原型模式创建对象
一.仔细分析前面的原型模式创建对象的方法,发现原型模式创建对象,也存在一些问题,如下: 1.它省略了为构造函数传递初始化参数这个环节,结果所有实例在默认的情况下都将取得相同的属性值,这还不是最大的问题 ...
- javascript创建对象之函数构造模式和原型模式结合使用(四)
创建自定义类型的常见方式就是组合使用构造函数模式与原型模式一起使用. 构造函数模式用于定义实例对象的特有的部分(属性和方法),原型模式用于定义共享的部分. 这样最大限度的节省了内存的开销. funct ...
- Java进阶篇设计模式之三 ----- 建造者模式和原型模式
前言 在上一篇中我们学习了工厂模式,介绍了简单工厂模式.工厂方法和抽象工厂模式.本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式. 建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用 ...
随机推荐
- Qt入门(13)——Qt的调用退出
如果我们创建了一个窗口,接下来使这个应用程序在用户让它退出的时候退出. #include <qfont.h>因为这个程序使用了QFont,所以它需要包含qfont.h.Qt的字体提取和X中 ...
- 利用matlab给图像加高斯噪声
I = imread('DSC_0034.JPG'); J = imnoise(I,'gaussian',0.20); figure, imshow(I), figure, imshow(J)
- Light OJ 1030 - Discovering Gold
题目大意: 给你一个1*N的方格,你初始位置是在1,给你一个骰子,假设你现在的位置是X,你投掷一个骰子掷的点数是y, 那么你的新位置就是 X+y, 并且你可以得到新位置的宝藏.假如X+y > N ...
- C#:ref和out的联系及区别
一:ref 关键字使参数按引用传递. 其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中.若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字. ...
- 关于aspx 页面生成html 源码顶部空行不得不说的事儿
原文引用自 http://www.360doc.com/content/12/0910/21/10504424_235418578.shtml 使用.aspx生成的页面一般都会有一个或多个空行,当然这 ...
- java一切乱码的解释 以及源头【转】
工作中经常遇到java编码问题,由于缺乏研究,总是无法给出确切的答案,这个周末在网上查了一些资料,在此做些汇总. 问题一:在java中读取文件时应该采用什么编码? Java读取文件的方式总体可以分为两 ...
- NOI题库1814 恼人的青蛙
1814:恼人的青蛙 总时间限制: 2000ms 单个测试点时间限制: 500ms 内存限制: 65536kB 描述 在韩国,有一种小的青蛙.每到晚上,这种青蛙会跳越稻田,从而踩踏稻子.农民在早上看到 ...
- linux环境下deb格式 转换成rpm格式
linux环境下deb格式 转换成rpm格式 使用alien工具转换deb格式到rpm格式 alien_8.87.tar.gz 下载alien_8.87.tar.gz [root@mysqlnode2 ...
- hdu 4640 Island and study-sister(状态压缩dp)
先处理前两个学长到达各个点所需要的最少时间,在计算前两个学长和最后一个学长救出所有学妹的最少时间. #include<stdio.h> #include<string.h> # ...
- 424. Longest Repeating Character Replacement
以最左边为开始,往右遍历,不一样的个数大于K的时候停止,回到第一个不一样的地方,以它为开始,继续.. 用QUEUE记录每次不一样的INDEX,以便下一个遍历开始, 从左往右,从右往左各来一次..加上各 ...