JavaScript:如何通过变量名检查变量是否存在?

5

我遇到了这个问题。我有一个脚本,检查变量是否存在,因为一些脚本是异步加载的,比如Facebook的FB或Twitter的twttr。

function whenAvailable(name, callback, interval) {
    interval || (interval = 100); // ms
    window.setTimeout(function() {
        if ((window.hasOwnProperty && window.hasOwnProperty(name)) || window[name] || !!eval(name)) {
            return callback();
        } else {
            window.setTimeout(arguments.callee, interval);
        }
    }, interval);
}

看起来是这样的

if ((window.hasOwnProperty && window.hasOwnProperty(name)) || window[name] || !!eval(name)) 

不起作用。IE会对eval(name)抛出错误 ——例如,如果name = 'FB',它会说无法评估'FB',因为它未定义。

如果name == 'twttr.widgets',则window.hasOwnProperty(name)不起作用。

是否有一种通用且跨浏览器的方法来检查变量名存在?


快速问题,这些变量在加载的脚本中是否总是存在? - Joseph
1
不能有一个名为twttr.widgets的变量。可以有一个名为twttr的变量,它可能有一个属性widgets,但希望您能看到这不是简单的“此属性是否存在”。 - Gareth
Gareth - 从技术上讲,你是对的,但我想要的需要与属性一起使用。 - mvbl fst
@Gareth:window里肯定可以有一个叫做twttr.widgets的属性。虽然这很不寻常,但完全是合法的。window['twittr.widgets'] = "foo"; - T.J. Crowder
4个回答

7

首先,你不需要使用eval(几乎从不需要),你可以使用字符串和方括号表示法来索引JavaScript对象,例如:

window['FB'];

或者

name = 'FB';
foo = window[name];

所以要检查:
if (typeof window[name] === "undefined")

...... 但是这并不能区分属性根本不存在和存在但具有值undefined的情况。

或者

if (name in window)

...但它检查的是原型和对象。对于window来说没问题。

如果name == 'twttr.widgets'window.hasOwnProperty(name)将不起作用。

是的,你需要把它拆开:

var index = 0,
    parts = name.split('.'), // doesn't handle [] notation
    result;
result = window;
index = 0;
try {
    while (typeof result !== "undefined" && result !== null && index < parts.length) {
        result = result[parts[index++]];
    }
}
catch (e) {
}
if (index < parts.length) {
    // Didn't find all of it
}

...或类似的东西。

(这句话没有上下文,无法进行更准确的翻译)

谢谢T.J. 我只是将 if (index < parts.length) 改成了 if (index < parts.length || (typeof result == 'undefined' && result === undefined)) return false; - mvbl fst
@SODA:不错的交易。顺便说一下,如果 typeof result == "undefined" ,那么很有可能(尽管在处理跨窗口的内容时并非100%)result === undefined,您可以放弃第二个部分,只保留 typeof 检查。还要注意,我包括了 result !== null 的原因(null 的 typeof 不是 "undefined",但如果您尝试使用括号解引用 null,则会抛出异常)。 - T.J. Crowder

3

我一直都只是使用以下代码:

if (window[name]) {
    return 'it exists';
} else {
    return 'nope';
}

编辑:这个代码有效是因为如果window[name]不存在,那么if语句就会将undefined判断为假。


不,就你的情况而言,如果我写 var name = 'FB',window.name 会返回 'FB',但我需要返回 window['FB'] 或 window.FB。 - mvbl fst

0
你要找的是:
if ('key' in object)
所以在你的例子中
if (name in window)

0
为了解决 twttr.widgetstwttr,可以尝试以下方法:
var parts = name.split( '.' )
  ,  aVar = window;

while( parts.length ){
    aVar = aVar[ aVar.shift() ];
    return setTimeout( ... );
}

// aVar will now be your resolved variable
return callback();

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