我在代码中使用一个名为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
)。
答案 0 :(得分:3)
你的例子:
if (typeof DEBUG === 'undefined') var DEBUG = false;
工作得很好。
你想要提升是正确的,但它不会在这里引起你的问题,因为这对解释者来说真的是这样:
var DEBUG;
if (typeof DEBUG === 'undefined') DEBUG = false;
但是,var DEBUG
在此范围内已定义DEBUG
时不执行任何操作。它不会影响此范围内相同名称的先前定义的变量,它不会导致错误,也不会更改DEBUG
变量的值。它所做的只是定义它(如果它还没有在这个范围内定义)。
注意:对于const
或let
,情况并非如此,这些情况不允许您重新声明"同一范围内的现有变量(它们将其变为错误)。您只能使用var
。
您的评论似乎表明您正在尝试影响node.js中的全局变量(即使您的问题没有说明这一点)。 node.js中的全局变量通过global
对象引用。所以,也许你想要的是这个:
if (typeof global.DEBUG === 'undefined') global.DEBUG = false;
在node.js中的严格模式下,无法定义不使用global
前缀的全局变量。这是因为在严格模式下,定义没有前缀的全局变量的唯一方法是在实际全局范围中使用var
或let
或const
,但在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