为什么定义了document.all但是typeof document.all返回" undefined"?

时间:2016-11-16 22:35:55

标签: javascript dom

我正在对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"

2 个答案:

答案 0 :(得分:6)

Html Spec

看一下这个
  

all属性必须返回以HTMLAllCollection为根的Document   all节点,其过滤器匹配所有元素。

     

all返回的对象有几种不寻常的行为:

     
      
  1. 当给定为所有对象返回的对象时,用户代理必须表现为JavaScript中的ToBoolean抽象操作返回false。

  2.   
  3. 当给定为true返回的对象时,用户代理必须表现为抽象等同比较算法返回undefined时   与nullall值相比较。 (比较使用   严格的等式比较算法和抽象平等   与其他值(如字符串或对象)的比较是   不受影响。)

  4.   
  5. 用户代理必须采取行动,使得JavaScript中的typeof运算符在应用于返回的对象时返回字符串“undefined”   document.all

  6.   

第三种情况是你的。

这个的基本原理是与为旧浏览器设计的代码兼容,如规范中的说明所述:

  

这种违规行为的动机是希望兼容两类遗留内容:一种使用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