74

JSLint 没有将此作为有效代码传递:

/* global someVar: false */
if (typeof someVar === "undefined") {
    var someVar = "hi!";
}

正确的方法是什么?

4

11 回答 11

97
/*global window */

if (window.someVar === undefined) {
    window.someVar = 123456;
}

if (!window.hasOwnProperty('someVar')) {
    window.someVar = 123456;
}
于 2012-07-21T22:39:26.203 回答
15
/**
 * @param {string} nameOfVariable
 */
function globalExists(nameOfVariable) {
    return nameOfVariable in window
}

使用 var foo 还是 window.foo 创建全局变量都没有关系——在全局上下文中使用 var 创建的变量会写入到 window。

于 2012-07-21T22:30:01.857 回答
14

如果您只想分配一个不存在的全局变量,请尝试:

window.someVar = window.someVar || 'hi';

或者

window['someVar'] = window['someVar'] || 'hi';
于 2012-07-21T22:43:10.170 回答
9

尝试

variableName in window

或者

typeof window[variableName] != 'undefined'

或者

window[variableName] !== undefined

或者

window.hasOwnProperty(variableName)
于 2012-07-21T22:35:07.163 回答
9

我认为这实际上是 JSLint 的一个问题。它将发出以下错误:

意外的“类型”。直接与“未定义”进行比较。

我相信这是个坏建议。在 JavaScript 中,undefined是一个全局变量,通常是未定义的。但有些浏览器允许脚本对其进行修改,例如:window.undefined = 'defined'. 如果是这种情况,直接比较undefined可能会导致意想不到的结果。幸运的是,当前兼容 ECMA 5 的浏览器不允许分配到undefined(并且会在严格模式下抛出异常)。

我更喜欢typeof someVar === "undefined",正如你发布的那样,或者someVar in window像 Susei 建议的那样。

于 2012-07-21T22:37:18.127 回答
6
if (typeof someVar === "undefined") {
    var someVar = "hi!";
}

将检查someVar(本地或全局)是否未定义。

如果要检查全局变量,可以使用

if(window['someVar'] === undefined) {
    ...
}

假设这是在浏览器中:)

于 2012-07-21T22:34:03.883 回答
1

bfavaretto 不正确。

将全局 undefined 设置为一个值不会改变对象针对 undefined 的测试。在你最喜欢的浏览器 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".
于 2012-09-24T11:44:36.123 回答
1

这将是一种执行检查的简单方法。

但是如果variableName声明并分配了boolean value: false

if(window.variableName){

}
于 2014-05-13T06:39:38.080 回答
1

从 ES6 开始,大多数其他答案,包括已接受的答案,都是不正确的,因为由letor定义的全局变量const或由声明产生的全局变量在全局对象(在浏览器或node.js 中)class上没有相应的属性。其中一些——主要是那些使用的——也可能被存在但设置为的全局变量所欺骗。windowglobaltypeofundefined

测试全局变量是否存在的唯一完全通用的方法——不管它是使用var,let还是const通过functionorclass声明创建的,还是通过赋值创建的(即,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)模块,是否在异步函数中等等。

于 2020-06-24T14:27:53.463 回答
1

我认为最好的解决方案如下:

if(window.hasOwnProperty('foo')) {
    console.log('Variable is not declared');
}

如果变量已声明但未分配 (var foo;),则以下解决方案将不起作用。

typeof foo === 'undefined'
于 2020-06-24T21:39:02.400 回答
0

如果您不确定是否定义了全局变量,您可以随时尝试访问它并查看会发生什么。

function node_env(name) {
    try {
        return process.env[name];
    } catch (ignore) {}
}
于 2022-01-13T11:32:29.867 回答