• 316

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

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

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

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

静候您的指教:、、、

阅读 1.5k
评论
    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
      • 2.2k

      算是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的基础,还要自己深入去理解,多多学习。

        • 6.7k

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

        崩溃久了就习惯了。

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

            • 4.5k

            用严格模式就简单多了

              • 352

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

                • 680

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

                  撰写回答

                  登录后参与交流、获取后续更新提醒