JSLint 没有将此作为有效代码传递:
/* global someVar: false */
if (typeof someVar === "undefined") {
var someVar = "hi!";
}
正确的方法是什么?
/*global window */
if (window.someVar === undefined) {
window.someVar = 123456;
}
if (!window.hasOwnProperty('someVar')) {
window.someVar = 123456;
}
/**
* @param {string} nameOfVariable
*/
function globalExists(nameOfVariable) {
return nameOfVariable in window
}
无论您使用 var foo 还是 window.foo 创建了全局变量,在全局上下文中使用 var 创建的变量都会写入 window 中。
在全局变量不存在时才赋值该变量,请尝试:
window.someVar = window.someVar || 'hi';
或
window['someVar'] = window['someVar'] || 'hi';
尝试
variableName in window
或
typeof window[variableName] != 'undefined'
或
window[variableName] !== undefined
或
window.hasOwnProperty(variableName)
我认为这实际上是JSLint的问题。它将发出以下错误:
意想不到的"类型"。直接与"未定义"进行比较。
我认为这是个不好的建议。在 JavaScript 中,undefined
是一个全局变量,通常是未定义的。但是有些浏览器允许脚本修改它,如下所示: window.undefined = 'defined'
.如果是这种情况,直接与undefined
进行比较可能会导致意外结果。幸运的是,当前符合 ECMA 5 的浏览器不允许分配undefined
(并且会在严格模式下引发异常(。
我更喜欢typeof someVar === "undefined"
,正如你发布的那样,或者像 Susei 建议的那样someVar in window
。
if (typeof someVar === "undefined") { var someVar = "hi!"; }
将检查someVar
(本地或全局(是否未定义。
如果要检查全局变量,可以使用
if(window['someVar'] === undefined) {
...
}
假设这是在浏览器中:)
从 ES6 开始,大多数其他答案,包括接受的答案,都是不正确的,因为由 let
或 const
定义的全局变量,或由 class
声明生成的全局变量在全局对象上没有相应的属性(在浏览器中window
,或在 node.js 中global
(。 其中一些(主要是使用 typeof
的(也可能被存在但设置为undefined
的全局变量所愚弄。
测试全局变量是否存在的唯一完全通用的方法——无论它是使用 var
、 let
还是 const
声明的,通过function
或class
声明创建,通过赋值创建(即,在程序的顶层myVar = value
没有任何myVar
声明(或通过在全局对象上创建属性(即 window.myVar = value
( - 尝试通过全局eval
访问它,并查看是否抛出 TypeError。
(这建立在Ferran Maylinch提出的想法之上,但有一个技巧来确保它即使在封装在函数中也能正常工作。
function globalExists(varName) {
// Calling eval by another name causes evalled code to run in a
// subscope of the global scope, rather than the local scope.
const globalEval = eval;
try {
globalEval(varName);
return true;
} catch (e) {
return false;
}
}
undeclared = undefined;
const myConst = undefined;
let myLet;
var myVar;
globalExists('undeclared') // => true
globalExists('myConst') // => true
globalExists('myLet') // => true
globalExists('myVar') // => true
globalExists('nonexistent') // => false
globalExists('globalExists') // => true - can see itself.
globalExists('varName') // => false - not fooled by own parameters.
globalExists('globalEval') // => false - not fooled by local variable.
请注意,这使用了 eval
,因此所有常见的警告都适用:您不应提供不受信任的值作为参数,如果必须使用不受信任的值,则应检查以确保varName
是有效的 JavaScript 标识符。 这样做超出了这个问题的范围,但它可以使用(相当复杂的(正则表达式来完成——请注意,正确的正则表达式取决于您使用的 ECMAScript 版本,代码是脚本还是 (ES6( 模块,是否在异步函数中,等等。
bfavaretto 是不正确的。
将全局未定义设置为值不会更改针对未定义的对象的测试。在您最喜欢的浏览器 JavaScript 控制台中尝试一下:
var udef; var idef = 42;
alert(udef === undefined); // Alerts "true".
alert(idef === undefined); // Alerts "false".
window.undefined = 'defined';
alert(udef === undefined); // Alerts "true".
alert(idef === undefined); // Alerts "false".
这仅仅是由于 JavaScript 忽略了尝试在未定义变量上设置的所有和任何值。
window.undefined = 'defined';
alert(window.undefined); // Alerts "undefined".
这将是执行检查的简单方法。
但是,如果声明了variableName
并分配了boolean value: false
if(window.variableName){
}
我认为最好的解决方案如下:
if(window.hasOwnProperty('foo')) {
console.log('Variable is not declared');
}
如果声明了变量但未赋值(var foo;(,则以下解决方案将不起作用。
typeof foo === 'undefined'
如果您不确定是否定义了全局变量,您可以随时尝试访问它并查看会发生什么。
function node_env(name) {
try {
return process.env[name];
} catch (ignore) {}
}