资讯专栏INFORMATION COLUMN

[译] node.js 中的 module.exports 与 exports

sunsmell / 3414人阅读

摘要:接下来我们将对和在中的使用有一个更好地了解。这篇文章包括了中的使用。这看起来似乎有些困惑,请记住和引用的是同一对象。重点返回一个,该对象引用了的值。我们将中公开的方法赋值给变量。总结和模块在中是一个随处可见的任务。

理解 node.js 中的 module.exports 与 exports

原文链接

作为一个开发者,我们经常会遇到需要使用不熟悉的代码的情况。
在这个过程中遇到一个问题:我需要花费多少时间去理解这些代码,明白如何使用?
一个典型的回答就是:先让我可以开始coding,等到时间允许再去做深入研究。
接下来我们将对 module.exports 和 exports 在 node.js中的使用有一个更好地了解。

Note: 这篇文章包括了 node 中 module 的使用。如果你想了解浏览器内部 modules 的使用,可以参考这面这篇文章:
Understanding JavaScript Modules: Bundling & Transpiling

What is a Module?

一个模块就是将文件中相关的代码封装为一个代码块。
创建一个module,可以理解为将所有相关的方法挪到一个文件中。
我们使用一个node.js的应用程序来说明一下这个观点。
创建一个名叫 greetings.js 的文件,其中包含下面两个方法:

// greetings.js
sayHelloInEnglish = function() {
  return "Hello";
};

sayHelloInSpanish = function() {
  return "Hola";
};
Exporting a Module

为了 greetings.js 公共逻辑增加的时候,其封装的代码可以在其他文件中使用。所以我们
重构一下 greetings.js 来达到这个目的。为了更好地理解这个过程,我们分为3步:

1) 想象一下有这么一行代码在 greetings.js 的第一行:

// greetings.js
var exports = module.exports = {};

2) 把greetings.js中的方法赋值给exports对象在其他文件中使用:

// greetings.js
// var exports = module.exports = {};
        
exports.sayHelloInEnglish = function() {
  return "HELLO";
};
   
exports.sayHelloInSpanish = function() {
  return "Hola";
};

在上面的代码中,我们可以使用 module.exports 替换 exports达到相同的结果。
这看起来似乎有些困惑,请记住:exports 和 module.exports引用的是同一对象。

3) 此时 module.exports 是这样的:

module.exports = {
  sayHelloInEnglish: function() {
    return "HELLO";
  },
       
  sayHelloInSpanish: function() {
    return "Hola";
  }
};
Importing a Module

我们在 main.js 中 require greetings.js 的公开接口。这个过程有以下三个步骤:

1)关键词 require 在 node.js 中用于导入模块,即所获取模块的 exports 对象。
我们可以想到它是这么定义的:

var require = function(path) {

  // ...

  return module.exports;
};

2) 在 main.js 中 require greetings.js

// main.js
var greetings = require("./greetings.js");

上面的代码等同于:

// main.js
var greetings = {
  sayHelloInEnglish: function() {
    return "HELLO";
  },
       
  sayHelloInSpanish: function() {
    return "Hola";
  }
};

3) 现在我们可以在 main.js 中使用greetings访问 greetings.js 中公开的方法就像获取它的属性一样。

// main.js
var greetings = require("./greetings.js");

// "Hello"
greetings.sayHelloInEnglish();
        
// "Hola"  
greetings.sayHelloInSpanish();
Salient Points 重点

require 返回一个 object ,该对象引用了 module.exports 的值。
如果开发者无意或有意的将 module.exports 赋值给另外一个对象,
或者赋予不同的数据结构,这样会导致原来的 module.exports 对象
所包含的属性失效。

看一个复杂的示例去说明这个观点。

// greetings.js
// var exports = module.exports = {};

exports.sayHelloInEnglish = function() {
  return "HELLO";
};

exports.sayHelloInSpanish = function() {
  return "Hola";
};

/* 
 * this line of code re-assigns  
 * module.exports
 */
module.exports = "Bonjour";

在 main.js 中require greetings.js

// main.js
var greetings = require("./greetings.js");

此时,和之前并没有任何变化。我们将greetings.js中公开的方法
赋值给greetings变量。

当我们试图调用sayHelloInEnglish和sayHelloInSpanish结果显示为
module.exports 重新赋值给一个新的不同于默认值的数据格式。

// main.js
// var greetings = require("./greetings.js");
    
/*
 * TypeError: object Bonjour has no 
 * method "sayHelloInEnglish"
 */
greetings.sayHelloInEnglish();
        
/* 
 * TypeError: object Bonjour has no 
 * method "sayHelloInSpanish"
 */
greetings.sayHelloInSpanish();

为了清楚地知道这个错误原因,我们将greetings的结果打印出来:

// "Bonjour"
console.log(greetings);

在这个点上,我们试着在 module.exports 抛出来的字符串"Bonjour" 去调用 sayHelloInEnglish 和 sayHelloInSpanish
方法,换句话说,我们永远也不会引用到 module.exports 默认输出object里面的方法。

Conclusion 总结

importing 和 exporting 模块在 node.js 中是一个随处可见的任务。
我希望 exports 和 module.exports之间的差异更加清晰。
此外,如果将来你遇到调用公共方法错误的时候,我希望你可以对这些
错误的原因有一个更好地理解。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90940.html

相关文章

  • []你并不知道Node

    摘要:问题什么是调用栈并且它是的一部分么调用栈当然是的一部分。为什么理解是重要的因为你在每个进程中只能获取一个调用栈。它是一个从事件队列中跳去事件的循环并且将它们的回调压入到调用栈中。当调用栈为空的时候,事件循环可以决定下一步执行哪一个。 你并不知道Node 原文:You don’t know Node 译者:neal1991 welcome to star my articles-tra...

    miqt 评论0 收藏0
  • []JavaScript ES6模块指南

    摘要:模块可以导入和导出各种类型的变量,如函数,对象,字符串,数字,布尔值,等等。所以这可能会导致一些不符合预期的行为。可变的基本类型值在导入一些基本类型的值如数字,布尔值或字符串时,可能会产生一个有趣的副作用。 前言 ECMAScript 2015(又称ES6)提供了一个前端JavaScript缺失已久的特性 —— 模块。ES2015中的模块参考了CommonJS规范(目前Node.js的...

    yimo 评论0 收藏0
  • Node.js 前端开发指南

    摘要:定时器在和浏览器中的表现形式是相同的。关于定时器的一个重要的事情是,我们提供的延迟不代表在这个时间之后回调就会被执行。它的真正含义是,一旦主线程完成所有操作包括微任务并且没有其它具有更高优先级的定时器,将在此时间之后执行回调。 众成翻译 原文链接 关于作者 2018年6月21日出版​ 本指南面向了解Javascript但尚未十分熟悉Node.js的前端开发人员。我这里不专注于语言本身...

    CntChen 评论0 收藏0
  • 保护 Node.js 项目的源代码

    摘要:而对于应用越来越广泛的而言,运行的则是源代码。通过查阅的相关代码,可以发现字节码的头部保存着这些信息其中第项就是源代码长度。本文同时发表于作者个人博客保护项目的源代码 SaaS(Software as a Service,软件即服务),是一种通过互联网提供软件服务的模式。服务提供商会全权负责软件服务的搭建、维护和管理,使得他们的客户从这些繁琐的工作中解放出来。对于许多中小型企业而言,S...

    Steven 评论0 收藏0
  • []Webpack的奇妙世界

    摘要:相反,解释背后的原理是什么使他比一个构造器更加强大。仍然是构造器类似这样的工具存在的主要原因之一就是解决依赖问题。是一个模块构造器,就是前文所说的。 Webpack是一个JavaScript模块构造器。 这是适合它功能的名称。 但是,我想在本文中展现Webpack的真正功能。 本文将不讲解如何使用Webpack。 相反,解释背后的原理:是什么使他比一个构造器更加强大。 Webpack仍...

    enali 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<