Backbone前端框架解读
作者: 京东零售 陈震
一、 什么是Backbone
在前端的发展道路中,前端框架元老之一jQuery对繁琐的DOM操作进行了封装,提供了链式调用、各类选择器,屏蔽了不同浏览器写法的差异性,但是前端开发过程中依然存在作用域污染、代码复用度低、冗余度高、数据和事件绑定烦琐等痛点。
5年后,Backbone横空出世,通过与Underscore、Require、Handlebar的整合,提供了一个轻量和友好的前端开发解决方案,其诸多设计思想对于后续的现代化前端框架发展起到了举足轻重的作用,堪称现代前端框架的基石。
通过对Backbone前端框架的学习,让我们领略其独特的设计思想。
二、 核心架构
按照MVC框架的定义,MVC是用来将应用程序分为三个主要逻辑组件的架构模式:模型,视图和控制器。这些组件被用来处理一个面向应用的特定开发。 MVC是最常用的行业标准的Web开发框架,以创建可扩展的项目之一。 Backbone.js为复杂WEB应用程序提供模型(models)、集合(collections)、视图(views)的结构。
◦ 其中模型用于绑定键值数据,并通过RESRful JSON接口连接到应用程序;
◦ 视图用于UI界面渲染,可以声明自定义事件,通过监听模型和集合的变化执行相应的回调(如执行渲染)。
如图所示,当用户与视图层产生交互时,控制层监听变化,负责与数据层进行数据交互,触发数据Change事件,从而通知视图层重新渲染,以实现UI界面更新。更进一步,当数据层发生变化时,由Backbone提供了数据层和服务器数据共享同步的能力。
其设计思想主要包含以下几点:
◦数据绑定(依赖渲染模板引擎)、事件驱动(依赖Events)
◦视图组件化,并且组件有了生命周期的概念
◦前端路由配置化,实现页面局部刷新
这些创新的思想,在现代前端框架中进一步得到了继承和发扬。
三、 部分源码解析
Backbone极度轻量,编译后仅有几kb,贯穿其中的是大量的设计模式:工厂模式、观察者模式、迭代器模式、适配器模式……,代码流畅、实现过程比较优雅。按照功能拆分为了Events、Model、Collection、Router、History、View等若干模块,这里摘取了部分精彩源码进行了解析,相信对我们的日常代码开发也有一定指导作用:
(1)迭代器
EventsApi起到一个迭代器分流的作用,对多个事件进行解析拆分,设计的非常经典,执行时以下用法都是合法的:
◦用法一:传入一个名称和回调函数的对象
modal.on({ "change": change_callback, "remove": remove_callback })
◦用法二:使用空格分割的多个事件名称绑定到同一个回调函数上
model.on("change remove", common_callback)
实现如下:
var eventsApi = function(iteratee, events, name, callback, opts) { var i = 0, names; if(name && typeof name === 'object') { // 处理第一种用法 if(callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback; for(names = _.keys(names); i < names.length; i++) events = eventsApi(iteratee, events, names[i], name[names[i]], opts); } else if(name && eventSplitter.test(name)) { // 处理第二种用法 for(names = name.split(eventSplitter); i < names.length; i++) events = iteratee(events, names[i], callback, opts); } else { events = iteratee(events, name, callback, opts); } return events; }
(2)监听器
用于一个对象监听另外一个对象的事件,例如,在A对象上监听在B对象上发生的事件,并且执行A的回调函数:
A.listenTo(B, "b", callback)
实际上这个功能用B对象来监听也可以实现:
B.on("b", callback, A)
这么做的好处是,方便对A创建、销毁逻辑的代码聚合,并且对B的侵入程度较小。实现如下:
Events.listenTo = function(obj, name, callback) { if(!obj) return this; var id = obj._listenId || (obj._listenId = _.uniqueId('l')); // 当前对象的所有监听对象 var listeningTo = this._listeningTo || (this._listeningTo = {}); var listening = listeningTo[id]; if(!listening) { // 创建自身监听id var thisId = this._listenId || (this._listenId = _.uniqueId('l')); listening = listeningTo[id] = {obj: obj, objId: id, id: thisId, listeningTo: listeningTo, count: 0}; } // 执行对象绑定 internalOn(obj, name, callback, this, listening); return this; }
(3)Model值set
通过option-flags兼容赋值、更新、删除等操作,这么做的好处是融合公共逻辑,简化代码逻辑和对外暴露api。实现如下:
set: function(key, val, options) { if(key == null) return this; // 支持两种赋值方式: 对象或者 key\value var attrs; if(typeof key === 'object') { attrs = key; options = val; } else { (attrs = {})[key] = val; } options || (options = {}); …… var unset = options.unset; var silent = options.silent; var changes = []; var changing = this._changing; // 处理嵌套set this._changing = true; if(!changing) { // 存储变更前的状态快照 this._previousAttributes = _.clone(this.attributes); this.changed = {}; } var current = this.attributes; var changed = this.changed; var prev = this._previousAttributes; for(var attr in attrs) { val = attrs[attr]; if(!_.isEqual(current[attr], val)) changes.push(attr); // changed只存储本次变化的key if(!_.isEqual(prev[attr], val)) { changed[attr] = val; } else { delete changed[attr] } unset ? delete current[attr] : (current[attr] = val) } if(!silent) { if(changes.length) this._pending = options; for(var i=0; i<changes.length; i++) { // 触发 change:attr 事件 this.trigger('change:' + changes[i], this, current[changes[i]], options); } } if(changing) return this; if(!silent) { // 处理递归change场景 while(this._pending) { options = this._pending; this._pending = false; this.trigger('change', this, options); } } this._pending = false; this._changing = false; return this; }
四、 不足(对比react、vue)
对比现代前端框架,由于Backbone本身比较轻量,对一些内容细节处理不够细腻,主要体现在:
◦视图和数据的交互关系需要自己分类编写逻辑,需要编写较多的监听器
◦监听器数量较大,需要手动销毁,维护成本较高
◦视图树的二次渲染仅能实现组件整体替换,并非增量更新,存在性能损失
◦路由切换需要自己处理页面更新逻辑
五、为什么选择Backbone
看到这里,你可能有些疑问,既然Backbone存在这些缺陷,那么现在学习Backbone还有什么意义呢?
首先,对于服务端开发人员,Backbone底层依赖underscore/lodash、jQuery/Zepto,目前依然有很多基于Jquery和Velocity的项目需要维护,会jQuery就会Backbone,学习成本低;通过Backbone能够学习用数据去驱动View更新,优化jQuery的写法;Backbone面对对象编程,符合Java开发习惯。
其次,对于前端开发人员,能够学习其模块化封装库类函数,提升编程技艺。Backbone的组件化开发,和现代前端框架有很多共通之处,能够深入理解其演化历史。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
使用 HertzBeat 对 线程池框架 DynamicTp 进行监控实践
使用 HertzBeat 对 线程池框架 DynamicTp 进行监控实践! 线程池框架 DynamicTp 介绍 DynamicTp 是Jvm语言的基于配置中心的轻量级动态线程池,内置监控告警功能,可通过SPI自定义扩展实现。 支持对运行中线程池参数的动态修改,实时生效。 实时监控线程池的运行状态,触发设置的报警策略时报警,报警信息推送办公平台。 定时采集线程池指标数据,配合像 grafana 这种可视化监控平台做大盘监控。 HertzBeat 介绍 HertzBeat 是一款开源,易用友好的实时监控系统,无需Agent,拥有强大自定义监控能力。 支持对应用服务,数据库,操作系统,中间件,云原生等监控,阈值告警,告警通知(邮件微信钉钉飞书短信 Slack Discord Telegram)。 其将Http,Jmx,Ssh,Snmp,Jdbc等协议规范可配置化,只需配置YML就能使用这些协议去自定义采集任何您想要采集的指标。您相信只需配置YML就能立刻适配一个K8s或Docker等新的监控类型吗? HertzBeat 的强大自定义,多类型支持,易扩展,低耦合,希望能帮助开发者和中小团队...
- 下一篇
Skywalking分布式追踪与监控:起始篇
Skywalking是由国内开源爱好者吴晟(原OneAPM工程师,目前在华为)开源并提交到Apache孵化器的产品,它同时吸收了Zipkin/Pinpoint/CAT的设计思路,支持非侵入式埋点。是一款基于分布式跟踪的应用程序性能监控系统。另外社区还发展出了一个叫OpenTracing的组织,旨在推进调用链监控的一些规范和标准工作。 OpenTracing 近年各种调用链监控产品层出不穷,呈现百花齐放的态势,为了避免碎片化,促进互操作性,社区诞生了一个叫做OpenTracing的标准化组织。 如上图所示:OpenTracing旨在标准化Trace数据结构和格式,其目的是: 不同语言开发的Trace客户端的互操作性,Java/.Net/PHP/Python/NodeJs等语言开发的客户端,只要遵循OpenTracing标准,就都可以对接OpenTracing兼容的监控后端。 Tracing监控后端的互操作性,只要遵循OpenTracing标准,企业可以根据需要替换具体的Tracing监控后端产品,比如从Zipkin替换成Jaeger/CAT/Skywalking等后端。 OpenTr...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7安装Docker,走上虚拟化容器引擎之路