博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js手札--关于AMD的简单分析
阅读量:7072 次
发布时间:2019-06-28

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

AMD中define常见的形式

define('alpha' ,['require', "exports", "module"], function(require, exports, module) {  var foo = require('foo');  module.exports = exports = function() {    foo.doSomething();  }});

参数

第一个是要定义的模块名字(id)

第二个是要用到的模块名,其实更专业点讲是定义的这个模块所依赖的模块名称
第三个回调函数,是要定义模块内容

分析define的回调函数

分析方法:替换部分代码进行分析

先来把回调中的require,exports,module替换了看看。

1.替换require

function callback(exports, module) {  // 假设foo是最简单的对象,把require('foo')换成最简答的对象看看  var foo = {    'doSomething': function() {}  };  module.exports = exports = function() {    foo.doSomething();  }}

那么其实已经不难看出,require其实就相当于是个查询函数吧,我给他传个对象名,它就能给我一个具体的对象。

var require = function(name) {  var modules = {'foo': {'doSomething': function() {}}};  return modules[name] || {};}

那么整个代码可以换成

var require = function(name) {  var modules = {'foo': {'doSomething': function() {}}};  return modules[name] || {};}function callback(exports, module) {  var foo = require('foo');  module.exports = exports = function() {    foo.doSomething();  }}

看起来好像有点道理哦,等会儿,等会儿,这里的modules又从哪儿冒出来的,哈哈哈,被发现了,别急慢慢来

2. 替换exports和module.exports

在替换之前,先来了解下exports和module.exports这两货是干啥的,而要了解他们先来看看模块是啥。

其实模块么,简单来说就是一个高级别的function,输入,处理,输出。至于为啥js的模块化为啥这么困难,这个问题不是三言两语就能解释清楚的,就不展开了(其实真实情况是,我也不清楚,哈哈哈)

既然模块要做输出,那么输出什么东西总要知道吧,而module.exports的作用就是这个,存储模块输出的内容。

也就是说,这个模块中要给外部使用的东西全放在module.exports里头了。废话真多,是的哈- -.

而要说清exports和module.exports的二三事,又不是件容易的事,简单理解,exports和module.exports指向同一内存区域。有兴趣可以看看。

那来改造一下,把module.exports,exports也提炼出来看看

var require = function(name) {  var modules = {'foo': {'doSomething': function() {}}};  return modules[name] || {};}var module = {};var module.exports = exports = {};function callback() {  var foo = require('foo');  module.exports = exports = function() {    foo.doSomething();  }}

define的推测

// 这里的id相当于模块名,deps就是需要依赖的模块名称列表define = function(id , deps, callback) {  callback(require, exports, module);};

晕,那require,exports,module跑哪儿溜达去了?加上去看看

define = function(id , deps, callback) {    var require = function(name) {    var modules = {'foo': {'doSomething': function() {}}};    return modules[name] || {};  }  var module = {};  var module.exports = exports = {};  callback(require, exports, module);};

看上去挺有道理的么,那么modules这玩意儿到底是哪儿冒出来的呢。

可以看出来modules 里面存放着的是foo模块的内容,那这些内容是怎么来的呢?通过foo的module.exports提供的啊。那么modules里面其实放的是,foo的module.exports。

而foo对于当前模块来说是外部的模块。而我想调用外面的东西,只有两种办法,要么传参数,要么通过全局变量(不过或许大神还有其他方案,我就只晓得这两种了)。define里面有的参数没有一个是存放module.exports的。那么答案呼之欲出了,modules是全局变量。

modules = {};function load(id, exports) {  (modules || (modules = {}))[id] = exports;}

再来看看完整的代码,变成啥样了

modules = {};function load(name, exports) {  (modules || (modules = {}))[name] = exports;}define = function(id, deps, callback) {    var require = function(name) {    return modules[name] || {};  }  var module = {};  var module.exports = exports = {};  callback(require, exports, module);  load(id, module.exports);};

到现在差不多已经成型了,那么这里的require, exports, module都是外来的模块吧bingo,其实callback里的模块都是根据deps来的,去掉require, exports, module

modules = {};function load(name, exports) {  (modules || (modules = {}))[name] = exports;}define = function(id, deps, callback) {    // 相当于  // var module = {};  // var module.exports = {};  var module = modules['module'];    // 相当于  //var require = function(name) {  //  return modules[name] || {};  //}  var require = modules['require'];  var args = deps.map(require);  callback.apply(null, args);  load(id, module.exports);};

来看define的另一种形式

define('alpha' ,['foo'], function(foo) {  return function() {    foo.doSomething();  }});

咦,精简了不少诶。没有exports了诶,会返回了么

modules = {};function load(name, exports) {  (modules || (modules = {}))[name] = exports;}define = function(id, deps, callback) {    var module = modules['module'];    var require = modules['require'];  var args = deps.map(require);  var exports = callback.apply(null, args);  load(id, exports || module.exports);};

OK,先告一段落了,累死我丫了。在慢慢优化吧,唉。

参考(关于exports 和 module.exports 的区别)

这篇文章很不赖。

人家大神已经说得非常好了。我在了浅薄的打个比方,我有个文件夹叫module.exports,然后我创建了一个超链接叫exports,那我在任何一个里面操作最终都会反应到另一个里,但如果我把超链接exports删了把它的指向地址改了,并不会影响真正的文件夹module.exports。

而有很多人明明已经改了超链接exports的指向地址(如:exports = 123;),再在超链接里面做了很多操作(如:exports.hello = 456;),那都不会对真正的文件夹module.exports起到任何作用(你是见不到module.exports.hello === 456的)。

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

你可能感兴趣的文章
Rsync全网数据同步备份及检查
查看>>
英特尔AI如何帮助修缮残垣断壁的长城,背后的奥秘找到了
查看>>
学习Java基础知识,打通面试关~十二接口与抽象类
查看>>
小米2系列板砖自救行动
查看>>
人脸识别竞争激烈机器人视觉或将成为下一热点
查看>>
今天,我们请来一波超龄儿童画出了他们眼中的AI……
查看>>
柬埔寨互联网创业终于起步了:青年们拿到一万美元投资都很开心
查看>>
阿里云聆听快讯,互通之链
查看>>
一条机器“龙”,堪称史上最快异形机器人!
查看>>
亦策软件参加中国第二届SaaS峰会--山东CIO 专场
查看>>
Ubuntu 16.04安装SecureCRT替代XShell
查看>>
NumPy 高级索引和数组概念
查看>>
数据库智能管理助手-CloudDBA
查看>>
双星闪耀,开创先河!蚂蚁金服安全实验室首次同时亮相BlackHat Asia 以及CanSecWest国际安全舞台...
查看>>
Windows7 中配置IIS7的方法(HTTP 错误 404.3 - Not Found)
查看>>
如何高效的将excel导入sqlserver?(转)
查看>>
ASP.NET MVC实践系列8-对查询后分页处理的解决方案
查看>>
让python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE等请求
查看>>
Volley
查看>>
马斯克的另一番“威胁论”:人类将成为人工智能的“宠物”
查看>>