如何在NodeJS模块***享常量?

目前,我正在这样做:

foo.js

const FOO = 5;

module.exports = {
    FOO: FOO
};

并在中使用它bar.js

var foo = require('foo');
foo.FOO; // 5

有一个更好的方法吗?在exports对象中声明常量感觉很尴尬。

小哥西门2020/03/23 10:32:22

由于Node.js使用的是CommonJS模式,因此只能module.exports像在浏览器中那样通过或通过设置全局变量来在模块之间共享变量,而不能使用窗口global.your_var = value;

十三飞云2020/03/23 10:32:22

作为替代方案,您可以将“常量”值分组在本地对象中,并导出返回该对象的浅表克隆的函数。

var constants = { FOO: "foo" }

module.exports = function() {
  return Object.assign({}, constants)
}

那么,是否有人重新分配FOO无关紧要,因为这只会影响他们的本地副本。

A梅2020/03/23 10:32:22

从技术上讲,const它不是ECMAScript规范的一部分。另外,使用您注意到的“ CommonJS Module”模式,您可以更改该“ constant”的值,因为它现在只是一个对象属性。(不确定是否会将对同一脚本的其他更改进行级联,但是有可能)

要获得真正的常数,你也可以分享,看看Object.createObject.definePropertyObject.defineProperties如果设置writable: false,则“常量”中的值无法修改。:)

这有点冗长(但即使使用一点JS也可以更改),但是您只需为常量模块执行一次即可。使用这些方法,您遗漏的任何属性都默认为false(与通过赋值定义属性相反,后者将所有属性默认为true

因此,假设地,您可以设置valueenumerable,省去,writable并且configurable由于它们将默认设置为false,为了清楚起见,我仅将它们包括在内。

更新 - 在这个用例中,我已经创建了一个带有辅助功能的新模块(node-constants)。

constants.js-好

Object.defineProperty(exports, "PI", {
    value:        3.14,
    enumerable:   true,
    writable:     false,
    configurable: false
});

constants.js-更好

function define(name, value) {
    Object.defineProperty(exports, name, {
        value:      value,
        enumerable: true
    });
}

define("PI", 3.14);

script.js

var constants = require("./constants");

console.log(constants.PI); // 3.14
constants.PI = 5;
console.log(constants.PI); // still 3.14
Itachi2020/03/23 10:32:22

您可以使用将其显式导出到全局范围global.FOO = 5然后,您只需要提供文件,甚至不保存您的返回值。

但实际上,您不应该这样做。保持适当封装是一件好事。您已经有了正确的想法,因此请继续做您正在做的事情。