在JavaScript“严格模式”中如何定义变量只有在全局范围内不存在?

时间:2018-01-15 23:15:05

标签: javascript

我在代码中使用一个名为DEBUG的变量来有条件地收集调试信息:

if (DEBUG) console.log('...');

此变量可能已在其他位置设置,例如,当我想构建生产时,我将其静态设置为false(在优化代码后有效地删除了整行代码)。但是,当未定义时,为了避免未定义的变量错误,我将其设置为默认值:

if (typeof DEBUG === 'undefined') DEBUG = false;

问题是它在strict mode中不起作用,因为不允许使用全局变量DEBUG。如果我将其更改为:

if (typeof DEBUG === 'undefined') var DEBUG = false;

然后它doesn't work正如预期的那样因为在JavaScript中提升。

所以我的问题是在“严格模式”中,如果变量在全局中不存在,我应该如何定义变量?

编辑:windows.DEBUG没有帮助,因为它只适用于不在node.js中的浏览器(我需要它们)并且它也不允许我使用代码优化器来设置全局变量并删除它调试行(参见:UglifyJS doc中的global_defs)。

1 个答案:

答案 0 :(得分:3)

你的例子:

if (typeof DEBUG === 'undefined') var DEBUG = false;

工作得很好。

你想要提升是正确的,但它不会在这里引起你的问题,因为这对解释者来说真的是这样:

var DEBUG;
if (typeof DEBUG === 'undefined') DEBUG = false;

但是,var DEBUG在此范围内已定义DEBUG时不执行任何操作。它不会影响此范围内相同名称的先前定义的变量,它不会导致错误,也不会更改DEBUG变量的值。它所做的只是定义它(如果它还没有在这个范围内定义)。

注意:对于constlet,情况并非如此,这些情况不允许您重新声明"同一范围内的现有变量(它们将其变为错误)。您只能使用var

执行此操作

您的评论似乎表明您正在尝试影响node.js中的全局变量(即使您的问题没有说明这一点)。 node.js中的全局变量通过global对象引用。所以,也许你想要的是这个:

if (typeof global.DEBUG === 'undefined') global.DEBUG = false;

在node.js中的严格模式下,无法定义不使用global前缀的全局变量。这是因为在严格模式下,定义没有前缀的全局变量的唯一方法是在实际全局范围中使用varletconst,但在node.js中使用一切在模块范围内,因此您无法将其中一个声明放入全局范围。因此,在node.js中,创建全局变量必须使用global前缀,如:

global.DEBUG = false;

但是,您可以测试已知的全局变量,而不使用前缀,只要您确定在更近的范围内没有定义相同名称的中间变量(因为如果有,您将测试更接近定义的变量,而不是全局变量。)

if (DEBUG) console.log("in debug mode");

只要在此代码可见的某个范围内已定义DEBUG,这将有效。

你不能做的是:

if (DEBUG) console.log("in debug mode");

什么时候没有定义DEBUG。这将导致Javascript错误。因此,只要您确保定义了DEBUG,就可以在没有前缀的情况下引用它。

如果您正在寻找一种浏览器/ node.js引用可在其中任何一个中使用的全局对象的方式,请参阅:https://gist.github.com/rauschma/7960405