对于以下现象,有没有一种通用的判断规则?

我太渴望一种普遍适用的准则解释这一切:

console.log(NaN == NaN);
//false

这个好理解:NaN(not a number),不是一个数字,还可以是很多其它东西,所以不相等

console.log('' == '');
//true

这个也还好理解:空字符等于 空字符,如果不相等,它还能咋地?上天不成?

但下面这个就有点逆天了

console.log([] == []);
//false

空数组不等于空数组,你是想咋地?好像真的上天了,既然如此,我也没辙

曾经还以为,空数组boolean值是false,但实际是true,这个还能接受:数组是objectobjectboolean值都是true,只有nullboolean值是false

console.log(!![]);
//true

后记: 虽然这些知识都比较小众,但是却决定了逻辑判断,选择了程序的走向,所以还是弄清楚为好。这么多东西肯定不可能全凭记忆,我太渴望一种普遍使用的准则来判断(准则肯定是有的,想想设计者的初衷),我不要:试验、根据结果作总结、推翻总结、再试验、再总结、再推翻总结、、、,这种大浪淘沙的过程太让人崩溃了。

静候您的指教:、、、

阅读 4.4k
7 个回答
  1. JS数据类型分为原始类型(Primitive)和对象类型(Object)两大类

  2. 原始类型(number、string、boolean等)的对比是比较值。

  3. 对象类型(array、object等)的==比较是比较引用,[]是字面量数组,是一个新的数组,两个数组的引用不同,所以不相等。

  4. [] == ![]之所以为true,是因为这里做了很多隐式转换,在标准里是这样的

    • 令A为左,B为右

    • B是对[]取非,先需要把B转成Boolean再取非,执行ToBoolean操作

    • []是Object,ToBoolean结果是true,取非结果是false

    • TYPE(A)为 Object ,值为[]

    • TYPE(B)为 Boolean,值为false

    • 两者TYPE不同,TYPE(A)的Object需要执行ToPrimitive操作,隐式转成原始类型

    • 调用[].valueOf(),返回值为[],Type为Object,不是原始类型,抛弃

    • 调用[].toString(),返回值为"",Type为String,是原始类型

    • TYPE(A)为 String, 值为""

    • TYPE(B)为 Boolean,值为false

    • 两者TYPE不同,TYPE(B)需要自行ToNumber操作,隐式转换为Number

    • false隐式转换为Number 0

    • TYPE(A)为 String,值为""

    • TYPE(B)为 Number,值为0

    • 两者TYPE不同,TYPE(A)需要执行ToNumber操作,隐式转换为Number

    • "" 隐式转换为Number 0

    • TYPE(A)为 Number,值为0

    • TYPE(B)为 Number,值为0

    • 两者类型一样,都为简单类型,比较值,值相等

    • 返回true

附上ToBoolean的对应表

Undefined Return false.
Null Return false.
Boolean Return argument.
Number Return false if argument is +0, −0, or NaN; otherwise return true.
String Return false if argument is the empty String (its length is zero); otherwise return true.
Symbol Return true.
Object Return true.

ToNumber的对应表

Undefined Return NaN.
Null Return +0.
Boolean Return 1 if argument is true. Return +0 if argument is false.
Number Return argument (no conversion).
String See grammar and conversion algorithm below.
Symbol Throw a TypeError exception.

其中String的ToNumber比较特殊,可以参见我的这篇写的内容https://zhuanlan.zhihu.com/p/...

" "       ==> 0
"123"     ==> 123
"  123"   ==> 123
"  123  " ==> 123
"a12"     ==> NaN
"1 2"     ==> NaN
"1,2"     ==> NaN
"1b2"     ==> NaN
"12c"     ==> NaN
"1.234"   ==> 1.234
"  1.234" ==> 1.234
" .234"   ==> 0.234

算是JS基本数据类型吧 你真的理解了就不会判断错
ES5 基本数据类型:null, undefined, NaN, string, number, boolean, object
当处理到逻辑判断的时候,通常都是将其他数据转成其对应的boolean值。
相当于是 Boolean(value)的结果。
这种情况只需简单判断:1.有没有值 2.值相不相等
Boolean(null), Boolean(undefined), Boolean(NaN)
这三个结果都是false,可以理解三者语义上表达就是没有值(根本就没有值,应该有值但是没有,不是个数字没法有值)。
Boolean('1'), Boolean(1), Boolean([]), Boolean({})
这几个结果都是true,因为其都是存在的值,因为他们都有各自的内存地址。
至于[] == [], {} == {}
是因为他们的内存地址不同,虽然两者看起来值一样,但是完全不一样
就好比耐克生成的鞋和莆田生产的鞋,外观一模一样,但是产地完全不同类似。
这类问题其实就是JS的基础,还要自己深入去理解,多多学习。

逻辑只是用来帮助猜和理解,不能代替事实。把 == 定义为按值比较, [] == [] 返回true的语言不是没有。

崩溃久了就习惯了。

[] 是有内存地址的, 所以两个空[] 不相等是可以理解的

用严格模式就简单多了

对象{}和数组[]都是存的引用,不要看表面现象

看过《javascript the good parts》没有呢,没有看过的话,去看一下。
不要用 == 要用 ===

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏