document.all 奇怪的地方在于它是一个数组(其实是对象),但是类型却是 undefined。
先看控制台代码
>>> document.all HTMLAllCollection[1009] // 控制台打印出一个数组 >>> document.all[0] <html>...</html> // 第一个元素是 html 标签,看起来很像一个数组 >>> typeof document.all 'undefined' // 咦,居然不是 object? >>> if(document.all){console.log('document.all 为真')}else{console.log('document.all 为假')} document.all 为假
我第一次看到 document.all 的时候也很惊讶,怎么会有这么奇葩的对象。
用各个浏览器测试一下结果如下:
所有浏览器都支持用 document.all[index] 或者 document.all[id] 获取标签 但是 typeof document.all,在 IE 10 以下的值为 ‘object’,在其他浏览器的值均为 ‘undefined’ 为何会这样?那我们就要从很久很久以前说起了。多久呢,大概20年前。
那个时候,浏览器刚刚出现,很多功能不完善,比如 document.getElementById,都有很多浏览器不支持。甚至连 W3C 都还没制定出 Web 标准,这个时候 IE 4(我擦我都没见过 IE 4)推出了一些 API,只有 IE 4 支持,其中就包括我们今天说 document.all,它比 document.getElementById 要好用一些,比如你可以用 document.all[‘topbar’] 来获取元素,所以那个时候很多程序员会些这样的代码:
if(document.all){ // IE 4 代码 document.all['topbar'] ... }else if(document.getElementById){ // 其他浏览器代码 document.getElementById('topbar') }
甚至某些程序员直接认为 document.all 为真的浏览器,就是 IE。也就是这样:
if(document.all){ // IE }else{ // 非 IE }
其他浏览器(网景)觉得 IE 4 有的功能,我也要有才行。于是也加上 document.all,功能一样,可以获取元素。
但是呢,其他浏览器又不想被某些程序员认为是 IE,于是 typeof document.all 的值定为 undefined。
有人说 W3C 标准出来后,为什么浏览器不把 document.all 纠正过来,去掉或者变成一个正常的对象都可以啊。
太天真了,如果浏览器这么做了,那么当时世界上会有很多页面 JS 代码都不能正常运行,到时候用户只会怪浏览器不给力,然后卸载掉浏览器。
浏览器厂商才不想冒这样的风险。
于是,最终,我们在所有浏览器上得到了一个类型为 undefined 的 document.all,只有 IE 10 以下,然后保留着 IE 4 的行为。
不过 document.all 现在已经被弃用了,大家不要再使用它了。用 document.getElementById 或者 document.querySelector 就好 :)
本文只是讲 document.all 吗?不。
现在的前端新人,对浏览器的演化过程并没有任何体会,以为浏览器天生就是按照 Web 标准实现的。发现 IE 不兼容就指责 IE。
浏览器也是软件,浏览器也会犯错,而且浏览器是一直在发展的。
有时间,可以看看浏览器的历史。