Backbone源码分析(一)
距离上一篇博客有一段时间了,期间各种琐事萦绕。最主要的一件是,当我差不多将整个dojo核心源码看完,惊讶的发现dojo1.*的设计以是老态龙钟之象,而我沉溺在dojo中太久,已经不知道前端世界变成了什么样。这无异于晴天霹雳,霹的我目瞪口呆、汗流满面,惶惶不可终日。索性亡羊补牢为时未晚,这段期间虽有各种烦心事,但还能于百烦之中腾出点时间,看看源码已经是万中之幸。各种前端类库如浩瀚星辰,面对它们才能感觉到自身技术的浅薄,自身能力的低微。初出茅庐天下无敌,再练三年寸步难行,这就是我当前最真切的体悟。现在的我只能找几个经典类库,悉心研究,戒骄戒躁,诚诚恳恳的去学习大牛的代码,今天为大家带来backbone的源码研究。能力浅薄,不足之处请各位大牛不吝斧正。
从backbone的总体结构来看,是一个立即执行的函数表达式,参数是一个匿名函数。(function(){})()和(function(){}())的目的是将函数声明转换为函数表达式,消除Js引擎在识别函数声明和函数表达式上的歧义,除了小括号外还有其他运算符能够做到,详细介绍可以参照这篇文章:js中(function(){…})()立即执行函数写法理解
- (function(factory) {
- //模块定义
- })(function(root, Backbone, _, $) {
- //Backbone
- });
模块处理内容如下:
- function(factory) {
- // Establish the root object, `window` (`self`) in the browser, or `global` on the server.
- // We use `self` instead of `window` for `WebWorker` support.
- //拿到当前环境中的全局对象;浏览器中为window,self也是浏览器提供的一个全局对象,始终指向window
- //server端的运行环境则提供global这个全局对象
- var root = (typeof self == 'object' && self.self === self && self) ||
- (typeof global == 'object' && global.global === global && global);
- // Set up Backbone appropriately for the environment. Start with AMD.
- //如果有amd加载器则将Backbone定义包装成amd加载器可识别的模块
- if (typeof define === 'function' && define.amd) {
- //AMD规范定义两个全局函数define和requrie,并且规定define有个amd属性,来区分amd的define和普通名为define的函数
- define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
- // Export global even in AMD case in case this script is loaded with
- // others that may still expect a global Backbone.
- root.Backbone = factory(root, exports, _, $);
- });
- // Next for Node.js or CommonJS. jQuery may not be needed as a module.
- //如果运行在Node端,则将Backbone包装成CommonJs的模块
- } else if (typeof exports !== 'undefined') {
- var _ = require('underscore'), $;
- try { $ = require('jquery'); } catch (e) {}
- factory(root, exports, _, $);
- // Finally, as a browser global.
- //以上两种情况都没有,则以最简单的执行函数方式,将函数的返回值作为全局对象Backbone
- } else {
- root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
- }
- }
factory部分整体结构如下:
- function(root, Backbone, _, $) {
- // Backbone.Events
- // ---------------
- // Backbone.Model
- // --------------
- // Backbone.Collection
- // -------------------
- // Backbone.View
- // -------------
- // Backbone.Router
- // ---------------
- // Backbone.History
- // ----------------
- // Helpers
- // -------
- }
本篇文章中,我们简单学习两个比较有用的工具方法:noConflict和extend。
首先介绍noConflict模式。这是jquery发明的使用方法,之后大家争相相仿。主要原理是因为JavaScript采用的词法作用域(通过阅读变量定义在内的少数几行代码就能知道变量的作用域),函数的作用域由定义时决定而不是由函数调用时决定的,所以noConflict运行时能够访问到previousBackbone变量。如果已经有全局的Backbone变量,先将全局的Backbone变量暂存在previousBackbone内,当调用noConflict时,全局的Backbone指向之前暂存在previousBackbone中的Backbone,而返回的this关键字指向该factory函数中定义的Backbone对象。
- // Save the previous value of the `Backbone` variable, so that it can be
- // restored later on, if `noConflict` is used.
- var previousBackbone = root.Backbone;
- // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
- // to its previous owner. Returns a reference to this Backbone object.
- Backbone.noConflict = function() {
- root.Backbone = previousBackbone;
- return this;
- };
下面介绍extend方法,extend方法常见于大多数的JavaScript类库中,来实现继承父类创造子类。关于继承的文章,请看我的这篇文章JavaScript面向对象之我见,这里直接介绍源码了。
- // Helper function to correctly set up the prototype chain for subclasses.
- // Similar to `goog.inherits`, but uses a hash of prototype properties and
- // class properties to be extended.
- //protoProps放置到子类原型上的属性
- //staticProps模拟静态属性,直接放置到子类上
- var extend = function(protoProps, staticProps) {
- var parent = this;//利用局部变量保存this关键字
- var child;
- // The constructor function for the new subclass is either defined by you
- // (the "constructor" property in your `extend` definition), or defaulted
- // by us to simply call the parent constructor.
- //如果protoProps中有constructor属性,则将constructor指向的函数作为构造函数
- if (protoProps && _.has(protoProps, 'constructor')) {
- child = protoProps.constructor;
- } else {//没有构造函数,则利用一个默认的函数作为构造函数。
- //基本上属于组合式继承
- child = function(){ return parent.apply(this, arguments); };
- }
- // Add static properties to the constructor function, if supplied.
- //underscore中的方法,与常见的mixin函数类似
- _.extend(child, parent, staticProps);
- // Set the prototype chain to inherit from `parent`, without calling
- // `parent`'s constructor function and add the prototype properties.
- //将child的原型链与parent.prototype关联。
- //_.create函数,的作用类似Object.create,第一个参数是要被继承的原型对象,第二个参数是要混入到新对象的键值对
- child.prototype = _.create(parent.prototype, protoProps);
- child.prototype.constructor = child;//原型中的constructor属性指向child
- // Set a convenience property in case the parent's prototype is needed
- // later.
- child.__super__ = parent.prototype;//设置一个私有属性指向父类的原型
- return child;
- };
而后将所有Backbone对外的提供的构造函数的extend属性都指向上文的extend函数,这样大家都有了派生子类的功能。
- // Set up inheritance for the model, collection, router, view and history.
- Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
以上就是本文的主要内容,稍后将为大家带来Model与Collection的解析。
Backbone源码分析(一)的更多相关文章
- Backbone源码分析(三)
Backbone源码分析(一) Backbone源码分析(二) Backbone中主要的业务逻辑位于Model和Collection,上一篇介绍了Backbone中的Model,这篇文章中将主要探讨C ...
- Backbone源码分析-Backbone架构+流程图
作者:nuysoft/高云/nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. Backbone0.9.1源码分析分析系列 jQuery1.6.1源码分析系 ...
- Backbone源码分析(二)
在传统MVC框架模式中,Model承担业务逻辑的任务.Backbone作为一个mvc框架,主要的业务逻辑交由Model与Collection来实现.Model代表领域对象,今天主要学一下Model源码 ...
- Backbone.js源码分析(珍藏版)
源码分析珍藏,方便下次阅读! // Backbone.js 0.9.2 // (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. // Backbone ...
- Backbone设计思路和关键源码分析
一. Backbone的江湖地位: backbone作为一个老牌js框架为大规模前端开发提供了新的开发思路:前端MVC模式,这个模式也是前端开发演变过程中的一个重要里程碑,也为MVVM和Redux等开 ...
- Backbone.js 0.9.2 源码分析收藏
Backbone 为复杂Javascript应用程序提供模型(models).集合(collections).视图(views)的结构.其中模型用于绑定键值数据和自定义事件:集合附有可枚举函数的丰富A ...
- Backbone源码解析(六):观察者模式应用
卤煮在大概一年前写过backbone的源码分析,里面讲的是对一些backbone框架的方法的讲解.这几天重新看了几遍backbone的源码,才发现之前对于它的理解不够深入,只关注了它的一些部分的细节和 ...
- 【 js 基础 】【 源码学习 】backbone 源码阅读(二)
最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(source-code-study)进行参考交流,有详细的源码注释,以及知识总结,同时 ...
- Yolov3&Yolov4网络结构与源码分析
Yolov3&Yolov4网络结构与源码分析 从2018年Yolov3年提出的两年后,在原作者声名放弃更新Yolo算法后,俄罗斯的Alexey大神扛起了Yolov4的大旗. 文章目录 1. 论 ...
随机推荐
- Python +crontab定时备份目录发送邮件
公司有一台静态页面展示服务器仅供给客户展示我们做的项目,当时买的时候是最低配,也就是磁盘空间为20G的系统盘,考虑到代码量很小所以没有另加磁盘,后来项目多了,就写了个crontab 定时备份目录. 就 ...
- [转]序列化悍将Protobuf-Net,入门动手实录
最近在研究web api 2,看了一篇文章,讲解如何提升性能的, 在序列化速度的跑分中,Protobuf一骑绝尘,序列化速度快,性能强,体积小,所以打算了解下这个利器 1:安装篇 谷歌官方没有提供.n ...
- NoSql数据库初探-mongoDB环境搭建
NoSQL数据库一改关系型数据库的缺点,更容易的集成.分布式.无模式.故障恢复等特点,正在一步步餐食关系型数据库的市场,作为一个与时俱进的码农了解一下新技术是必须的,尤其是在读了<NoSql精粹 ...
- I Could Have Danced All Night
百老汇著名音乐剧<窈窕淑女(My Fair Lady)>中脍炙人口的经典歌曲. Bed, bed ,I couldn't go to bed床,床,我不能上床去 My head's too ...
- VadRoot枚举进程模块在Windows7下的完整实现
原理小伟的小伟在http://bbs.pediy.com/showthread.php?t=66886说的挺清楚了,Windows7下有一些变化,使用NtQueryVirtualMemory来枚举 ...
- Ubuntu菜鸟入门(六)—— 有道词典安装
一.在有道辞掉官网上下载安装包: youdao-dict_1.1.0-0-ubuntu_amd64.deb 二.安装 1.打开下载目录,进行安装 sudo dpkg -i youdao-dict_1. ...
- IDEA快捷键+使用小技巧
一 常用快捷键 Alt+回车 导入包,自动修正,当引入的类需要异常捕获的时候 Ctrl+Shift+Space 自动补全代码,"new"字符,还可以引入强制转换的 Ctrl-Alt ...
- MIT 6.828 JOS学习笔记12 Exercise 1.9
Lab 1中Exercise 9的解答报告 Exercise 1.9: 判断一下操作系统内核是从哪条指令开始初始化它的堆栈空间的,以及这个堆栈坐落在内存的哪个地方?内核是如何给它的堆栈保留一块内存空间 ...
- node - glob模块
node的glob模块允许你使用 *等符号, 来写一个glob规则,像在shell里一样,获取匹配对应规则的文件. 这个glob工具基于javascript.它使用了 minimatch 库来进行匹配 ...
- 《UML大战需求分析》阅读随笔(四)
状态机图(State Machine Diagram),状态机图是通过描述某事物状态的改变来展现流程的.一般适用于流程围绕某个事物展开,例如请假的流程就围绕请假条的展开.语法,开始于结束符号,实心圆表 ...