详解nodejs中exports和module.exports的区别

require 用来加载代码,而 exports 和 module.exports 则用来导出代码。但很多新手可能会迷惑于 exports 和 module.exports 的区别,为了更好的理解 exports 和 module.exports 的关系,我们先来巩固下 js 的基础。示例:

app.js

var a = {name: 'nswbmw 1'};
var b = a;
console.log(a);
console.log(b);
b.name = 'nswbmw 2';
console.log(a);
console.log(b);
var b = {name: 'nswbmw 3'};
console.log(a);
console.log(b);

运行 app.js 结果为:

{ name: 'nswbmw 1' }
{ name: 'nswbmw 1' }
{ name: 'nswbmw 2' }
{ name: 'nswbmw 2' }
{ name: 'nswbmw 2' }
{ name: 'nswbmw 3' }

解释一下:a 是一个对象,b 是对 a 的引用,即 a 和 b 指向同一个对象,即 a 和 b 指向同一块内存地址,所以前两个输出一样。当对 b 作修改时,即 a 和 b 指向同一块内存地址的内容发生了改变,所以 a 也会体现出来,所以第三、四个输出一样。当对 b 完全覆盖时,b 就指向了一块新的内存地址(并没有对原先的内存块作修改),a 还是指向原来的内存块,即 a 和 b 不再指向同一块内存,也就是说此时 a 和 b 已毫无关系,所以最后两个输出不一样。

明白了上述例子后,我们进入正题。

我们只需知道三点即可知道 exports 和 module.exports 的区别了:

  • exports 是指向的 module.exports 的引用
  • module.exports 初始值为一个空对象 {},所以 exports 初始值也是 {}
  • require() 返回的是 module.exports 而不是 exports

所以:我们通过

var name = 'nswbmw';
exports.name = name;
exports.sayName = function() {
 console.log(name);
}

给 exports 赋值其实是给 module.exports 这个空对象添加了两个属性而已,上面的代码相当于:

var name = 'nswbmw';
module.exports.name = name;
module.exports.sayName = function() {
 console.log(name);
}

我们通常这样使用 exports 和 module.exports

一个简单的例子,计算圆的面积:

使用 exports

app.js

var circle = require('./circle');
console.log(circle.area(4));

circle.js

exports.area = function(r) {
 return r * r * Math.PI;
}

使用 module.exports

app.js

var area = require('./area');
console.log(area(4));

area.js

module.exports = function(r) {
 return r * r * Math.PI;
}

上面两个例子输出是一样的。你也许会问,为什么不这样写呢?

app.js

var area = require('./area');
console.log(area(4));

area.js

exports = function(r) {
 return r * r * Math.PI;
}

运行上面的例子会报错。这是因为,前面的例子中通过给 exports 添加属性,只是对 exports 指向的内存做了修改,而

exports = function(r) {
 return r * r * Math.PI;
}

其实是对 exports 进行了覆盖,也就是说 exports 指向了一块新的内存(内容为一个计算圆面积的函数),也就是说 exports 和 module.exports 不再指向同一块内存,也就是说此时 exports 和 module.exports 毫无联系,也就是说 module.exports 指向的那块内存并没有做任何改变,仍然为一个空对象 {} ,也就是说 area.js 导出了一个空对象,所以我们在 app.js 中调用 area(4) 会报 TypeError: object is not a function 的错误。

所以,一句话做个总结:当我们想让模块导出的是一个对象时,exports 和 module.exports 均可使用(但 exports也不能重新覆盖为一个新的对象),而当我们想导出非对象接口时,就必须也只能覆盖 module.exports。

我们经常看到这样的用写法:

exports = module.exports = somethings;

上面的代码等价于

module.exports = somethings;
exports = module.exports;

原因也很简单,module.exports = somethings 是对 module.exports 进行了覆盖,此时 module.exports 和 exports 的关系断裂,module.exports 指向了新的内存块,而 exports 还是指向原来的内存块,为了让 module.exports 和 exports 还是指向同一块内存或者说指向同一个 “对象”,所以我们就 exports = module.exports。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • seaJs使用心得之exports与module.exports的区别实例分析

    本文实例讲述了seaJs使用心得之exports与module.exports的区别.分享给大家供大家参考,具体如下: 1. exports 是 module.exports 的 辅助对象,exports对外提供api 时需要用return 返回exports 对象 2. module.exports 也可直接向外提供api 参考 : https://github.com/seajs/seajs/issues/242 exports Object exports 是一个对象,用来向外提供模块接口

  • 浅谈node中的exports与module.exports的关系

    因为是做前端的,对node的生态一直也比较关注,对于node中对commonJS模块化的实现给了我们很大的方便,之前对于导出的module.exports和exports一直模模糊糊,今天做一个整理 先来个js基础部分的复习 let obj1 = {} let obj2 = obj1 obj2.a = 'a' obj1.b = 'b' console.log(obj1) //{a: 'a', b: 'b'} console.log(obj2) //{a: 'a', b: 'b'} obj2 =

  • 详解Node.js中exports和module.exports的区别

    今天看了下node.js的require方法的源码,终于搞清楚exports和module.exports的区别了. 我们知道,node.js的模块暴露有两种方法. 1. 方式一:用exports //a.js exports.log =function (str) { console.log(str); } //b.js var s = require("./a"); s.log("哈哈哈哈"); 2. 方式二:用module.exports //a.js mod

  • node.js中module.exports与exports用法上的区别

    Node.js 引入了模块(Module)概念,一个模块可以通过module.exports 或 exports 将函数.变量等导出,以使其它 JavaScript 脚本通过require() 函数引入并使用. module.exports 初始值为一个空对象 {},所以 exports 初始值也是 {},exports 是指向的 module.exports 的引用,在模块内部大概是这样: exports = module.exports = {}; 举个栗子,在node.js中创建模块非常简

  • Node.js 中exports 和 module.exports 的区别

    Node.js 中exports 和 module.exports 的区别 require 用来加载代码,而 exports 和 module.exports 则用来导出代码.但很多新手可能会迷惑于 exports 和 module.exports 的区别,为了更好的理解 exports 和 module.exports 的关系,我们先来巩固下 js 的基础.示例: test.js var a = {name: 1}; var b = a; console.log(a); console.log

  • nodejs中exports与module.exports的区别详细介绍

    你肯定非常熟悉nodejs模块中的exports对象,你可以用它创建你的模块.例如:(假设这是rocker.js文件) 复制代码 代码如下: exports.name = function() { console.log('My name is Lemmy Kilmister'); }; 在另一个文件中你这样引用 复制代码 代码如下: var rocker = require('./rocker.js'); rocker.name(); // 'My name is Lemmy Kilmiste

  • JavaScript ES6中export、import与export default的用法和区别

    前言 相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在看他们之间的区别之前,我们先来看看它们的用法. ES6 import和export的用法 ES6之前已经出现了js模块加载的方案,最主要的是CommonJS和AMD规范.commonjs主要应用于服务器,实现同步加载,如nodejs.AMD规范应用于浏览器,如requirejs,为异步加载.同时还有CMD规范,为同步加载方案如seaJS. ES6在语言规格的层面上,实现了模块功能,而且

  • 深入理解node exports和module.exports区别

    我们只需知道三点即可知道 exports 和 module.exports 的区别了: 1.exports 是指向的 module.exports 的引用 2.module.exports 初始值为一个空对象 {},所以 exports 初始值也是 {} 3.require() 返回的是 module.exports 而不是 exports 所以: • 我们通过 var name ='nswbmw'; exports.name = name; exports.sayName =function(

  • node.js的exports、module.exports与ES6的export、export default深入详解

    前言 最近难得有空,决定开始重新规范的学习一下node编程.但是引入模块我看到用 require的方式,再联想到咱们的ES6各种export .export default. 阿西吧,头都大了.... 头大完了,那我们坐下先理理他们的使用范围. require: node 和 es6 都支持的引入 export / import : 只有es6 支持的导出引入 module.exports / exports: 只有 node 支持的导出 这一刻起,我觉得是时候要把它们之间的关系都给捋清楚了,不

  • 详解nodejs中的异步迭代器

    前言 从 Node.jsv10.0.0 开始,异步迭代器就出现中了,最近它们在社区中的吸引力越来越大.在本文中,我们将讨论异步迭代器的作用,还将解决它们可能用于什么目的的问题. 什么是异步迭代器 那么什么是异步迭代器?它们实际上是以前可用的迭代器的异步版本.当我们不知道迭代的值和最终状态时,可以使用异步迭代器,最终我们得到可以解决{value:any,done:boolean}对象的 promise.我们还获得了 for-await-of 循环,以帮助我们循环异步迭代器.就像 for-of 循环

  • 详解Java中Comparable和Comparator接口的区别

    详解Java中Comparable和Comparator接口的区别 本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧. Comparable 简介 Comparable 是排序接口. 若一个类实现了Comparable接口,就意味着"该类支持排序".  即然实现Comparable接口的类支持排序,假设现在存在"实现Comparable接口的类的对象的List列表(

  • 详解Java中的sleep()和wait()的区别

    详解Java中的sleep()和wait()的区别 对于sleep()方法,我们首先要知道该方法是属于Thread类中的.而wait()方法,则是属于Object类中的. sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态. 在调用sleep()方法的过程中,线程不会释放对象锁. 而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象

  • 详解pandas中iloc, loc和ix的区别和联系

    Pandas库十分强大,但是对于切片操作iloc, loc和ix,很多人对此十分迷惑,因此本篇博客利用例子来说明这3者之一的区别和联系,尤其是iloc和loc. 对于ix,由于其操作有些复杂,我在另外一篇博客专门详细介绍ix. 首先,介绍这三种方法的概述: loc gets rows (or columns) with particular labels from the index. loc从索引中获取具有特定标签的行(或列).这里的关键是:标签.标签的理解就是name名字. iloc get

  • 详解Java中方法next()和nextLine()的区别与易错点

    1.基本语法 1.1基本使用方法 本篇博客重点nextLine()会读取换行('\r'),但是不会进行输出. Java中Scanner类中的方法next()和nextLine()都是吸取输入台输入的字符,区别: next()不会吸取字符前/后的空格/Tab键,只吸取字符,开始吸取字符(字符前后不算)直到遇到空格/Tab键/回车截止吸取: nextLine()吸取字符前后的空格/Tab键,回车键截止. 输入两行字符串: 我爱学JAVA 我真的很爱爱学JAVA 我真的很爱很爱学JAVA 期望输出结果

  • 带例子详解Sql中Union和Union ALL的区别

    目录 前言 提前准备 测试 Union Union ALL Union Union All union Union All 最后 前言 一段时间没有用Union和Union,再用的时候忘了怎么用了...所以做一篇文章来记录自己学Union和Union的经历. 提前准备 在Sql Server 创建两张表,下面是创建表sql语句. create table Student1( Id varchar(50) not null, Name varchar(50) not null, Age int n

  • 详解nodejs中exports和module.exports的区别

    require 用来加载代码,而 exports 和 module.exports 则用来导出代码.但很多新手可能会迷惑于 exports 和 module.exports 的区别,为了更好的理解 exports 和 module.exports 的关系,我们先来巩固下 js 的基础.示例: app.js var a = {name: 'nswbmw 1'}; var b = a; console.log(a); console.log(b); b.name = 'nswbmw 2'; cons

  • 详解nodejs中的process进程

    虽然node对操作系统做了很多抽象的工作,但是你还是可以直接和他交互,比如和系统中已经存在的进程进行交互,创建工作子进程.node是一个用于事件循环的线程,但是你可以在这个事件循环之外创建其他的进程(线程)参与工作. 进程模块 process模块允许你获得或者修改当前node进程的设置,不想其他的模块,process是一个全局进程(node主进程),你可以直接通过process变量直接访问它. process实现了EventEmitter接口,exit方法会在当进程退出的时候执行.因为进程退出之

  • 详解nodeJS中读写文件方法的区别

    导言:nodejs中所有与文件相关的操作都在fs模块中,而读写操作又是我们会经常用到的操作,nodejs的fs模块针对读操作为我们提供了readFile,read, createReadStream三个方法,针对写操作为我们提供了writeFile,write, createWriteStream三个方法,下面分析一下它们的区别: 一.readFile和writeFile 1.readFile方法是将要读取的文件内容完整读入缓存区,再从该缓存区中读取文件内容,具体操作如下: fs.readFil

  • 详解Java中字符流与字节流的区别

    本文为大家分析了Java中字符流与字节流的区别,供大家参考,具体内容如下 1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个"流动的方向",通常可以从中读入一个字节序列的对象被称为输入流:能够向其写入一个字节序列的对象被称为输出流. 2. 字节流 Java中的字节流处理的最基本单位为单个字节,它通常用来处理二进制数据.Java中最基本的两个字节流类是InputStream和Out

随机推荐