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

时间:2012-07-21 22:24:31

标签: javascript global-variables jslint

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

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

正确的方法是什么?

10 个答案:

答案 0 :(得分:73)

/*global window */

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

if (!window.hasOwnProperty('someVar')) {
    window.someVar = 123456;
}

答案 1 :(得分:13)

/**
 * @param {string} nameOfVariable
 */
function globalExists(nameOfVariable) {
    return nameOfVariable in window
}

使用var foo或window.foo创建全局变量无关紧要 - 在全局上下文中使用var创建的变量将写入窗口。

答案 2 :(得分:11)

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

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

window['someVar'] = window['someVar'] || 'hi';

答案 3 :(得分:8)

尝试

variableName in window

typeof window[variableName] != 'undefined'

window[variableName] !== undefined

window.hasOwnProperty(variableName)

答案 4 :(得分:8)

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

  

意外'typeof'。直接与'undefined'比较。

我认为这是一个糟糕的建议。在JavaScript中,undefined是一个全局变量,通常是未定义的。但是有些浏览器允许脚本修改它,如下所示:window.undefined = 'defined'。如果是这种情况,直接与undefined进行比较可能会导致意外结果。幸运的是,当前符合ECMA 5标准的浏览器不允许赋值给undefined(并且会在严格模式下抛出异常)。

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

答案 5 :(得分:4)

if (typeof someVar === "undefined") {
    var someVar = "hi!";
}

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

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

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

假设这是在浏览器中:)

答案 6 :(得分:2)

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".

答案 7 :(得分:1)

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

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

,则此检查将失败
if(window.variableName){

}

答案 8 :(得分:1)

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

测试是否存在全局变量的唯一完全通用的方法,而不管它是使用{{1}创建的varlet还是const声明的}}或function声明,它是通过赋值(即程序的顶层的class,而对myVar = value没有任何声明)或在全局对象上创建属性(即, myVar)-尝试通过全局window.myVar = value访问它,并查看是否抛出TypeError。

(这构建了on an idea presented by Ferran Maylinch,但有一个技巧,可以确保即使将其封装在函数中也能正常工作。)

eval

请注意,这利用了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. ,因此所有常规警告都适用:您不应提供不可信值作为参数,并且如果必须使用不可信值,则应检查以确保{{ 1}}是有效的JavaScript标识符。这样做超出了此问题的范围,但是可以使用(rather complex) regular expression来完成—请注意,正确的正则表达式取决于您使用的ECMAScript版本,无论代码是脚本还是(ES6)模块,是否在异步函数中等等。

答案 9 :(得分:0)

我认为最好的解决方案是:

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

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

typeof foo === 'undefined'