如何在JavaScript中检查变量是否存在?

30

我不是在询问变量是否未定义或为null。我想检查变量是否存在。这是否可能?


11
这只是我的观点,但基于检查变量或函数是否存在的逻辑似乎是错误的方法。如果你的逻辑期望某个变量存在,我坦率地认为这是语义或语法错误,而不是逻辑决策。 - Matías Fidemraizer
8个回答

25

typeof 技术并不起作用,因为它们不能区分一个变量是否根本未被声明,或者已经声明但尚未被赋值,或者声明并等于 undefined。

但是,如果您尝试在 if 条件语句中使用一个未声明的变量(或在赋值的右侧使用),则会出现错误。所以,这应该可以工作:

var exists = true;
try {
    if (someVar)
        exists = true;
} catch(e) { exists = false; }
if (exists)
   // do something - exists only == true if someVar has been declared somewhere.

2
+1 对于解释和解决方案。考虑这个修改:var exists = false; try { eval("someVar"); exists = true } catch (e) { }; if (exists) ... -- eval() 的目的是防止超级聪明的 Javascript 引擎将其优化掉。它也会欺骗大多数其他静态分析工具。 - user166390
1
是的,即使忽略潜在的优化,我在发布后意识到,在try块内有一个额外的exists = true;是多余和令人困惑的,因为它实际上不是逻辑的一部分:if (someVar) {}应该足够了,因为if()的目的只是尝试崩溃而不是在它工作时做某事。赋值可能比if更好的选择,或者像你说的那样,使用eval。 - nnnnnn
它可以非常简单,例如 var exists = true; try {someVar} catch(e) {exists = false;} - RobG

1
我使用这个函数:

function exists(varname){
    try {
        var x = eval(varname);
        return true;
    } catch(e) { return false; }
}

希望这有所帮助。

如果变量不是全局的呢?(或者你会在需要它的任何函数内部声明该函数吗?) - nnnnnn
4
判断变量是否存在时不要使用 eval。千万不要使用 eval,因为它是一种非常危险的做法,会导致安全漏洞。 - Seb

1
if ('bob' in window) console.log(bob);

记住这种方式,即使您使用var声明了一个变量,也意味着它存在。

2
这不是正确的。window.bob = false 是一个反例。 - user166390
好的,我放弃了之前的代码并重新写了一个新的。 - Mauvis Ledford
如果变量不是全局的,会怎样? - heyallan

0
当您尝试访问未在上下文中声明的变量时,您会看到错误消息显示该变量未定义。这是您可以执行的真正检查,以查看变量是否已定义,而不是null检查。

0
如果在运行时不需要了解,请使用JSLint。还要记住,JavaScript var语句是被升高的,所以即使var在if块内部,它仍将被定义。
老实说,如果您不确定变量是否已定义,则正在做错事,并且应该重构代码。

0
你需要的是:
window.hasOwnProperty("varname");

更安全的方法甚至可能是:

this.hasOwnProperty("varname");

不过这取决于你的调用上下文...


1
如果变量不是全局的呢?那么它就不会成为 windowthis 的属性。 - nnnnnn

0

我认为这取决于您想如何使用变量。

例如,假设您有一个JS库,如果已定义函数,则调用该函数,否则不调用。 您可能已经知道,在JS中,函数是一级对象,并且是变量。

您可能会尝试首先询问它是否存在,然后再调用它。 但是,您也可以将尝试调用它的操作包装在try / catch块中。

以下是调用函数的代码示例(如果已定义),在触发事件之前和之后:

function fireEvent(event)
{
    try
    {
        willFireEvent(event); // Is maybe NOT defined!
    } catch(e) {}

    //... perform handler lookup and event handling

    try
    {
        hasFiredEvent(event); // Might also NOT exist!
    } catch(e) {}
}

所以,不要检查变量,而是捕获错误:

var x;

try
{
    x = mayBeUndefinedVar;
}
catch (e)
{
    x = 0;
}

无论从性能等方面来看,这是否是一件好事都取决于你正在做什么...

0

试一下这个

var ex=false;
try {(ex=myvar)||(ex=true)}catch(e) {}
alert(ex);

其中ex为真,如果myvar已经声明。

工作示例:http://jsfiddle.net/wcqLz/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接