标签:
概念:模块(Module)和包(Package)是Node.js最重要的支柱。开发一个具有一定规模的程序不可能只用一个文件,通常需要把各个功能拆分、分装、然后组合起来。模块正式为了实现这种方式而诞生,在浏览器JavaScript中,脚本模块的拆分和组合通常使用HTML的script标签来实现,Node.js提供了require函数来调用其他模块,而且模块都是基于文件,机制非常简单,模块和包的区别是透明的,因此经常不作区分。
模块和文件是一一对应的。一个Node.js文件就是一个模块,这个文件可能是JavaScript代码、JSON或者编译过的C/C++扩展。
var http=require(‘http’),其中http是Node.js的一个核心模块,通过require函数获取这个模块,然后使用其中的对象.
Node.js提供了exports和require两个对象,其中exports是模块的公开接口,require()是从外部获取一个模块的接口,下面提供了一个例子:
下面是module.js代码:
var name;
exports.setName=function(getName){
name = getName;
}
exports.setHello=function(){
console.log(‘hello‘+name);
}
下面的是getModule.js代码:
var myModule = require(‘./module‘);
myModule.setName(‘helios‘);
myModule.setHello();
输出是hellohelios
通过require函数得到的这个文件里面有暴露属性的对象(exports),因为require不会重复加载模块
无论重复加载多少次,获取的模块都是第一个require的,看下面改动后的getModule.js代码
var myModule1 = require(‘./module‘);
// 设置myModule1对象的name
myModule1.setName(‘helios‘);
var myModule2 = require(‘./module‘);
// 设置myModule2对象的name
myModule2.setName(‘newName‘);
//调用myModule1的方法setHello
myModule1.setHello(); //输出的是hellonewName
//这就说明了无论怎么改动都是改动了第一次引用的require
要理解这个问题就先要理解exports
和module.exports
分别是什么意思;
其实在一开始的时候exports
和module.exports
就是一个东西,这里说他们是一个东西其实并不确切,更应该说exports
和module.exports
指向的是同一块内存,为什么这么说呢请看下面这个例子:
console.log(exports === module.exports);//true
console.log(exports);//{}
console.log(exports == {});//false
console.log(module.exports);//{}
console.log(module.exports == {});//false
给exports
赋值就相当于给module.exports
添加属性,如下面代码:
var name = ‘helios‘;
exports = name;
exports.setName = function(){}
上面的代码就相当于下面的代码:
var name = ‘helios‘;
module.exports = name;
module.exports.setName = function(){}
我们通过require的到的其实是一个module.exports
方法,为什么这么说呢!请看下面的这几个例子:
1.下面是modul.js
exports.name=function(){
console.log("this is name method");
}
下面这个是getModule.js
var myModule1 = require(‘./module‘);
myModule1.name();
2.下面对module
这个文件改动了一下:
module.exports=function(){
console.log("this is name method");
}
下面是对getModule.js
的稍稍改动
var myModule1 = require(‘./module‘);
myModule1();
2.exports
和module.exports
指向的是同一块内存那么为什么不用下面这样方法写呢?
下面是对module.js
的改动
exports=function(){
console.log("this is name method");
}
如果写成了这样不论geyModule.js
写为什么样子都会报错,这就引出了下面的结论:require返回的其实是module.exports
这个方法,exports
其实是指向module.exports
的一个引用,
换一种说法就是这样写法是对exports
进行了覆盖,也就是说exports
指向了一块新的内存(因为对他重新赋值了),也就是说无论exports
怎么变化module.exports
内存都是没有的不会变化,我们在getModule.js
引入了一个空对象肯定会报myModule1 is not a function
这样的错误。
所以我们会经常看到这样的写法:
exports = module.exports = somethings
上面的代码就等价于:
module.exports = somethings//对module.exports进行覆盖
exports = module.exports //对exports进行覆盖
这就是为了保证exports
和module.exports
还是指向的是同一块内存;
有的时候为了方便我们会把所有的方法或者属性都放在构造函数里面,然后在对方暴露这个构造函数:
下面是module.js
function hello(){
var name;
this.setName=function(thyName){
name=thyName;
}
this.sayHello=function(){
console.log(‘hello ‘+name);
}
}
//exports.hello=hello;
module.exports=hello;
下面是getModule.js
var hello=require(‘./module‘);
var he=new hello();//helloundefined
he.setName(‘shangyilong‘);
he.sayHello();//helloshangyilong
var he2=new hello();
he2.setName(‘helios‘);
he2.sayHello();//hellohelios
这样就能克服require单次加载的弊端了。
包是在模块基础上更深一步的抽象,Node.js的包类似于C/C++的函数库或者java的类库,它讲某个独立的功能封装起来,用于发布、更新、依赖管理的版本控制。开发了npm来解决包的发布和获取需求。
包是由package.json
定义的文件或目录
我们通过npm install XX 后面的XX就是包
我们可以通过npn init
初始化一个包。我们可以把这个包做大然后上传到nodejs给别人使用
这是Node的一个系列,可以在本栏目下看其他关于Node文章,会 一直更新,有问题请在下方留言
标签:
原文地址:http://blog.csdn.net/woshinannan741/article/details/51339495