让前端飞JavaScript 进阶营

【JS】对象真的都为true吗?

2024-04-23  本文已影响0人  来一斤BUG

平常我们在js的类型转换学习过程中,经常能看到对象转换成布尔值的例子,不论是空对象{}还是原型为null的对象,它们在转换成布尔值之后都为true。那么,对象真的都为true吗?

我们先看看ECMA -262(ECMAScript)规范中针对布尔类型转换是怎么说的(不知道ECMAScript的同学可以先去了解一下):

ToBoolean抽象运算

前两步没啥好说的的,undefined、null、NaN、0、空字符串都为false。重点是这个被替换掉的第三点,我们跳转过去看看:

Changes to ToBoolean

翻译过来就是:如果参数是一个对象并且参数有[[IsHTMLDDA]]内置插槽,就返回false

问题来了,[[IsHTMLDDA]]是什么?

[[IsHTMLDDA]]

[[IsHTMLDDA]]插槽是采用ECMA规范的语言在其内部定义的,外部(比如js)无法获取到这个插槽。根据描述,所有拥有[[IsHTMLDDA]]插槽的对象在转换成布尔值,宽松相等的比较(==)和使用typeof操作符时都应该表现的像undefined

下面是其宽松比较和使用typeof操作符相关的规范

Changes to IsLooselyEqual, Changes to the typeof Operator

那么,什么对象拥有[[IsHTMLDDA]]插槽呢?这个在规范中也提到了:

document.all

除了document.all以外没有其他已知的对象拥有此插槽,也无法手动创建一个插槽。做个测试:

测试

确实和规范里说的一样。

所以为什么document.all这么特殊?简单来说是历史原因,document.all已经被废弃了,取而代之的是document.getElementByIddocument.querySelector等方法,但是为了兼容老的浏览器,就不得不写if (document.all) {xxx} else {document.getElementById(xxx)}这种代码,然而某些现代浏览器依然保留了document.all,导致优先进入了前一个if分支,于是W3C听从了大家的建议,将document.all的规范定义成了如今这样,这样一来老的浏览器判断document.alltrue,但是新的浏览器不论有没有保留document.all,直接判断为false了。

参考:

上一篇 下一篇

猜你喜欢

热点阅读