node.js - nodejs 模块及其导出之间的差异

标签 node.js oop static node-modules

<分区>

我刚刚浏览了 nodejs 源代码,注意到不同模块导出方式之间的差异。例如,某些模块导出具有原型(prototype)继承样式的对象:

Thing = function () {
  constructor stuff
}

Thing.prototype.jump () {
  jump stuff
}

exports = Thing

其他模块会将函数直接附加到导出:

exports.spectacles = function () {
  spectacle stuff
}

在我看来,他们将实现相似的目标,但他们显然不同。我相信第一个示例描述的是类似于类的内容,而第二个示例只是提供了可用的静态方法。

这两种方法之间的根本区别是什么?如何正确描述它们以及一种方法相对于另一种方法的优点/缺点是什么?

最佳答案

尝试从另一个角度来看:需要您的模块的模块。

Node 中的每个文件都是一个模块。每个模块都有一个全局变量,module,以及它的属性,exports。无论您在 exports 属性上放置什么,都将作为模块的导出提供。

原始

即。 bool 值、数字或字符串都可以:

module.exports = 3;

当您需要该文件时,您将获得“3”。

var myModule  = require('./my-module');
console.log(myModule); // <== 3

但由于 JavaScript 中的一切都是对象,因此您可以调用方法,甚至是原始 prop:

console.log(myModule.toString()); // <== "3"

函数

您还可以导出函数。

module.exports = function() {
    console.log('3 more');
};

那个导出将是一个函数:

var myModule  = require('./my-module');
myModule(); // <== '3 more'

当然,一个函数也是一个对象,所以你也有方法可以尝试。

console.log(myModule.toString());
// You get: 'function (){\n    console.log(\'3 more\');\n    }'

对象

然后您可以导出包含其中一些内容的对象:

module.exports = {
    prop: 3,
    method: function() {
        console.log('Not 3 this time.');
    }
};

当您需要此模块时,您将拥有该对象 - 一个具有属性 prop 和方法 method 的对象。

var myModule  = require('./my-module');
console.log(myModule.prop); // <== 3
myModule.method();          // <== 'Not 3 this time'

所以你明白模式了吗?无论你在 module.exports 中放入什么,你都会在另一端得到什么。正如我所说,这是一个视角问题。

默认

即使您不导出任何内容(即需要一个空文件),您也可以导出。

需要一个空文件(它必须存在)

var myModule  = require('./my-module');
console.log(myModule); // <== {}

这告诉您默认导出的是一个空对象。


这就是有趣的地方。

如果默认情况下 module.exports = {},那么如果我们简单地附加到它,我们可以向它添加 props:

因此,当 Node 第一次获取您的模块(文件)时,它是一个 {}。我们可以简单地附加 Prop 。

module.exports.prop = 3;
module.exports.method = function() { console.log('I am out of ideas for placeholders, I should use kitten');}

为什么没有 module 关键字就可以工作?

现在,为什么不用 module 关键字也能正常工作? IE。只是:

exports.prop = 3;
exports.method = function() {};

因为当 Node.js 开始处理您的文件时,它会将导出别名为 module.exports。 但要小心,您可以覆盖它!

这是什么意思?这几乎就像您在文件开头写了 var exports = module.exports

因此您可以仅使用exports 语法,但我不想这样做。为什么?因为您可能会犯错误并覆盖 exports var。你会更加小心 module.exports。 (还有其他原因,这个是我最先了解到的,内存最深刻的。)

示例 1:

exports.prop = false;

// later in module
module.exports = myObj; // see? overriden. 

示例 2:

var exports = {}; // see? Overridden default module.exports.
exports.prop = 4;

exports.method = function(){
    console.log('3 more');
};

所以当你以后需要这个的时候:

var myModule  = require('./my-module');
console.log(myModule); // <== {}

希望对您有所帮助。

关于node.js - nodejs 模块及其导出之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24623575/

相关文章:

node.js - 如何在 res.redirect 期间传递数据?

node.js - socket.io,我如何知道套接字是否保持事件状态?

ruby - 终端 curl : (7) Failed to connect to localhost port 3000: Connection refused

ruby - 为什么我们在 Ruby 中有隐式接收者?

c++ - 加载 DLL 不初始化静态 C++ 类

node.js - Sequelize 多个连接?

OOP 哲学(摘自《Scala 编程》中的组合和继承)

c# - 覆盖对象的虚拟方法

java - Android 从静态上下文中获取 fragment 中的资源

Android 存储 URL 的最佳方式是什么?静态数据成员还是在 String.xml 中?