如何在Nodejs中使用全局对象获取常量变量



我想获得一个带有全局对象的常量变量来动态使用它,但global.myconstant不起作用,但global.myvar起作用。

λ node
> const myconstant = true
undefined
> global.myconstant
undefined
> var myvar = true
undefined
> global.myvar
true
> global.const
undefined

我想做的事:

const myconstant = () => { console.log("ok const"); };
var myvariable = () => { console.log("ok var"); };
const watchlist = {
myconstant: "file1.html",
myvariable: "file2.html"
};
Object.keys(watchlist).forEach((taskName) => {
try {
global[taskName](); //doesn't work with const
} catch (e) {
console.error("error", taskName);
}
});

实际输出:

error myconstant
ok var

想要输出:

ok const
ok var

现场演示:https://repl.it/repls/SunnyScholarlyPasswords

如何使用字符串获取常量变量不使用var替换const

只有用var声明的变量才能隐式分配给全局对象。如果要创建不可重新分配的属性,则应使用Object.defineProperty。例如,在浏览器中,引用window而不是global:

Object.defineProperty(
window,
'myconstant',
{
value: () => { console.log("ok const"); },
configurable: false
}
);
var myvariable = () => { console.log("ok var"); };
const watchlist = {
myconstant: "file1.html",
myvariable: "file2.html"
};
Object.keys(watchlist).forEach((taskName) => {
try {
window[taskName]();
} catch (e) {
console.error("error", taskName);
}
});
// Won't reassign, and will throw an error in strict mode:
window.myconstant = 'foo';
console.log(typeof window.myconstant);

configurable: false是关键,尽管它是可选的——无论如何它都默认为false。无法修改或删除不可配置的属性。

描述的行为对Node REPL来说是自然的,但对模块中评估的代码来说不是。模块范围内的变量不会泄漏到全局,因为它们是在模块范围内定义的,这适用于varconst。这就是节点模块中会发生的情况:

const myconstant = 1;
var myvariable = 2;
console.log(global.myconstant) // undefined
console.log(global.myvariable) // undefined

之所以在REPL中发生这种情况,是因为代码是在全局范围内求值的。所描述的行为可以通过间接eval:在模块范围内复制

(0, eval)(`
const myconstant = 1;
var myvariable = 2;
`);
console.log(global.myconstant) // undefined
console.log(global.myvariable) // 2

这是var和块范围变量(const等)之间的区别。当在全局范围中定义时,var会导致在全局变量(Node中的global)上定义属性,而const不会。

如果意图定义全局,则应将其定义为属性:

global.myconstant = 1;
global.myvariable = 2;

如果需要定义不会重新分配的全局变量,则应该使用描述符(正如另一个答案已经解释的那样):

Object.defineProperty(global, 'myconstant', {
value: 1,
configurable: false,
writable: false
});

通常不鼓励将全局用于本地目的,尤其是在Node等模块化环境中。

最新更新