检查全局变量是否存在的正确方法是什么



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 开始,大多数其他答案,包括接受的答案,都是不正确的,因为由 letconst 定义的全局变量,或由 class 声明生成的全局变量在全局对象上没有相应的属性(在浏览器中window,或在 node.js 中global(。 其中一些(主要是使用 typeof 的(也可能被存在但设置为undefined的全局变量所愚弄。

测试全局变量是否存在的唯一完全通用的方法——无论它是使用 varlet 还是 const 声明的,通过functionclass声明创建,通过赋值创建(即,在程序的顶层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) {}
}

相关内容

  • 没有找到相关文章

最新更新