Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

js中相等性判断探索 #12

Open
KangXueLiang opened this issue Dec 26, 2019 · 0 comments
Open

js中相等性判断探索 #12

KangXueLiang opened this issue Dec 26, 2019 · 0 comments

Comments

@KangXueLiang
Copy link
Owner

js中相等性判断探索

最近发现一个比较神奇的问题如下:

  • [] == false // true
  • !![] == true // true

一脸懵逼中。。。
那么,现在就来从开始探索一下这道题的原理

js比较操作

js提供了三中不同的比较操作,分别是:

  • 严格相等 ("triple equals" 或 "identity"),使用 ===
  • 宽松相等 ("double equals") ,使用 ==
  • ES6新出的Object.is()

说一下几种操作的特点与不同。首先,使用=== 与Ojbect.is()进行比较时,是不会进行类型转换的,先判断两边的数据类型,如要两边的数据类型不同,就会直接返回false,再判断数据的值是否相同,这里有个坑点就是对于Number,=== 与Ojbect.is()在处理+0, -0, 与NaN方面有一些不同之处,如下

+0 === -0  // true
Object.is(+0, -0) // false

NaN === NaN // false
Object.is(NaN, NaN) // true

再来说一下==,这个因为涉及到了类型的转换,比较复杂一些。

  • 相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。在转换后(等式的一边或两边都可能被转换),最终的比较方式等同于全等操作符 === 的比较方式。
  • 理解一下两个方法,ToNumber(A),是指在比较前将A转为数字,与 +A(单目运算符+)的效果相同。ToPrimitive(A), 是指通过调用A.toString()或者A.valueOf()方法将A转为原始值(primitive)

然后来看一下表格表格

可知:
1、Undefined 和 Null:一般情况下,他们只和自身及对方相等,其他情况都会返回false。有个IsFalsy()看起来很奇怪,对象不都应该是返回true么,有啥好判断的?还真不是……有些浏览器会允许一些特殊的对象,如:document.all 等,在某些情况下(相等操作符等)充当undefined的角色,所以,他就会返回false。都是坑爹呢这是……
2、Number: 想与Numbr进行对比,二话不说,你先转成number再BB
3、Boolean:刚想与Boolean做比较,额,他倒是先转成Number了,得嘞,走上了与Number比较的老路
4、Object:可能因为Object比较杂,所以需要先通过ToPrimitive()去找到他的真身以后再进行比较
5、String:优先级最低,因为留给他的对手不多了,一般都是被迫转型,除非对手是String或者ToPrimitive()是String

看起来,类型转换机制还挺复杂的,所以,一般情况下,能用 === 的就尽量不要用 == 了,免得掉进了自己的坑里。什么,非要用==不可?好吧,来看看一下几个案例:

"0" == false; // true
false == 0;  // true 
false == "";  // true
false == [];  // true 
"" == 0;  // true 
"" == [];  // true 
0 == [];  // true 

如果以上这些情况你都能理解,嗯,你可以放心的用==了。
最后,祝大家好运~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant