backbone源码学习中的知识点整理(一)

一、self

var root = (typeof self == 'object' && self.self === self && self) || (typeof global == 'object' && global.global === global && global);

现代web之前的window.self和self

对于web页面,在默认状况下,下面4个写法都是等同的:

window === self // true window.window === window.self // true window.self === self // true window.window === self // true

其实真实情况还就是这样,并没有需要self出场的理由,唯一可能有作用的就是更语义地判断当前页面是否作为iframe嵌入了,直接:

parent === self // true表示作为iframe嵌入,false则表示被iframe嵌入了

在HTML5一些新特性出来之前,全局的self就是个没什么实用价值的半吊子。但是,随着HTML5一些新特性的到来,self开始慢慢登上正式的舞台,最常见的就是用在Service Workers或者Web Workers中。

无论是出来有段时间的Web Workers或者说是新晋宠儿Service Workers,本质上都是开启了另外的线程。

Workers开辟的新线程是没有“窗体”这个概念的,都是在浏览器背后悄悄运行的线程,没有窗体的概念也就意味着没有window对象。换句话说,Service Workers和Web Workers相关的脚本中是不能使用window这个对象的。那问题来了,我们希望在全局作用域里面做事情该怎么办呢?

我们可以使用self来表示全局作用域,注意,只能是光秃秃的self,window.self这样的写法是不行的。

举个简单的例子,假设我们注册一个Service Workers,Workers脚本在sw-test.js中,如下:

navigator.serviceWorker.register('/sw-test.js');

则我们希望Service Workers注册完毕干点什么事情,就可以在sw-test.js中这么写:

self.addEventListener('install', function(event) { // ... });

二、AMD

define(['underscore', 'jquery', 'exports'], function(_, $, exports) { //AMD的具体写法,这里不过多讲述 root.Backbone = factory(root, exports, _, $); });

AMD,全称 Asynchronous Module Definition,即异步模块加载机制。AMD 规范非常简单只有一个API,即 define 函数:

define([module-name?],[array-of-dependencies?],[module-factory-or-object]);

其中,

module-name:模块标识,可以省略

array-of-dependencies:所依赖的模块数组,可以省略

module-factory-or-object:模块的实现或者一个 JavaScript 对象

define 函数具有异步性,其首先会异步加载第二个参数中列出的依赖模块,当所有的模块被加载后,执行第三个参数的回调函数。

1)三个参数

define("A", ["require", "exports"], function(require, exports){ export.fun = function(){ return require("B").fun; } });

  上述代码定义了一个 A 模块,并且依赖于内置的 require,exports 模块,第三个参数是回调函数,可以直接使用依赖的模块,他们按依赖声明顺序作为参数提供给回调函数。

  require 函数是用来模块依赖,即获取模块的引用,即使模块没有作为参数定义,也能够被使用;

exports 定义 A 模块实体,在其上定义的任何属性和方法就是 A 模块的属性和方法。通过 exports.fun= … 就是为 A 模块定义了一个 fun 方法。

2)两个参数

define 函数允许省略第一个参数,因此定义一个匿名模块。这时候模块文件的文件名就是模块标识,即如果这个模块文件名为 A.js ,那么 A 就是模块名。可以在依赖项目中用 A 来依赖于这个匿名模块。这将带来一个好处,就是模块的高度可重用的。你拿来一个匿名模块,随便放在一个位置就可以使用它,模块名就是它的文件路径。这也很好的符合了 DRY(Don’t Repeat Yourself)原则。

define(['A'], function(A){ 
return { 
   fun: function(){ 
     return A.fun() + 2; } 
   };
});

3)一个参数 

define 的前面两个参数都可以省略;第三个参数有两种情况:一钟是 JavaScript 对象,另一种是一个函数。

  如果是对象,可以是包含方法的对象或者是只提供数据。后者和 JSONP非常类似,因此,AMD可以认为包含了一个完整的JSONP实现。模块演变为一个简单的数据对象,这样的数据对象是高度可用的,而且因为是静态对象,它也是CDN友好的,可以提高JSONP的性能。

  如果是函数,其用途之一是快速开发实现。适用于较小型的应用,该方式无需提前考虑需要引入的模块,只需使用时,require 即可。

define(function(){ var a = require("A"); })

define函数在执行的时候,会调用函数的 toString 方法,并扫描其中的 require 调用,提前载入这些模块,载入完成后再执行。

注意:Opera 不能很好的支持函数的 toString 方法,因此,在浏览器中它的适用性并不强。但是使用构建工具打包时,构建工具会扫描 require 并强制载入依赖模块。

三、commonJs

//nodejs或者CommonJS的加载规范,这里jQuery需要当作一个模块来加载

} else if (typeof exports !== 'undefined') { 
var _ = require('underscore'), $; 
try { $ = require('jquery'); } catch (e) {} factory(root, exports, _, $); 
}

Node 应用由模块组成,采用 CommonJS 模块规范。每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。

CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。

var x = 5; var addX = function (value) { 
return value + x; 
}; 
module.exports.x = x; 
module.exports.addX = addX;

require方法用于加载模块。

CommonJS模块的特点如下:

1、所有代码都运行在模块作用域,不会污染全局作用域。

2、模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。

3、模块加载的顺序,按照其在代码中出现的顺序。

为了方便,Node为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令。

如果你觉得,exports与module.exports之间的区别很难分清,一个简单的处理方法,就是放弃使用exports,只使用module.exports。

CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。

AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。

AMD规范允许输出的模块兼容CommonJS规范

define(function (require, exports, module){ 
var someModule = require("someModule"); 
var anotherModule = require("anotherModule"); 
someModule.doTehAwesome(); 
anotherModule.doMoarAwesome(); 
exports.asplode = function (){ 
someModule.doTehAwesome(); 
anotherModule.doMoarAwesome(); }; 
});

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/wangch5453/blog/3062617

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值