用纯Javascript打造类似NodeJS的模块载入系统

用纯Javascript打造类似NodeJS的模块载入系统2011-11-15 18:35:46     我来说两句      收藏    我要投稿

 http://www.2cto.com/kf/201111/111190.html

 

NodeJS的模块系统有两个重要的特点:

 

1. 模块中直接用var定义的变量是仅作用与当前模块的,而不是全局。

 

2. 每个模块中都可以使用require和module这两个“全局变量”。之所以打上引号,因为它们其实是每个模块都有的通用实例,不同模块中的实例是不一样的。

 

也许你会认为这两个特性和我们在浏览器中使用的Javascript性质有很多不同,一定是NodeJS运行环境提供的native特性,那就不一定了。尽管没有研究过NodeJS是如何实现的,但是我们用纯JavaScript完全可以做出一样的模块系统。这其实只要要用到一个Javascript中很少用的语法:new Function()。

 

 

 

Javascript中除了用function func(){}来定义一个函数之外,还可以用new Function()来创建一个函数。Function是Javascript中所有函数的prototype,即所有函数的基类。通过给Function.prototype增加属性可以给所有的函数实例增加属性,这也是大家相对常用的一个做法。今天要给大家介绍的是通过直接new Function()来创建一个函数,尽管这被认为性能不好,但在某些特殊场景能做到一些很有用的功能。

 

 

new Function()的详细语法格式是:

 

 

new Function(args, body) 

这里的args是一个字符串,表示函数的参数,参数之间用逗号隔开,而body则是函数体本身。比如:

var add = new Function('x, y', 'return x + y;');

这样创建的函数就等价于:

 

var add = function(x, y){ 

     return x + y; 

这两者效果没有任何区别,通常我们也只会用第二种做法,因为有更好的可读性。

 

 

现在我们来看new Function的两种潜在应用场景:

1. 避免命名冲突

大家知道通过<script>标签引入的Javascript文件是全局的,每个文件中定义的变量都是全局的,这时为了避免命名冲突,可以通过如下的小技巧:

 

(function(){ 

     var x = 0; 

     //my code 

})(); 

通过外包一个函数并立刻调用,可以做成一个闭包,其中的变量的作用域就只局限于函数体之内。从而避免了与其它的文件之间的命名冲突。但是在有些情况下,我们需要使用一个第三方的Javascript文件或者因为某些原因而无法修改的文件,它完成某个独立的任务,但是其中定义了一些全局变量。这些文件无法被修改成使用上面提到的方法来避免命名冲突。这时我们的new Function()就可以发挥作用了。这时我们不是通过<script>引入Javascript文件,而是通过XMLHttpRequest获得Javascript文件的内容,然后用如下的方式来执行这个Javascript:

 

var result = (new Function('', jsCode + '; return {x: x}'))(); 

这样,我们相当于也是在jsCode外面包装了一层function,并且,我们把需要用的的结果作为返回值返回出来,供外面程序使用。当然,对于大部分独立的文件,我们并不一定需要返回值,而只是需要执行一下即可。下面来看下一个应用场景。

 

 

2. 打造自己的模块载入系统

这也是上一种应用场景的一个延伸,既然我们通过这种方式来载入Javascript文件,何不将其做成一个通用的模块载入系统,供自己的项目使用。从而不用每个文件都外包一层function来避免命名冲突。其实如果大家用过NodeJS,就也许知道,NodeJS中的每个模块中定义的变量都是局限于当前模块的,不会被其它模块直接使用。而且每个模块中还有一个默认的require和module变量,这两个每个模块中都可以像使用全局变量一样使用,但它们却又不是全局变量,NodeJS文档中写的也很清楚,它们在各个模块中都是不同的实例。这样,一个模块都它们进行的修改并不会影响到其它模块。你也许会认为这一定是NodeJS的native环境提供的特殊功能,但实际上,我们完全可以用纯Javascript打造出一个同样的模块机制,只需对上面提到的例子做一点修改,比如这个loader是有类似如下的代码:

 

var require = getRequireInstance(); 

var module = getModuleInstance(); 

 //通过XMLHttpRequest获得要载入的Javascript文件的代码 

var moduleText = getModuleText();   

//执行模块代码,并“注入”require和module变量。 

(new Function('require, module', moduleText))(require, module); 

怎么样,是不是很简单?new Function()虽然是一个很少用的功能,但是确实非常灵活,更多应用场景就靠大家继续挖掘了

 

摘自 Dojo中文博客-

时间: 2024-09-12 22:13:17

用纯Javascript打造类似NodeJS的模块载入系统的相关文章

使用纯javascript实现放大镜效果

 本文给大家分享的是使用纯javascript实现放大镜效果的代码,并附上封装的步骤,做电商程序的小伙伴们一定不要错过.     jd或者淘宝的具体商品有个放大镜的效果.虽然网上类似插件琳琅满目,应用到项目上有诸多不便,自己抽点时间自己写了个类似插件,积累下代码,何乐而不为呢!!let'go: 打算把此特效封装成个插件,先把最基本的算法实现,然后再一步步封装吧: 最终实现效果: html 代码:   代码如下: <div id="Magnifier"></div>

Apache Avro 纯 JavaScript 实现 avsc

avsc 详细介绍 avsc 是 Apache Avro 的纯 JavaScript 实现. 特性: 完整的 Avro 架构支持,包括递归架构, sort order, 以及 schema evolution. 快速!速度相当于 JSON 的两倍,同时更少的编码(varies per schema). 无依赖, avsc 甚至可以在浏览器运行 表现: 解码吞吐率的示意图(越高越好): 库比较: node-avsc, this package. node-json, built-in JSON s

CSS3网页制作实例:纯CSS3打造的精致时钟

文章简介:在css3的渲染下,拥有华丽的视觉界面,这个纯css3精致时钟,你值得拥有! 今天为大家分享一个纯CSS3打造的精致时钟,没有用到任何的图片和 js .该时钟有时针.分针以及秒针,在时钟的圆盘内,都有详细的刻度标记,在时间中央还有数字时钟显示,功能可谓十分强大,界面十分精致. 在css3的渲染下,拥有华丽的视觉界面,这个纯css3精致时钟,你值得拥有! 其主要的实现原理是用animation.transform等属性来实现时钟的走动以及数字时钟的跳动:再结合使用linear-gradi

纯javascript实现四方向文本无缝滚动效果

  本文主要给大家分享了使用纯javascript实现的可控制的四方向文本无缝滚动的代码,效果非常不错,有需要的小伙伴可以参考下. 实现一个文本无缝滚动的效果: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

纯JavaScript实现HTML5 Canvas六种特效滤镜示例

实现了六款简单常见HTML5 Canvas特效滤镜,并且封装成一个纯JavaScript可调用的API文件gloomyfishfilter.js,程序源代码如下,感兴趣的朋友可以参考下哈   小试牛刀,实现了六款简单常见HTML5 Canvas特效滤镜,并且封装成一个纯JavaScript可调用的API文件gloomyfishfilter.js.支持的特效滤镜分别为: 1.反色 2.灰色调 3.模糊 4.浮雕 5.雕刻 6.镜像 滤镜原理解释: 1.反色:获取一个像素点RGB值r, g, b则新

使用纯javascript实现经典扫雷游戏

  使用纯javascript实现经典扫雷游戏         本文给大家分享的是个人刚开始学习javascript的时候写的仿windows经典的扫雷游戏的代码,当时只是写了下来,没加注释,这里补上,有需要的小伙伴可以参考下. 很久以前写的 当时都没写注释的 刚加上了 (尼玛,好多自己都不认识了 ... ) 不足的地方就是本来想写个游戏排名的统计的,等有空了再加上(好像每次都这么说 然后就等好久好久...) 还有就是没有实现:点击第一个格子不能是雷的功能 ? 1 2 3 4 5 6 7 8 9

纯Javascript实现ping功能的方法

 这篇文章主要介绍了纯Javascript实现ping功能的方法,实例分析了javascript实现ping功能的技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了纯Javascript实现ping功能的方法.分享给大家供大家参考.具体实现方法如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

纯javascript实现简单下拉刷新功能

 这篇文章主要介绍了纯javascript实现简单下拉刷新功能,没有借助任何的框架,十分简单实用,有需要的小伙伴来参考下吧.     代码很简单,实现的功能却很实用,直接奉上代码 CSS:   代码如下: <meta charset="utf-8" /> <title>Pull to Refresh</title> <meta name="viewport" content="width=device-width,

nodejs URL模块操作URL相关方法介绍

 这篇文章主要介绍了nodejs URL模块操作URL相关方法介绍,本文讲解了parse方法.format方法.querystring方法等,需要的朋友可以参考下     url模块 处理HTTP请求时url模块使用率超高,因为该模块允许解析URL.生成URL,以及拼接URL.首先我们来看看一个完整的URL的各组成部分. 代码如下: href ----------------------------------------------------------------- host path -