听飞狐聊JavaScript设计模式系列04

  • A+
所属分类:JavaScript

本回内容介绍


上一回聊到JS的Function类型,做了柯里化,数组去重,排序的题。

介一回,偶们来聊一下用JS中的类,有些盆友可能用过ES6或者TypeScript的,知道Class语法糖,可是在ES5中并没有,ES5中需要用到构造函数来模拟类。

既然是类,肯定要聊到继承,而聊到继承,那原型也少不了,但是,继承、原型这些知识在网上的基础讲解已经很多了。

所以,偶就把jquery,extjs,nodejs,underscore.js的继承源码拿来做个比较分析,至于模拟接口虾米的,后面会聊滴,来吧开始咯:

1. 再谈对象


重温对象,还是先来个书上(高程3)的例子:

这是之前讲的对象,要修改属性的特性,比如把name修改为不可更改,可能有的盆友说了,用之前聊过的对象冻结isFrozen()方法,是的,可以做到,但是防篡改的方法是作用对象定义之后,如果要修改属性的默认特性,就得用ES5的Object.defineProperty()方法了,

2. Object.defineProperty()方法


Object.defineProperty()方法接收3个参数,属性所在对象,属性名,描述符对象;其中描述符对象的属性必须是:configurable,enumerable,writable,value。这是书上的描述,好像有点抽象,来吧看例子:

怎么样,配上注释,应该不难理解吧。

3. 访问器属性getter,setter


getter,setter,这俩函数具有4个属性(配置,枚举,访问,写入),对写过java的一定很亲切吧,来吧直接看例子要更直观些:

这里简单的改了一下书上的例子,聊到Object.defineProperty()就顺便说一下AngularJS的双向绑定,做一个知识的扩展吧:

如下:

这里做一个最简单的模拟,只是为了演示Object.defineProperty(),如下:

Object.defineProperty是ES5的新玩意儿,不支持IE低版本。很多盆友又要疑惑了,那avalon框架就支持低版本又咋玩的嘞,其实是使用VBScript来实现低版本IE的兼容。

(注:以上的代码,纯属扩展,如果感觉晕菜请跳过)
如果有盆友感兴趣,那我再单独写个angular1.x源码学习读后感,把我读过的Angular源码段分享出来,O(∩_∩)O~

4. Object.defineProperties()方法


Object.defineProperties()方法,定义多个属性,接收两个对象参数,第一个是对象要操作的对象本身,第二个是要操作的对象属性。

这里光看例子可能有点抽象,没关系,后面讲设计模式,聊到观察者模式的时候还会聊到事件。

5. 类的模拟


(1) 工厂模式,这里就直接用书上的例子:

工厂模式虽然简单,而且解决了创建多个相似对象的问题,却无从识别对象的类型,因为全部都是Object,不像Date、Array等,于是乎构造函数模式应运而生。

(2) 构造函数模式,这里也直接用书上的例子:

构造函数没有显示创建对象:new Object(),但会隐式地自动new Object()。而且要注意一点,构造函数没有return语句,是自动返回。

看到这里,构造函数已经很不错了吧,但是:

每次创建实例的时候都要重新创建一次方法,看下面的例子:

可以看出,对象的方法是相同的,而重复的创建导致了定义了多个全局函数,用书上的原话,丝毫木有封装性可言,那啷个办呢,于是乎,引出了原型模式。

6. 原型模式


我们创建的每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性及方法。

高程3上的这个解释貌似有点绕脑袋,来吧,直接看例子:

看上去很不错了,所有对象实例共享了所包含的属性及方法,但是嘞,构造函数传递初始化参数木有了,而且因为共享,一个实例修改了引用,另一个也随之被更改了,这样的话就可以结合原型模式与构造函数模式使用,继续下一个。

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


构造函数模式用于定义实例属性,原型模式用于定义共享属性,看例子:

看上去很不错了,每个实例都会有自己的一份实例属性,但同时又共享着方法,最大限度的节省了内存。

8. 动态原型模式


动态原型模式是把所有信息都封装在构造函数中,通过构造函数中初始化原型,检测该方法是否有效而选择是否需要初始化原型,直接看例子吧:

金星老师说:"完美"!

在高程3的书上还介绍有寄生构造函数模式,稳妥构造函数模式,这里我们不一一列举,咱现在有个大概的理解了,后面就可以继续装逼继续飞了。

这一回聊的有点儿多,先装个逼,话说薛之谦最近有首新歌不错哟,歌名《绅士》。

9. JQuery的extend源码分析


可以看出来,JQuery的这个深拷贝和浅拷贝就是拷贝,说白了就是复制,粘贴。

这个是摘自jquery的源码关于继承的段儿,我加工的注释,如果感觉有难度,可以跳过,看下一个。

10. underscore.js的_.extend源码分析


是不是感觉,很简单粗暴。

11. node.js的inherits源码分析


Object.create()是ES5的新玩意儿,所以IE9以下不支持

这个是node.js的底层源码,因为是nodejs,所以不用去考虑浏览器的兼容性,直接用新玩意儿Object.create(),代码量少,功能强大。

那么问题来了,要考虑浏览器的兼容性,那啷个办呢,来吧,帅狐show给你看。

12. 模拟ExtJS的继承


这个模拟ExtJS源码实现,摘自JavaScript设计模式书上的例子。

这个是模拟ExtJS的继承实现,每一步我都写了注释,应该还是不难理解吧,ExtJS底层源码做了很多扩展,这里只是简单展现思路。

话说最近伪装者过了又是琅琊榜,梅长苏又迷到了万千少女,不知道钟汉良的新戏啥时候上映啊,汉良哥,快快出来挑战胡歌吖...

weinxin
我的微信公众号
我的微信公众号扫一扫

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: