哈喽,大家好,我是Fine。
我们都知道,JavaScript是一种弱类型语言,它会自动进行类型转换以使表达式得到合理的结果。类型转换是一种常见的操作,其中之一是将一个值转换为原始类型。
在看正文之前,我们先来了解一下ToPrimitive
ToPrimitive 是 JavaScript 中用于将值转换为其对应的原始类型的抽象操作。
ToPrimitive 的转换规则如下:
这些规则确保 JavaScript 在进行类型转换时遵循一定的优先级和规则,以便得到预期的结果。
在了解ToPrimitive之后,我们来详细看看[] == ! []为什么会返回ture?
以下是正文:
本文的讲解是建立在类型转换的基础上,如果对类型转换机制不了解的同学可以先了解一下
在 JavaScript 学习过程中,往往出现一些与我们常理相违背的结果,比如我们今天的论题[] == ![] ,它的返回的结果竟然是true ,这着实让初学者感到困惑。因为根据直觉,[]和![]两者应该是不相等的。面试官恰恰就会抓住这一点,对程序员们进行考察。
而本文将结合官方文档对该题进行深度剖析。
==关于==,文档这样描述:
根据官方文档,我总结了以下 == 的隐式转换规则,一些简单的就忽略掉了:
类型相同的比较:
(1)如果类型是 Undefined 或 Null,返回 true。
null == null; // true
(2)如果一个是 +0,另一个是 -0,返回 true:
+0 == -0; // true
(3)如果类型是对象,二者引用同一个对象,返回 true,反之返回 false。
{} == {}; // false
null 和 undefined 比较: 仅当它们之间的比较时,返回 true。
null == undefined; // true
false,包括NaN自己。NaN == NaN; // false
'5' == 5; // true,将字符串 '5' 转换为数字 5 进行比较
true 转换为 1,false 转换为 0),非布尔值也需要转换成数字再比较。true == 1; // true,将布尔值 true 转换为数字 1 进行比较
false == '123'; // false,将布尔值 false 转换为数字 0 ,将字符串 '123' 转换为数字 123 进行比较
ToPrimitive 转换为原始类型,然后进行比较。_(即如果原始类型为字符串,则对象转换成字符串再比较;如果原始类为布尔值,则将布尔值与对象都转换成数字进行比较;如果原始类为数字,则将对象转换成数字进行比较。)_举个例子:
{} == 1; //false
ToPrimitive 在上面详细介绍过,这里我们直接当做公式套用。
ToPrimitive(obj, Number) ==> Number({})
如果 obj 是基本类型,直接返回 否则,调用 valueOf 方法,如果得到原始值,则返回 否则,调用 toString 方法,如果得到原始值,则返回 否则,报错
首先{}先被ToPrimitive转换成字符串"[object Object]",就相当于直接判断 "[object Object]" == 1,字符串与数字的比较中,又要将字符串转换成数字,"[object Object]"转换成数字为 NaN,而NaN 与任何值比较都为 false。
所以 {} == 1 返回 false。
回到[] == ! []
这里判断[]与![],两边都是对象,那怎么比呢,我们发现右边还有一个!,我们知道!的优先级是要大于==的,那么先进行非运算。
!关于!,文档这样描述:
上表为各数据类型转换成布尔值的结果。
简而言之,!这个运算符会进行两步操作:
对
!后面的操作数转换成布尔值将这个布尔值取反
于是我们判断![],将[]转换成布尔值,我们在官方文档中就知道了,任何对象转换成布尔值都得到ture,然后在取反,得到![]为false。
原式[] == ![]经过!运算将等式右边转换成了 false。即[] == false。
接着,根据==隐式转换规则,等式两边为对象和布尔,那么它们都应该转换成数字进行比较。
[]经过ToPrimitive会被转换成字符串""。再将等号两边的字符串""和布尔值false转换成数字 0 ,得到 0 == 0 。打印得到 true。
所以实际在进行[] == ! []判断时,在JS引擎内部,会将这行代码执行成这个样子:
[] == ![]
[] == !true // 将空数组这个对象类型转换成布尔值
[] == false // ! 运算符对 true 进行取反
'' == false // 对 [] 进行 ToPrimitive 操作,返回一个空对象
0 == 0 // 将等号两边都转换成数字类型
看到这里,恭喜你又拿下一道大厂面试题!
希望这篇文章能够为你提供帮助,如果你还有不懂之处,可以反复阅读,或者在评论区留言,学习是一个循序渐进,敢于试错的过程,我们顶峰相见!
原文地址:https://juejin.cn/post/7308536984028856346
原文作者:阳阳羊
还没有使用过我们刷题网站(https://fe.ecool.fun/)或者前端面试题宝典的同学,如果近期准备或者正在找工作,千万不要错过,我们的题库主打无广告和更新快哦~。
老规矩,也给我们团队的辅导服务打个广告。