《JavaScript框架设计》——2.4 define方法
本节书摘来自异步社区《JavaScript框架设计》一书中的第2章,第2.4节,作者:司徒正美著,更多章节内容可以访问云栖社区“异步社区”公众号查看
2.4 define方法我们再来看define方法,打个比方,它与require的关系就是内应外合。define是应,require是合。require拥有加载器90%的调度资源,以围城姿态攻打我们封闭的JavaScript模块。JavaScript模块则由一个“内鬼”define来看守城门。当require发出请求,define就打开城门,模块被兼并到mass Framework的“庞大帝国内”!
define有3个参数,前面两个为可选,事实上这里的ID没什么用,就是给开发者看的,它还是用getCurrentScript方法得到script节点路径做ID,deps没有就补上一个空数组。在mass中,先根据浏览器的情况对模块进行分级,一些模块是专门用于打补丁的,只对IE6、IE7、IE8有用,但对Chrome没有用,这个我们在require时就自动排除它。但合并后,我们不得不把它们都加上(因为不知道面对的是什么浏览器),mass设置一个参数,用于忽略执行这个补丁模块的工厂函数,保证框架用浏览器的原生API执行。这个参数就设置在define中,为一个布尔,如果为true就跳过。
此外,define还要考虑循环依赖的问题。比如说加载A,要依赖B与C,加载B,要依赖A与C,这时A与B就循环依赖了。A与B在判定各自的deps中的键值都是2时才执行,结果都无法执行了。
define的源码:
window.define = $.define = function(id, deps, factory) { var args = $.slice(arguments); if (typeof id === "string") { var _id = args.shift(); if (typeof args[0] === "boolean") { //用于文件合并,在标准浏览器中跳过补丁模块 if (args[0]) { return; args.shift(); if (typeof args[0] === "function") { args.unshift([]); } //上线合并后能直接得到模块ID,否则寻找当前正在解析中的script节点的src作为模块ID //现在除了Safari外,我们都能直接通过getCurrentScript一步到位得到当前执行的script节点 //Safari可通过onload+delay闭包组合解决 id = modules[id] modules[id].state = 1 ? _id : getCurrentScript(); factory = args[1]; factory.id = _id; //用于调试 factory.delay = function(id) { args.push(id); var isCycle = true; try { isCycle = checkCycle(modules[id].deps, id); } catch (e) { if (isCycle) { $.error(id + "模块与之前的某些模块存在循环依赖"); delete factory.delay; //释放内存 require.apply(null, args); //0,1,2 -- 1,2,0 if (id) { factory.delay(id, args); } else { //先进先出 factorys.push(factory);
checkCycle方法:
function checkCycle(deps, nick) { //检测是否存在循环依赖 for (var id in deps) { if (deps[id] === "司徒正美" modules[id].state !== 2 (id === nick || checkCycle(modules[id].deps, nick))) { return true; }
define与require互相调用的示意如图2.1所示。
▲图2.1
至此整个加载器就完成了。现在的难点转为我们如何判定当前模块的加载情况,如何知道它的模块名,如何排查它的对应的链接是否有效。为此mass动用一个modules对象,两个数组(loadings与factory)。小小一个加载器,里面的注释就提及到许多兼容性问题,真正与DOM打交道还没有开始呢!
最后看一下mass加载器,加载自己框架的ajax、node模块一共做了多少事吧!
require("ajax, node", function($) { $.log("加载完成!")
Firefox20会加载这么多模块,如图2.2所示。
▲图2.2
IE10在IE7模式下会加载如下模块,如图2.3所示。
▲图2.3
由于使用了模块化,我们就可以分级,对旧版本IE使用体积更庞大的query模块,其他则使用query_neo,并且多了许多补丁模块。
此外,mass加载器会把加载过程全部记录下来,大家可以直接在Firefox看到这些消息,如图2.4所示。
▲图2.4
模块加载器会让我们的前端开发变得更为工业化,维护调试都非常方便,强烈建立大家在工作时使用。现在国内主流的几个加载器seajs、requirejs、mass、oyejs都是比较好的选择。
【Unity3D 灵巧小知识点】☀️ | 使用宏定义和Application.platform判断运行平台 Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。 也可以简单把 Unity 理解为一个游戏引擎,可以用来专业制作游戏!
[原创]Javascript模拟“类”的综合实现方式以及部分细节【截至ES6】 前言 最近几个旧项目里使用的图片编辑插件出现Bug, 经Review 后确定需要在其内外均做些改动,但是头疼的发现部分页面里的JavaScript 代码被冗余了NN次。部分新同事堆叠了大量的过程式的脚本块(几乎没有利用面向对象封装的概念-虽然面向对象也按需择时),改起来挺累(而且几个项目里各自不同)。
使用 ES6 编写更好的 JavaScript Part II:深入探究 [类] 本文讲的是使用 ES6 编写更好的 JavaScript Part II:深入探究 [类],从功能上来讲,class 声明就是一个语法糖,它只是比我们之前一直使用的基于原型的行为委托功能更强大一点。本文将从新语法与原型的关系入手,仔细研究 ES2015 的 class 关键字。文中将提及以下内容:
异步社区 异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。
相关文章
- 细说JavaScript单线程的一些事
- 移动端基于HTML模板和JSON数据的JavaScript交互
- JavaScript中数组元素删除的七大方法汇总
- Windows Store App JavaScript 开发:选取文件和文件夹
- javascript设为首页、加入收藏
- javascript 清空数组的方法
- [Functional Programming ADT] Debug a Functional JavaScript composeK Flow
- [Javascript] Understanding the .constructor property on JavaScript Objects
- [React Flow] Up and Running with Facebook Flow for Typed JavaScript
- [Javascript] Web APIs: Persisting browser data with window.localStorage
- Javascript网页截屏的方法
- 你想不到的压缩方法:将javascript文件压缩成PNG图像存储
- [Javascript] Singleton Pattern
- [Javascript] Understanding the difference between .prototype and .__proto__ in JavaScript
- [Javascript] Convert a Callback-Based JavaScript Function to a Promise-Based One
- [Javascript] Deep Search nested tag element in DOM tree
- [Javascript] JavaScript Array Methods in Depth - push
- [Javascript] How to use JavaScript's String.replace
- JavaScript实现单词首字母大写的方法总汇
- Javascript定义类(class)的三种方法
- Javascript异步编程的4种方法
- javascript(js) Uint8Array转普通数组(int数组)数组拼接concat Uint8Array没有concat()方法
- javascript中的正则表达式
- 【 华为OD机试 2023】 最快到达医院的方法(C++ Java JavaScript Python)
- [连载]JavaScript讲义(02)--- JavaScript核心编程
- python web py入门(37)- javascript的switch-case语句
- web前端框架Javascript开发基础之JavaScript作用域
- Javascript 创建对象方法的总结