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

Ebr*_*owi 56 javascript global-variables jslint

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

/* global someVar: false */
if (typeof someVar === "undefined") {
    var someVar = "hi!";
}
Run Code Online (Sandbox Code Playgroud)

什么是正确的方法?

big*_*ute 80

/*global window */

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

if (!window.hasOwnProperty('someVar')) {
    window.someVar = 123456;
}
Run Code Online (Sandbox Code Playgroud)

  • 为了得到相同的结果,第二个解决方案实际应该是`if(!window.hasOwnProperty('someVar'))` (12认同)
  • 而不是`/*全局窗口*/`,你可以使用`/*jslint browser:true*/`. (5认同)
  • @Offirmo有关如何做的任何想法?在这种情况下,`window`是一个全局变量,我们想要检查它的存在 - 这当然是我们首先要解决的问题. (5认同)
  • 请注意,"窗口"本身未在Web工作者中定义.为获得最大兼容性,请先检查窗口是否存在. (3认同)
  • 如果页面在你之前运行这个脚本怎么办:`undefined ='some value'`? (2认同)
  • @ gion_13`undefined ='some value'; console.log(undefined);`仍然给出`undefined`. (2认同)

gvl*_*sov 13

/**
 * @param {string} nameOfVariable
 */
function globalExists(nameOfVariable) {
    return nameOfVariable in window
}
Run Code Online (Sandbox Code Playgroud)

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

  • 当然,你不必使用函数,只需在窗口`中使用``foo' (4认同)
  • Hrmmm,JSlint说:''意外'在'.与undefined比较,或者使用hasOwnProperty方法.然后,我想,正确的方法是:`window.hasOwnProperty("nameOfVar")` (3认同)
  • @Susei:jsLint不正确.`.hasOwnProperty()`是错误的,因为可能有一个全局位于`window`原型链的下方.它仍然是一个全局变量,但`.hasOwnProperty()`不会看到它.`in`或`undefined`测试是这样做的方法. (2认同)

mra*_*rak 12

如果您只想分配全局变量(如果它尚不存在),请尝试:

window.someVar = window.someVar || 'hi';
Run Code Online (Sandbox Code Playgroud)

要么

window['someVar'] = window['someVar'] || 'hi';
Run Code Online (Sandbox Code Playgroud)


gio*_*_13 8

尝试

variableName in window
Run Code Online (Sandbox Code Playgroud)

要么

typeof window[variableName] != 'undefined'
Run Code Online (Sandbox Code Playgroud)

要么

window[variableName] !== undefined
Run Code Online (Sandbox Code Playgroud)

要么

window.hasOwnProperty(variableName)
Run Code Online (Sandbox Code Playgroud)

  • 您是否尝试在JSLint上测试这些?"'someVar'在窗口中","typeof window ['someVar']!=='undefined'","window ['someVar']!== undefined"(不将其转换为"window.someVar!== undefined")对JSLint不好.但无论如何,谢谢你的答案:) (2认同)

bfa*_*tto 8

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

意外的'typeof'.直接与'undefined'比较.

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

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

  • 今天特别相关,因为并非所有 JS 都将在浏览器中运行。如果您正在编写一个库,您希望您的代码既能在浏览器上运行,也能在不存在 window 的 nodejs 等运行时上运行。 (2认同)

cpc*_*len 6

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

\n

测试全局变量是否存在的唯一完全通用的方法\xe2\x80\x94,无论它是否已使用var,let或声明,通过or声明const创建,通过赋值创建(即,在程序的顶层,没有)的任何声明或通过在全局对象(即)\xe2\x80\x94 上创建属性来尝试通过全局访问它并查看是否引发 TypeError 。functionclassmyVar = valuemyVarwindow.myVar = valueeval

\n

(这建立在 Ferran Maylinch 提出的想法的基础上,但有一个技巧可以确保即使封装在函数中也能正常工作。)

\n
function globalExists(varName) {\n  // Calling eval by another name causes evalled code to run in a\n  // subscope of the global scope, rather than the local scope.\n  const globalEval = eval;\n  try {\n    globalEval(varName);\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\nundeclared = undefined;\nconst myConst = undefined;\nlet myLet;\nvar myVar;\n\nglobalExists(\'undeclared\')    // => true\nglobalExists(\'myConst\')       // => true\nglobalExists(\'myLet\')         // => true\nglobalExists(\'myVar\')         // => true\nglobalExists(\'nonexistent\')   // => false\nglobalExists(\'globalExists\')  // => true - can see itself.\nglobalExists(\'varName\')       // => false - not fooled by own parameters.\nglobalExists(\'globalEval\')    // => false - not fooled by local variable.\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,这使用了eval,因此所有常见的注意事项均适用:您不应提供不受信任的值作为参数,并且如果必须使用不受信任的值,则应检查以确保它varName是有效的 JavaScript 标识符。这样做超出了这个问题的范围,但可以使用(相当复杂的)正则表达式\xe2\x80\x94 来完成,请注意,正确的正则表达式取决于您正在使用的 ECMAScript 版本、代码是否是脚本或(ES6)模块,无论是在异步函数中,等等。

\n


Vat*_*tev 5

if (typeof someVar === "undefined") {
    var someVar = "hi!";
}
Run Code Online (Sandbox Code Playgroud)

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

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

if(window['someVar'] === undefined) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

假设这是在浏览器中:)