浏览sea.js源码小结

sea.js想处理的题目

  1. 恼人的定名争执

  2. 啰嗦的文件依靠

对应带来的优点 Sea.js 带来的两大优点:

  1. 经由历程 exports 暴露接口。这意味着不须要定名空间了,更不须要全局变量。这是一种完全的定名争执处理方案。

  2. 经由历程 require 引入依靠。这能够让依靠内置,开辟者只需体贴当前模块的依靠,其他事变 Sea.js 都邑自动处理好。对模块开辟者来讲,这是一种很好的 关注度星散,能让顺序员更多地享用编码的兴趣。

API速查

1. seajs.config
2. seajs.use
3. define
4. require
5. require.async
6. exports
7. module.exports

sea.js的实行历程

启动

script标签引入sea.js文件,seajs.config(data)启动设置函数,config函数会会兼并一切config设置,seajs.use = function(ids, callback),启用主剧本

运转历程

主剧本启动以后,起首应用request模块要求主剧本(天生script标签插进去head标签中),然后依据正则剖析模块define的依靠,并对依靠递归剖析其依靠。
在运转历程当中,经由历程监听发布者形式,体系内置了8个事宜,可用于开辟插件。

resolve       -- 将 id 剖析成为 uri 时触发
load          -- 最先加载文件时触发
fetch         -- 详细猎取某个 uri 时触发
request       -- 发送要求时触发
define         -- 实行 define 要领时触发
exec         -- 实行 module.factory 时触发
config         -- 挪用 seajs.config 时触发
error          -- 加载剧本文件涌现 404 或其他毛病时触发

全局挂载

一切相干数据末了悉数挂载在window.seajs下,包含要领及模块数据。

小学问点

exports与module.exports

exports 仅仅是 module.exports 的一个援用。在 factory 内部给 exports 从新赋值时,并不会转变 module.exports 的值。因而给 exports 赋值是无效的,不能用来变动模块接口。

//源码以下
// Exec factory
var factory = mod.factory;

var exports = isFunction(factory) ?
  factory.call(mod.exports = {}, require, mod.exports, mod) :
  factory

关于动态依靠

有时会愿望能够运用 require 来举行前提加载:

if (todayIsWeekend)
  require("play");
else
  require("work");

但请切记,从静态剖析的角度来看,这个模块同时依靠 play 和 work 两个模块,加载器会把这两个模块文件都下载下来。 这类情况下,引荐运用 require.async 来举行前提加载。

//sea.js源码以下
require.async = function(ids, callback) { //可传入回调函数
  Module.use(ids, callback, uri + "_async_" + cid())  //——async_英语标识这个剧本是异步加载的,cid用于消灭缓存
  return require //返回require轻易链式挪用
}

在开辟时,Sea.js 是怎样晓得一个模块的详细依靠呢?

a.js

define(function(require, exports) {
  var b = require('./b');
  var c = require('./c');
});

Sea.js 在运转 define 时,接收 factory 参数,能够经由历程 factory.toString() 拿到源码,再经由历程正则婚配 require 的体式格局来获得依靠信息。依靠信息是一个数组,比方上面 a.js 的依靠数组是:[‘./b’, ‘./c’]

//源码以下

// Parse dependencies according to the module factory code
if (!isArray(deps) && isFunction(factory)) {  
  deps = typeof parseDependencies === "undefined" ? [] : parseDependencies(factory.toString()) //parseDependencies是应用正则剖析依靠的一个函数
}

时刻动身函数Emit

// Emit event, firing all bound callbacks. Callbacks receive the same
// arguments as `emit` does, apart from the event name
var emit = seajs.emit = function(name, data) {
  var list = events[name]

  if (list) {
    // Copy callback lists to prevent modification
    list = list.slice()

    // Execute event callbacks, use index because it's the faster.
    for(var i = 0, len = list.length; i < len; i++) {
      list[i](data)
    }
  }

  return seajs
}

重要看这个部份list = list.slice(),解释是防备拷贝该时刻的回调函数,防备修正,疑心了一下。

原因是Javascript中赋值时,关于援用数据范例,都是传地点。
所以这里,假如想防备触发事宜的历程当中回调函数被变动,必需对这个list数组举行拷贝,而并不是只是将list指向events[name]的地点。

依据debug值设置是不是删除动态插进去的剧本

// Remove the script to reduce memory leak
      if (!data.debug) {
        head.removeChild(node)
      }

这里思索了蛮久,为何能够删除动态插进去的剧本?如许剧本还会见效吗?

起首,必需相识计算机内存分为

  1. 静态数据区 (用来寄存顺序中初始化的全局变量的一块内存地区)

  2. 代码区 (一般用来寄存实行代码的一块内存地区)

  3. 栈区 (栈在历程运转时发生,一个历程有一个历程栈。栈用来存储顺序暂时寄存的局部变量,即函数内定义的变量 不包含static 范例的。函数被挪用时,他的形参也会被压栈。

  4. 堆区 (用于寄存历程运转中被动态分派的内存段,它的大小并且不牢固,可动态扩展。当历程挪用malloc等分派内存时,新分派的内存被动态的添加到堆上(堆被扩展),当应用free等函数开释内存时,被开释的‘ 内存从堆中剔除)

这些在Javascript中都被屏障了,大部份时刻我们都不须要斟酌,然则假如要深切相识的话,则是必需要晓得的学问。

起首HTML文档中的JS剧本在计算机中作为指令被读入内存,以后最先实行,CPU最先一条一条指令读取,比方,读取到var cool = "wilson"时,就会在内存中分派一个6字符大小的内存,一个function也一样会在内存中占有肯定大小。所以,当指令悉数运转完以后,指令自身实在已没有用了,然则依然给占有了一部份内存。
当你点击按钮触发一个回调函数时,并不是去读取指令,而是读取内存中这个回调函数的地点。所以删除这些动态加载的JS文件是没有题目的。

ID 和途径婚配准绳

所谓 ID 和途径婚配准绳 是指,运用 seajs.use 或 require 举行援用的文件,假如是签字模块(即定义了 ID 的模块),会把 ID 和 seajs.use 的途径名举行婚配,假如一致,则准确实行模块返回效果。反之,则返回 null。

对 module.exports 的赋值须要同步实行,不能放在回调函数里。下面如许是不可的

// x.js
define(function(require, exports, module) {

  // 毛病用法
  setTimeout(function() {
    module.exports = { a: "hello" };
  }, 0);

});

//在 y.js 里有挪用到上面的 x.js:

// y.js
define(function(require, exports, module) {

  var x = require('./x');

  // 没法马上获得模块 x 的属性 a
  console.log(x.a); // undefined

});

WilsonLiu’s blog首发地点:http://blog.wilsonliu.cn

    原文作者:WilsonLiu95
    原文地址: https://segmentfault.com/a/1190000005802224
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞