Node应用由模块组成,采用CommonJS模块规范。

根据这个规范,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。

CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。

var x = 5;
var addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

上面代码通过module.exports输出变量x和函数addX。

require方法用于加载模块。

var example = require('./example.js');

console.log(example.x); // 5
console.log(example.addX(1)); // 6

加载:require

语法:

var 自定义变量名称 = require('模块')

作用:

1、执行被加载模块中的代码

2、得到被加载模块中的exports导出接口对象

导出:exports

Node中是模块作用域,默认文件中所有的成员只在当前文件模块有效。

对于希望可以被其它模块访问的成员,我们就需要把这些公开的成员都挂载到exports接口对象中就可以了。

1. 导出多个成员(必须在对象中)

//foo.js
var foo = 'bar'
function add(x, y) {
return x + y
}
exports.foo = foo
exports.a = "科比"
exports.b= "詹姆斯"
exports.c = add //main.js
var fooExports = require('./foo')
console.log(fooExports) //结果
{ foo: 'bar', a: '科比', b: '詹姆斯', c: [Function: add] }

2. 导出单个成员

错误写法1

//foo.js
var foo = 'bar' function add(x, y) {
return x + y
}
exports = foo
exports.a = "科比"
exports.b= "詹姆斯"
exports.c = add //main.js
var fooExports = require('./foo')
console.log(fooExports) 结果为空对象 {}

错误写法2

//foo.js
var foo = 'bar' function add(x, y) {
return x + y
} exports.a = "科比"
exports.b= "詹姆斯"
exports.c = add
exports = foo //main.js
var fooExports = require('./foo')
console.log(fooExports) 结果为{ a: '科比', b: '詹姆斯', c: [Function: add] }

如果一个模块需要直接导出某个成员,而非挂载的方式,那这个时候必须使用下面这种方式

//foo.js
var foo = 'bar' function add(x, y) {
return x + y
}
module.exports = foo //位置一
exports.a = "科比"
exports.b= "詹姆斯"
exports.c = add
//module.exports = foo 位置二 /* module.exports = { 位置三
add: function () {
return x + y
},
str: 'hello'
} */ //main.js
var fooExports = require('./foo')
console.log(fooExports)

结果:

只有一个module.exports时,不管是在位置一还是位置二,都为 bar。

当有两个module.exports 时,比如一个在位置一,另一个在位置三,会导出位置三的对象(module.exports会被后者覆盖)。

上面的结果出现的原因:exports 和module.exports是有区别的。

在Node中,每个模块内部都有一个自己的module 对象,该 module 对象中,有一个成员叫exports也是一个对象,类似这样:

var module = {
exports: {
foo: 'bar',
add: function
}
}

每次导出的对象是module.exports,如果你需要对外导出成员,只需要把导出的成员挂载到module.exports中。

也就是说module.exports才是真正的接口,exports只不过是它的一个辅助工具。最终返回给调用的是module.exports而不是exports。

为了方便,Node为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令:

var exports = module.exports

exports相当于是 一个引用,指向module.exports对象,所以有

console.log(module.exports === exports)   ///true 

于是我们可以直接在 exports 对象上添加方法,表示对外输出的接口,如同在module.exports上添加一样。注意,不能直接将exports变量指向一个值,因为这样等于切断了exports与module.exports的联系。

同理,给 module.exports 重新赋值也会断开。

但是这里又重新建立两者的引用关系:

exports = module.exports

最后,一定要记得return的是module.exports

如果给exports赋值,断开了两个引用之间的联系,就不管用了。

module.exports.foo = 'bar'
exports.a = 'abc'
exports = {}
exports.b = '123' //断开连接后,就没联系了,需重新联系起来
exports = module.exports
exports.foo = 'haha'
module.exports.a = 'cba' 结果 { foo: 'haha', a: 'cba' }

exports 和 module.exports 的使用

如果要对外暴露属性或方法,就用 exports 就行,要暴露对象(类似class,包含了很多属性和方法),就用 module.exports。

node.js模块中exports和module.exports的区别的更多相关文章

  1. (译)Node.js的模块-exports和module.exports

    原文标题:Node.js Module – exports vs module.exports 原文链接:http://www.hacksparrow.com/node-js-exports-vs-m ...

  2. Node.js 模块系统入门

    在编程领域中,模块是自包含的功能单元,可以跨项目共享和重用.它们使开发人员的生活更加轻松,因为我们可以使用它来增加应用程序的功能,而不必亲自编写这些功能.它还让我们可以组织和解耦代码,从而使应用程序更 ...

  3. Developer - 如何自我保证Node.js模块质量

    组里正在做SaaS产品,其中一些模块(Module)是Node.js实现,这里我们主要使用Node.js实现Web Server来提供服务. 在做SaaS项目之前,组里的开发模式是传统的Deverlo ...

  4. Node.js中exports与module.exports的区别

    原文:http://www.hacksparrow.com/node-js-exports-vs-module-exports.html 你肯定对Node.js模块中用来创建函数的exports对象很 ...

  5. Node.js模块导出module.exports 和 exports,Es6模块导出export 和export default的区别

    1.module.exports  module变量代表当前模块.这个变量是一个对象,module对象会创建一个叫exports的属性,这个属性的默认值是一个空的对象: module.exports ...

  6. node.js中的exports和module.exports

    不同的编程语言都有各自的代码组织和复用的方式,如.net.php中的命名空间,python中的import,ruby中的module等,来避免命名空间污染.一直都没搞清楚node中的exports和m ...

  7. Node.js中exports,module.exports以及require方法

    在Node.js中,使用module.exports.f = ...与使用exports.f = ...是一样的,此时exports就是module.exports的一种简写方式.但是,需要注意的是, ...

  8. Node.js模块导出exports 和 module.exports 的区别

    原文: https://blog.csdn.net/Pwiling/article/details/51958693 每一个node.js执行文件,都自动创建一个module对象,同时,module对 ...

  9. Node.js中的exports与module.exports的区分

    1. module应该是require方法中,上下文中的对象 2. exports对象应该是上下文中引用module.exports的新对象 3. exports.a = xxx 会将修改更新到mod ...

随机推荐

  1. Win32 编程 基础

    Win32    程序开发的流程 message based, event driven Win32程序是message based, event driven.也就是说Win32程序的运行是依靠外部 ...

  2. mariadb数据库增删改查

    1.常用数据类型 1)整数:int, bit 2)小数:decimal     #decimal(5,2)表示共有五位数,保留两位小数 3)字符串:varchar, char 4)日期时间:date, ...

  3. C++复习练习题:1-1000的完数

    一个数如果恰好等于它的因子之和,就被成为完数.例如6的因子为1,2,3,而6=1+2+3,所以6是一个完数.编程找出1-1000之间的所有完数 #include<iostream> usi ...

  4. 重装java后hadoop配置文件的修改

    1.删除hdfs-site.xml中dfs.namenode.name.dir目录和dfs.datanode.data.dir目录 然后 hdfs namenode -format 不然将无法启动na ...

  5. Mysql 表空间和 数据页空洞

    一.表空间1.表空间: innodb 引擎存储的最高层: 存放所有的数据2.独立表空间:Mysql 版本 5.6 后默认开启的单表单空间(1)Innodb 默认存储引擎页的大小为 16K :默认表空间 ...

  6. [.net core] 12.环境变量

    异常给开发人员提供了很大好的排错功能. 但是其背后的技术细节很复杂,会损耗性能,也会使.net core web app更容易被反派攻击. 于是我们要学会使用环境变量, 通过环境变量,控制一些逻辑 当 ...

  7. for XML path 使用技巧

    FOR XML PATH 是sqlserver数据库的语法,能将查询出的数据转换成xml格式的数据. 首先,我们来看一个正常的查询: SELECT TOP 2 id, name,crDate FROM ...

  8. Dynamic Compilation and Loading of .NET Objects

      This is another approach to dynamic compilation of objects and their usage via Interfaces. Introdu ...

  9. Jquery复习(三)之链式调用

    通过 jQuery,可以把动作/方法链接在一起. Chaining 允许我们在一条语句中运行多个 jQuery 方法(在相同的元素上). jQuery 方法链接 直到现在,我们都是一次写一条 jQue ...

  10. [转载]Jupyter Notebook中自动补全代码

    原文地址:https://yq.aliyun.com/articles/667928 在公众号之前的文章中,已经介绍了在Jupyter Notebook中设置主题以及输出代码文件到pdf文件中,本文来 ...