博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【SeaJS】【3】seajs.data相关的源码阅读
阅读量:5966 次
发布时间:2019-06-19

本文共 2829 字,大约阅读时间需要 9 分钟。

   在SeaJS官网上推荐了源码阅读顺序,本文并没有采用这个顺序,而是按个人习惯以调试官方示例的方式进行源码阅读。早期版本作者玉伯使用了几个闭包形式,本文源码版本为2.1.1,它的编码方式个人认为更加脚本化,该版本代码量不到1K。


1. 使用Chrome打开《》中的hello.html文件,按F12打开JavaScript控制台,依次选择Source > sea.js,可以看到SeaJS使用了一个大的闭包:

(function(global, undefined)

{  

   if(global.seajs){

      return;

   }

   //...略

})(this);



说明:this是Window对象,同时把Window对象赋值给global变量,这样在这个闭包中使用Window的地方均可以用global代替。



2. hello.html文件中使用<script s rc="../sea-modules/seajs/seajs/2.1.1/sea.js"></script>引入sea.js,所以浏览器解析html文件时会加载sea.js代码。加载完sea.js后Window对象结构如图一:

(图一)

3. 从上图中可以看到seajs的初始值的大体轮廓,下面我们看一下seajs.data值的由来:

// 定义seajs.data变量对象

var data = seajs.data = {};

// 定义seajs.data的事件集合

var events = data.events = {};


// 定义已加载模块的集合

var fetchedList = {};

data.fetchedList = fetchedList;

// 设置字符集

data.charset = "utf-8";

// 定义获取依赖模块个数方法

var _cid = 0;

function cid(){

   return _cid++;

}

data.cid =cid;

// 把document和location对象赋值给doc、loc

var doc = document;

var loc = location;

// 通过文档location对象获取hello.html文件所在的路径,并把其赋给data.cwd作为当前工作路径

var DIRNAME_RE = /[^?#]*\//

function dirname(path){

   return path.match(DIRNAME_RE)[0];

}

var cwd = dirname(loc.href);

data.cwd = cwd;

// 通过文档document对象读取hello.html文件中引入seajs的路径,并把其设置为加载路径

function getScriptAbsoluteSrc(node){

   return node.hasAttribute ? node.src : node.getAttribute("src", 4);

}

var scripts = doc.getElementsByTagName("script");

var loaderScript = doc.getElementById("seajsnode") || scripts[scripts.length - 1];

var loaderDir = dirname(getScriptAbsoluteloaderScript ) || cwd);

data.dir = loaderDir;


说明:dirname()函数的逻辑

(1)URL路径的基本知识

   常见URL写法如

   当在百度中搜索“url”字符串时,浏览器显示的url为http://www.baidu.com/s?wd=url,用?表示后面跟随的是参数;

   当在谷歌中搜索“url”字符串时,浏览器显示的url值为http://www.google.com.hk/#fp=11d84258cf3e1c4a&q=url,其中#是指导浏览器动作的,对服务端没有任何用途。关于URL中#号的作用,感兴趣的读者可以参考《http://www.ruanyifeng.com/blog/2011/03/url_hash.html》。

(2)入参path的值为file:///E:/seajs/officialsample/app/hello.html,而DIRNAME_RE正则表达式的含义原来“不是?或#的0个或多个字符 + / ”,由于*在正则表达式中是贪婪的,所以它匹配的值为[file:///E:/seajs/officialsample/app/],然后取集合中的第一个,所以函数返回的值为file:///E:/seajs/officialsample/app/




说明:getScriptAbsoluteSrc()函数的逻辑

function getScriptAbsoluteSrc(node){

   return node.hasAttribute ? node.src : node.getAttribute("src", 4);

}

(1)入参node的值为loaderScript,经上面初始化后loaderScript值为<script s rc="../sea-modules/seajs/seajs/2.1.1/sea.js" />

(2)在非IE6、IE7中node具有hasTrribute属性,所以此处为了兼容IE6、IE7这里使用了node.getAttribute("src", 4)方法,获取node对象中的src对应值


// 从加载路径中获取seajs所属路径作为根路径

var BASE_RE = /^(.+?\/)(\?\?)?(seajs\/)+/

data.base = (loaderDir.match(BASE_RE) || ["", loaderDir])[1];


说明:解释BASE_RE正则表达式

(1)它分为三部分^(.+?\/)、(\?\?)?和(seajs\/)+,第一部分匹配以xxx/格式开头的字符串,第二部分匹配零个或多个??,第三部分匹配一个或多个seajs/字符串

(2)match()表示:如果没有找到任何匹配的文本将返回null,否则它将返回一个数组。该数组的第0个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表式匹配的文本

(3)由于loaderDir的值为file:///E:/seajs/officialSmaple/sea-modules/seajs/seajs/2.1.1/,匹配之后的值为["file:///E:/seajs/", "file:///E:/", undefined, "seajs/" ],所以data.base的值为file:///E:/


转载地址:http://gjvax.baihongyu.com/

你可能感兴趣的文章
[React] React Router: Router, Route, and Link
查看>>
USACO holstein AC code
查看>>
linux下限制ip访问
查看>>
Winform文件下载之WebClient
查看>>
linux添加环境变量
查看>>
Dumpsys Input Diagnostics
查看>>
ASP.NET MVC 入门8、ModelState与数据验证
查看>>
被swoole坑哭的PHP程序员
查看>>
linux进程调度之 FIFO 和 RR 调度策略---SYSTEMTAP
查看>>
JSTL的相关使用
查看>>
ActiveMQ, RabbitMQ和ZeroMQ 选型关注点
查看>>
王垠:完全用Linux工作
查看>>
Understanding the Router
查看>>
红米3 Flyme5.1.9.5插桩适配长期不定时更新
查看>>
MySQL 5.6 for Windows 解压缩版配置安装(转)
查看>>
组件居中显示 安卓
查看>>
delete
查看>>
sql server生成不重复的时间字符串
查看>>
DataBase 之 数据库设计六大范式
查看>>
Struts与Struts2的区别
查看>>