为什么null==false返回false,而null>=false返回true?JavaScript比较规则

写作背景

因为不理解为什么null==false返回false,而null>=false返回true,所以对 JavaScript的比较运算符==、===、>=、!=的比较规则 部分的知识进行了查漏补缺。

1. == & ===

==是宽松相等,===是严格相等。两者的区别在于:当两边变量类型不相等时,== 会进行隐式转换。(null、undefined除外)

== 的比较规则

  1. 当两边类型相同时,若是原始类型则比较值,若是对象类型,则比较引用是否一致。
  2. 当两边类型不同时,触发隐式转换。

隐式转换规则

什么时候会触发隐式规则?当比较运算符两边的类型不相等时。(null、undefined除外)

  1. boolean vs any,布尔类型-> number
  2. Number vs String,String -> number
  3. 对象类型 vs 原始类型,对象类型 toPrimitive
  4. (null、undefined) vs any,null与非(null、undefined)的值比较总是返回false。

隐式转换的方法共有四种:toString、toNumber、toBoolean、toPrimitive

对于toString和toNumber:

toString toNumber
null "null" 0 (null可理解为no object)
undefined "undefined" NaN
true/false "true"/""false 1/0
10 "10" 10
"hello"/"123" "hello"/"123" NaN/123
1,2,3,4/\[\]/1,null,2,undefined,3 "1,2,3,4"/""/"1,,2,,3" "1,2,3,4"/""/"1,,2,,3"
{} objet Object object Object

对于toBoolean: JS中假值只有6种:false、null、undefined、0、NaN、空字符,其他值转为布尔值全为true。

对于toPrimitive: 获取对象类型的valueOf方法的返回值。如果valueOf不存在/返回的不是原始类型的值,则获取对象的toString()方法的返回值,即遵循ToString规则。如果valueOf和toString都没返回值,则抛出异常。

注意:数组调用valueOf返回数组本身,所以数组一旦toPrimitive相当于调用toString。

2. >=

>= 的比较规则

  • 如果两个变量都是String,则按照字典顺序和Unicode比较.如"cat">"Cat","cat1">"cat","2">"11"
  • 如果两个变量都是原始类型,则转成数值比较。
  • 如果变量是对象类型,则转成原始类型比较(toPrimitive)。

所以null==false返回false,但是null>=false,这是因为 == 比较依据是null与非(null、undefined)都不宽松相等,而 >= 将两边都转成number类型。

3. !=

其算法是先求宽松相等运算符的结果,然后返回相反值。

4. 验收学习成果

js 复制代码
  0 == '' // true
  1 == '1' // true
  1e21 == '1e21' // true
  Infinity == 'Infinity' // true
  true == '1' // true
  false == '0' // true
  false == '' // true
  
  // NaN和任何人都不相等,包括它自己
  
  null == false // false
  undefined == false // false

  [] == ![] // true

  [] == 0 // true
  
  [2] == 2 // true

  ['0'] == false // true

  '0' == false // true

  [] == false // true

  [null] == 0 // true

  null == 0 // false

  [null] == false // true

  null == false // false

  [undefined] == false // true
  // 首先变成 [undefined]==0
  // 接着[undefined].valueOf()返回自身
  // 接着调用toString返回""
  // 所以""==0 返回true

  undefined == false // false
//  undefined 和 非(null、undefined)都返回false
    
    [2,3,4]>=[2,3,4] // true
    [2,3,4]==[2,3,4] // false
    let a = [2,3,4]
    a==a // true
    a==[2,3,4]// false
    [2,3,4]>=[1,2,3] // true
    [2,3,4]>=[1,2,3,999] // true
JS 复制代码
  Number([]) // 0
  Number(['10']) //10

  const obj1 = {
    valueOf () {
      return 100
    },
    toString () {
      return 101
    }
  }
  Number(obj1) // 100

  const obj2 = {
    toString () {
      return 102
    }
  }
  Number(obj2) // 102

  const obj3 = {
    toString () {
      return {}
    }
  }
  Number(obj3) // TypeError
Reference

javascript学习之比较运算符_javascript 连续比较 <-CSDN博客 从一道面试题说起---js隐式转换踩坑合集 - 掘金 (juejin.cn)

相关推荐
成都渲染101云渲染66666 小时前
如何在3ds Max中实现更快、更高质量的渲染
前端·javascript·人工智能
我叫黑大帅10 小时前
MySQL 并发插入竞态问题:原子写入实践指南
后端·mysql·面试
SRET10 小时前
Mineradio 沙盒隔离安装完全指南 | 一键安全运行 Electron 应用!!!
javascript·经验分享·安全·electron·aigc·音视频·ai编程
全栈前端老曹10 小时前
【MongoDB】安全与权限管理 —— 用户认证、角色权限、SSL 加密
前端·javascript·数据库·安全·mongodb·nosql·ssl
我叫黑大帅11 小时前
别再手动写 updated_at了,这坑我踩过
后端·面试·go
ShineWinsu11 小时前
对于Linux:网络基础的解析
linux·网络·面试·udp·笔试·ip·tcp
咖啡星人k12 小时前
从Vibe Coding到Prompt Engineering:AI编程的新技能树
面试·职场和发展·ai编程
free3513 小时前
作用域链与 Environment:变量查找、遮蔽和赋值怎么实现
javascript
YHL13 小时前
🤖 Agent 智能体开发实战 · 第一课:Tool Use —— 让大模型自动干活
前端·javascript·人工智能
HUMHSX15 小时前
Vue 组件通信核心知识点梳理
javascript·vue.js·ecmascript