[]==![]的判断、{}+[]\[]+{}

4 篇文章 0 订阅

1.写出下面程序的运行结果:

console.log([] == ![])    // true
console.log([] == [])    // false
console.log([] == {})    // false
console.log(new String('a') == new String('a')) // false
console.log(isNaN(NaN))    // true
console.log(isNaN('32131dsafdas'))    // true
console.log(NaN === NaN)    // false
console.log(NaN === undefined)    // false
console.log(undefined === undefined)    // true
console.log(typeof NaN)     // number

console.log({} + [])    // 0
console.log([] + {})    // "[object Object]"
console.log({} + {})    // "[object Object][object Object]"
console.log([]+ [])    // ""
console.log({} + 1)    // 1
console.log([] + 1)    // "1"


隐式类型转换参考:https://blog.csdn.net/m0_37793545/article/details/87862847
 

前段时间看见这样一道js的题,[] == ![] 的结果,经过在chrome控制台中打印发现结果是true,才发现自己没有完全掌握好 “==”和”===”的底层比较原理。 


于是查阅相关文档,关于”==” 和 “===”的总结: 
“===”叫做严格运算符,”==”叫做相等运算符。

严格运算符的运算规则如下: 
1、如果类型不同,就[不相等] 
2、如果两个都是数值,并且是同一个值,那么[相等];如果其中至少一个是NaN,那么[不相等]。(判断一个值是否是NaN,只能用isNaN()来判断) 
3、如果两个都是字符串,每个位置的字符都一样,那么[相等];否则[不相等]。 
4、如果两个值都是true,或者都是false,那么[相等]。 
5、如果两个值都引用同一个对象或函数,那么[相等];否则[不相等]。 
6、如果两个值都是null,或者都是undefined,那么[相等]。

相等运算符的运算规则如下: 
1、如果两个值类型相同,进行 === 比较。 
2、如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较: 
(1)如果一个是null、一个是undefined,那么[相等]。 
(2)如果任一值是字符串,另一个值是数值,在比较相等性之前先将字符串转换为数值;即是调用Number()函数。 
(3)如果任一值时布尔值,则在比较相等性之前先将其转换为数值,即是调用Number()函数。 
(4)如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。 js核心内置类,会尝试valueOf先于toString;例外的是Date,Date利用的是toString转换。

再次分析 [ ] == ![ ]这道题: 
(1)看见 ![ ]这个是要对空数组转成布尔类型结果得到![ ] = false,(2)发现此时符合第三条,如果任一值是布尔类型是需要将其转换为数值,即Number(false),结果为 Number(false) = 0。(3)此时得到 [ ] == 0比较,此时符合第四条 
即 [ ].toString();结果为[].toString() = ” ”;(4)此时得到 ” ” == 0,发现符合第二条即Number(“”); 
结果为Number(” ”) = 0;(5)此时得到 0 == 0 两个同时为数值类型比较所以结果为true;

 

谈谈JS中的 {} + [] 和 [] + {}
先谈谈为什么会有这种问题,这是因为js的弱类型导致的,js的弱类型,导致js的隐式类型转换频繁。比如像标题中的{} + [],[] + {},你完全不能去预测它的类型。

先来看一条在js里的隐式的rule,js在进行加法运算的时候, 会先推测两个操作数是不是number。 
如果是,则直接相加得出结果。 
如果其中有一个操作数为string,则将另一个操作数隐式的转换为string,然后进行字符串拼接得出结果。 
如果操作数为对象或者是数组这种复杂的数据类型,那么就将两个操作数都转换为字符串,进行拼接 
如果操作数是像boolean这种的简单数据类型,那么就将操作数转换为number相加得出结果

知道了这些规则的话就简单多了

先来看第一个[] + {},这是两个复杂数据结构相加的例子,按照上面的rule,我们先将两个操作数转换为string,然后进行拼接,于是

[] -----> ''
{} -----> '[object Object]'

[] + {} = '[object Object]'



再来看第二个{} + [],这也是两个复杂数据结构相加的例子,看样子与第一个没有什么差别,按理说也应该是[object Object],但是你相加的时候你会发现, 得出的答案是 0!

这是为什么呢?

原因是有的js解释器会将开头的 {} 看作一个代码块,而不是一个js对象,于是真正参与运算的是+[],就是将[]转换为number,于是得出答案0

那么我们如何证明{}被看作一个代码块而不是一个js对象呢?很简单, 我们可以在{}里写上一些语句,比如

{console.log("hello")} + [] 
//hello
//0


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值