我正在对JavaScript的typeof
运算符进行一些研究,并偶然发现了以下奇怪之处:</ p>
例外
所有当前浏览器都公开类型为Undefined的非标准主机对象{{1}。
document.all
虽然规范允许非标准异类对象的自定义类型标记,但它要求这些类型标记与预定义标记不同。
typeof document.all === 'undefined';
类型为document.all
的案例必须归类为违反规则的行为。
(Source)
我在浏览器中设置了以下内容进行测试:
'undefined'
它屈服了:
console.log("typeof: " + typeof document.all);
console.log("toString: " + document.all);
为什么typeof: undefined
toString: [object HTMLAllCollection]
会这样?由于document.all
是一个对象(在我的浏览器中定义),不应该document.all
返回typeof
,而不是"object"
?
答案 0 :(得分:6)
all
属性必须返回以HTMLAllCollection
为根的Document
all
节点,其过滤器匹配所有元素。
all
返回的对象有几种不寻常的行为:
当给定为所有对象返回的对象时,用户代理必须表现为JavaScript中的ToBoolean抽象操作返回false。
当给定为
true
返回的对象时,用户代理必须表现为抽象等同比较算法返回undefined
时 与null
和all
值相比较。 (比较使用 严格的等式比较算法和抽象平等 与其他值(如字符串或对象)的比较是 不受影响。)- 醇>
用户代理必须采取行动,使得JavaScript中的typeof运算符在应用于返回的对象时返回字符串“undefined”
document.all
。
第三种情况是你的。
这个的基本原理是与为旧浏览器设计的代码兼容,如规范中的说明所述:
这种违规行为的动机是希望兼容两类遗留内容:一种使用
document.all
作为检测旧用户代理的方法,另一种仅支持那些旧用户代理和用途select GET_ANNUAL_INCOME(3) from dual;
对象没有首先测试它的存在。
希望它对你有意义。
答案 1 :(得分:0)
变通方法更新:
document.all !== undefined;
>> true /*otherwise*/ false
由于https://html.spec.whatwg.org/需要,...
当给定为所有对象返回的对象时,用户代理必须表现为抽象等同比较算法,与未定义和空值相比时返回true。
但是从......
(使用严格等式比较算法进行比较,与其他值(如字符串或对象)进行抽象等式比较不受影响。)
使用 静态类型比较运算符 (例如: === |!== )可以非常安全地检查< em> HTMLAllCollection 对象在当前的UA客户端中可以使用和/或存在。
动态类型比较运算符 将继续按规范要求返回错误缺席。
document.all != undefined;
>> false /*otherwise*/ false
变通方法(较旧)
"all" in document;
>> true /*otherwise*/ false
处理第三方代码时更精细的方法是
delete document.all && "all" in document
>> true /*otherwise*/ false