Tow*_*wer 216 javascript node.js
目前我这样做:
foo.js
const FOO = 5;
module.exports = {
FOO: FOO
};
Run Code Online (Sandbox Code Playgroud)
并在bar.js以下方面使用它:
var foo = require('foo');
foo.FOO; // 5
Run Code Online (Sandbox Code Playgroud)
有一个更好的方法吗?在exports对象中声明常量会感觉很尴尬.
Spa*_*ain 266
在我看来,利用Object.freeze允许DRYer和更具说明性的风格.我的首选模式是:
./lib/constants.jsmodule.exports = Object.freeze({
MY_CONSTANT: 'some value',
ANOTHER_CONSTANT: 'another value'
});
Run Code Online (Sandbox Code Playgroud)
./lib/some-module.jsvar constants = require('./constants');
console.log(constants.MY_CONSTANT); // 'some value'
constants.MY_CONSTANT = 'some other value';
console.log(constants.MY_CONSTANT); // 'some value'
Run Code Online (Sandbox Code Playgroud)
以下问题已于2014年1月在v8中修复,并且与大多数开发人员不再相关:
请注意,将可写入设置为false并使用Object.freeze在v8中都会产生巨大的性能损失 - https://bugs.chromium.org/p/v8/issues/detail?id=1858和http://jsperf.com /性能冰冻对象
Dom*_*nes 160
从技术上讲,const它不是ECMAScript规范的一部分.此外,使用您注意到的"CommonJS模块"模式,您可以更改"常量"的值,因为它现在只是一个对象属性.(不确定是否会将任何更改级联到需要相同模块的其他脚本,但这是可能的)
要获得真正的常数,你也可以分享,看看Object.create,Object.defineProperty和Object.defineProperties.如果设置writable: false,则无法修改"常量"中的值.:)
它有点冗长,(但即使可以用一点JS来改变)但你应该只为你的常量模块做一次.使用这些方法,您省略的任何属性都默认为false.(而不是通过赋值定义属性,默认所有属性true)
所以,假设你可以设置,value并且enumerable离开writable,configurable因为他们将默认false,我只是为了清楚而包括它们.
更新 - 我为这个用例创建了一个带有辅助函数的新模块(node-constants).
Object.defineProperty(exports, "PI", {
value: 3.14,
enumerable: true,
writable: false,
configurable: false
});
Run Code Online (Sandbox Code Playgroud)
function define(name, value) {
Object.defineProperty(exports, name, {
value: value,
enumerable: true
});
}
define("PI", 3.14);
Run Code Online (Sandbox Code Playgroud)
var constants = require("./constants");
console.log(constants.PI); // 3.14
constants.PI = 5;
console.log(constants.PI); // still 3.14
Run Code Online (Sandbox Code Playgroud)
Die*_*llo 84
ES6的方式.
在foo.js中导出
const FOO = 'bar';
module.exports = {
FOO
}
Run Code Online (Sandbox Code Playgroud)
在bar.js中导入
const {FOO} = require('foo');
Run Code Online (Sandbox Code Playgroud)
Ale*_*yne 83
您可以使用显式将其导出到全局范围global.FOO = 5.然后你只需要要求文件,甚至不保存你的返回值.
但实际上,你不应该这样做.保持正确封装的东西是一件好事.你已经有了正确的想法,所以继续做你正在做的事情.
小智 15
我发现Dominic建议的解决方案是最好的,但它仍然错过了"const"声明的一个特性.当您使用"const"关键字在JS中声明常量时,将在分析时检查常量的存在,而不是在运行时.因此,如果您在代码中稍后某处拼错了常量的名称,则在尝试启动node.js程序时会出现错误.这是一个更好的拼写错误检查.
如果使用像Dominic建议的define()函数定义常量,如果拼错了常量,则不会出现错误,并且拼写错误常量的值将是未定义的(这可能导致调试问题).
但我想这是我们能得到的最好的.
另外,这是对constans.js中Dominic函数的一种改进:
global.define = function ( name, value, exportsObject )
{
if ( !exportsObject )
{
if ( exports.exportsObject )
exportsObject = exports.exportsObject;
else
exportsObject = exports;
}
Object.defineProperty( exportsObject, name, {
'value': value,
'enumerable': true,
'writable': false,
});
}
exports.exportObject = null;
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以在其他模块中使用define()函数,它允许您在constants.js模块内部定义常量,并在模块内定义您调用函数的常量.然后可以通过两种方式(在script.js中)声明模块常量.
第一:
require( './constants.js' );
define( 'SOME_LOCAL_CONSTANT', "const value 1", this ); // constant in script.js
define( 'SOME_OTHER_LOCAL_CONSTANT', "const value 2", this ); // constant in script.js
define( 'CONSTANT_IN_CONSTANTS_MODULE', "const value x" ); // this is a constant in constants.js module
Run Code Online (Sandbox Code Playgroud)
第二:
constants = require( './constants.js' );
// More convenient for setting a lot of constants inside the module
constants.exportsObject = this;
define( 'SOME_CONSTANT', "const value 1" ); // constant in script.js
define( 'SOME_OTHER_CONSTANT', "const value 2" ); // constant in script.js
Run Code Online (Sandbox Code Playgroud)
另外,如果你想只从constants模块调用define()函数(不要膨胀全局对象),你可以在constants.js中定义它:
exports.define = function ( name, value, exportsObject )
Run Code Online (Sandbox Code Playgroud)
并在script.js中使用它:
constants.define( 'SOME_CONSTANT', "const value 1" );
Run Code Online (Sandbox Code Playgroud)
Man*_*ddy 10
根据以前的项目经验,这是一个好方法:
在constants.js中:
// constants.js
'use strict';
let constants = {
key1: "value1",
key2: "value2",
key3: {
subkey1: "subvalue1",
subkey2: "subvalue2"
}
};
module.exports =
Object.freeze(constants); // freeze prevents changes by users
Run Code Online (Sandbox Code Playgroud)
在main.js(或app.js等)中,如下使用它:
// main.js
let constants = require('./constants');
console.log(constants.key1);
console.dir(constants.key3);
Run Code Online (Sandbox Code Playgroud)
atr*_*eon 10
import和export(可能需要像 2018 年的 babel 一样使用导入)
类型.js
export const BLUE = 'BLUE'
export const RED = 'RED'
Run Code Online (Sandbox Code Playgroud)
我的应用程序
import * as types from './types.js'
const MyApp = () => {
let colour = types.RED
}
Run Code Online (Sandbox Code Playgroud)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
我认为这const可以解决大多数寻求此问题的人的问题。如果您确实需要一个不变的常数,请查看其他答案。为了使所有内容井井有条,我将所有常量保存在一个文件夹中,然后需要整个文件夹。
src / main.js文件
const constants = require("./consts_folder");
Run Code Online (Sandbox Code Playgroud)
src / consts_folder / index.js
const deal = require("./deal.js")
const note = require("./note.js")
module.exports = {
deal,
note
}
Run Code Online (Sandbox Code Playgroud)
附言 在这里,dealand note将是main.js的第一层
src / consts_folder / note.js
exports.obj = {
type: "object",
description: "I'm a note object"
}
Run Code Online (Sandbox Code Playgroud)
附言 obj将成为main.js的第二级
src / consts_folder / deal.js
exports.str = "I'm a deal string"
Run Code Online (Sandbox Code Playgroud)
附言 str将成为main.js的第二级
main.js文件的最终结果:
console.log(constants.deal);
输出:
{deal:{str:'I \'ma deal string'},
console.log(constants.note);
输出:
注意:{obj:{类型:“对象”,描述:“ I \'ma note对象”}}
作为替代方案,您可以将“常量”值分组到本地对象中,并导出返回该对象的浅克隆的函数。
var constants = { FOO: "foo" }
module.exports = function() {
return Object.assign({}, constants)
}
Run Code Online (Sandbox Code Playgroud)
那么如果有人重新分配 FOO 也没关系,因为它只会影响他们的本地副本。
| 归档时间: |
|
| 查看次数: |
159143 次 |
| 最近记录: |