`
JadeLuo
  • 浏览: 425712 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

用纯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中文博客-

分享到:
评论

相关推荐

    Nodejs模块载入运行原理

    Node.js模块载入运行原理是理解其核心机制的关键部分,涉及到如何找到、解析和执行不同类型的模块。在Node.js中,模块大致分为四类:内置(builtin)模块、常量(constant)模块、本地(native)模块以及第三方模块...

    基于javaScript开发的图书管理系统+数据库+源码+项目展示+开发文档(毕业设计&课程设计&项目开发)

    使用MySQL+ExpressJS+AngularJS+NodeJS尝试开发的图书管理系统,开发前端后台模块,后台用ExpressJS和NodeJS搭建服务器,前端用AngularJS,样式用的Bootstrap。自己封装了数据库连接池的接口,利用Java项目MVC的思想...

    nodejs 内部资料 进程管理

    fork()方法与spawn()类似,但专门为Node.js的子进程提供,只需指定要执行的JavaScript文件模块即可。这四个方法的异同点,主要体现在如何启动子进程、执行的方式和使用的场景上。 在进程间通信方面,Master-Worker...

    基于JavaScript语言Web项目-图书管理系统

    使用MySQL+ExpressJS+AngularJS+NodeJS开发的图书管理系统,开发前端后台模块,后台用ExpressJS和NodeJS搭建服务器,前端用AngularJS,样式用的Bootstrap。自己封装了数据库连接池的接口,利用Java项目MVC的思想组织...

    nodejs个人博客开发第三步 载入页面

    本文将详细介绍如何在Node.js环境下开发个人博客的页面载入功能,并涵盖了模板引擎的使用、路由控制以及数据库的链接。 首先,模板引擎是页面载入的关键技术之一。本文选择了EJS作为博客前端模板引擎,它能够将JSON...

    node-segment:基于Node.js的中文分词模块

    可使用JavaScript编写自定义的分词模块 1、使用方法 安装: $ npm install segment --save 使用方法: // 载入模块 var Segment = require('segment'); // 创建实例 var segment = new Segment(); // 使用默认的识别...

    nodejs基础应用

    要使用http模块,需要先用require函数载入http模块。创建服务器时,通常使用http.createServer方法,该方法接受一个回调函数作为参数,这个回调函数会在有HTTP请求被发送到服务器时被调用。服务器创建后,需要调用...

    nodejs入门教程二:创建一个简单应用示例

    Node.js是一种基于Chrome V8引擎的JavaScript运行环境,它允许开发者使用JavaScript来编写服务器端的代码。Node.js使用事件驱动、非阻塞I/O模型,使其轻量又高效,特别适合处理大量并发访问,因此非常适用于网络应用...

    使用 Node.js 对文本内容分词和关键词抽取

    安装完成后,你可以通过`require`引入模块,并使用其提供的方法进行分词。例如: ```javascript var nodejieba = require("nodejieba"); var result = nodejieba.cut("帝国主义要把我们的地瓜分掉"); console.log...

    wit_workflow:微智2014前端开发工作流

    微智2014前端开发工作流 ...遵循CMD规范,书写规则类似与nodejs,关于的东西,这里不阐述,有兴趣的可以去seajs的官网查询 2、使用less开发css 是一款css的预处理语言,他有独立的运算能力,而且具有混合,变量等动

    xjs-framework:基于MVC模式设计的单页面应用框架

    个人使用前端开发集成框架,集成了单页应用框架以及前端项目自动构建工具,适用于中小型项目的快速开发。 API文档: 目录分类: dev/ 前端自动构建工具生成文件夹,存储编译过后的文件 src/ 前端资源文件夹 icons/ ...

    程序员面试刷题的书哪个好-front-end-interview:前端面试

    数据类型、面向对象、继承、闭包、插件、作用域、跨域、原型链、模块化、自定义事件、内存泄漏、事件机制、异步装载回调、模板引擎、Nodejs、JSON、ajax 等。 1.浅拷贝和深拷贝的区别 2.defer 和 async 的区别(JS ...

Global site tag (gtag.js) - Google Analytics