为什么window.something不会抛出错误?

4

我在我的Ionic应用程序中使用AdMob插件,如文档所示,一种测试插件是否正确加载的方法是执行以下操作:

if(AdMob) {
    ///other config code...
}

现在,在设备上,这个功能运行得非常好。但是,在浏览器中它不起作用; 它会在控制台日志中抛出一个错误:AdMob未定义

我已经找到了一种解决方法来测试插件的存在(而不会在控制台中抛出错误):

if (window.AdMob){...}

我在StackOverflow上看到了多个问题都使用了这种用法。然而,我无法找到一个解释为什么这不会抛出错误的说明。

我有一些模糊的想法,但是如果有经验丰富的人能够更详细地解释一下,我将不胜感激。

编辑:我进行了如下的额外测试:

var a = "hi";
console.log(a); //shows "hi"
console.log(b); //throws an error that b is not defined

var c = {};
c.b = "hi again";
console.log(c.b); //shows "hi again" as expected

//and now for the grand finale
console.log(c.something);//doesn't throw an error, please explain to me in more detail why?

3
当你尝试读取一个不存在的属性(x.y)时,会得到 undefined 值。当你尝试读取一个不存在的变量时,会得到一个引用错误。有人可以在规范文本中找到相关内容。 - Jeremy
1个回答

4
我找不到为什么这不会引发错误的解释。
在第一个示例中,您试图读取完全未定义的标识符的值。在第二个示例中,您尝试从对象中读取属性,该对象可能没有该属性。
尝试读取未定义标识符的值会导致ReferenceError; JavaScript引擎不知道那个标识符是什么。相比之下,尝试读取对象没有的属性的值会产生值undefined
这就是语言的设计方式,Brendan Eich划定了界限:可以从对象读取不存在的属性的值,但不可以读取未声明的标识符的值。
我要指出第三个选项:typeof。您允许将未定义的标识符作为操作数提供给typeof
if (typeof AdMob === "undefined")

即使未声明AdMob,它也不会抛出ReferenceError;相反,typeof将返回"undefined"。(如果AdMob是一个已经声明的标识符,并且其值为undefinedtypeof也会返回"undefined"。)

你在另一个答案的评论中说:

...确实有助于看到官方规范的确切内容来确认此事。

这将是ECMAScript规范,特别是对于在无法解析的符号上抛出ReferenceError§6.2.3.1和对于返回不存在属性的undefined§9.1.8。但是我应该警告您,规范,尤其是这个第六版规范,非常难以理解。 :-)


太棒了,谢谢你,这真是一个详尽的答案。还有感谢官方参考! - Nikola

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