当前位置: 首页 > news >正文

JS中的值比较操作:==,===,Object.is()

原本是想简单写一下==和===之间的区别,后来看了下mdn发现了一些额外的相关知识,于是一并记录了下来

直接看MDN:JS中的相等性判断

JavaScript提供三种不同的值比较操作:

  • 严格相等 ("triple equals" 或 "identity"),使用 === ,
  • 宽松相等/抽象相等 ("double equals") ,使用 ==
  • 以及 Object.is (ECMAScript 2015/ ES6 新特性)

其区别在于,在用于判断两值是否相等时,若两值为数据类型不同,==会先转换数据类型再比较值,===不会进行类型转换(所以对于类型不同的值,===直接返回false),Object.is()与===类似,但对于NaN和-0,+0会进行特殊处理

NaN === NaN    //false
-0 === +0    //true
Object.is(NaN, NaN)    //true
Object.is(-0, +0)    //false复制代码

综上,个人认为Object.is()在对待NaN的处理是符合直觉的,===在对待-0,+0的处理是符合直觉的

下面列一些零散的知识点

===效率比==高

因为===不涉及类型转换。个人认为应该尽量用===,要尽量避免==这种骚操作

x !== x ?

JS中只有NaN符合以上表达式

==的类型转换

相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。在转换后(等式的一边或两边都可能被转换), 最终的比较方式等同于全等操作符 === 的比较方式。 相等操作符满足交换律(即a == b和b == a是一样的)


  • null和undefined和Number,String,Boolean做比较时自身不会进行类型转换,比较的另一方Number,String,Boolean也不会进行类型转换。即null,undefined和原始数据类型做比较时比较的双方都不会发生类型转换,所以均返回false,但与Object比较时会判断该对象是否是一个假值。
falsy(虚值)是在 Boolean 上下文中已认定可转换为‘假‘的值
Boolean 上下文:需要将值转化为布尔值的场景,如条件语句和循环语句

印象中JS的对象都是真值,但其实存在一类十分不常见的可以转换为假值的对象,如document.all

document.all instanceof Object    //true
typeof document.all    //undefined
document.all == undefined    //true复制代码
  • Number在使用==做比较时具有最高的权重。这里的最高权重是我个人的理解。即五种原始数据类型中(不包括symbol),除undefined和null外(这两个大哥与任何类型的值做比较都不会自身都不会做类型转换)。剩下三种原始数据类型在做比较时遇到数据类型不一致时,非Number的数据类型都会使用Number() ?? 先转换为Number类型的值

1 == "1" ==> 1 == Number("1")
"1" == true ==> Number("1") == Number(true)    //true
Number(true)    //1
Number(false)    //0复制代码
  • Object在使用==做比较时权重最低。Object和Object做比较时,比较的是指针,不会进行数据类型转换。但如果Object和Number,String,Boolean比较,会调用toString或valueOf方法,将对象转换为原始值(Primitive),同时如果另外一个原始值不是Number,会使用Number将其转换为Number

[] == false    //true
解析:
[].valueOf() ==> [],[].toString() ==> "" Number("") ==> 0
Number(false) ==> 0,0 == 0 ==> true

a = {}
a.toString()    //"[object Object]"

b = {}
Object.prototype.toString = function() {return 0}
b == "" //true复制代码

总结:乍一看使用==做比较时类型转换的规则比较繁琐,但总结下来核心就三条

  • null和undefined不会做任何数据类型转换
  • 非Number的原始数据类型会先使用Number()将其转换为Number类型(null, undefined除外)
  • Object和非Object类型的数据做比较时(null,undefined除外),会先使用toString或valueOf将其转换为原始数据类型(字符串类型)

但个人觉得实际工作中还是不要用 == 比较好,太JBSD

纠正:2019-5-19

发现自己之前写的有明显的错误,在此纠正。

之前认为Object类型和原始类型比较时,若另一运算子是字符串类型,会使用String方法转换对象。String方法转换对象的算法是先调用对象的toString方法,若返回不是原始类型,则再调用valueOf方法。若返回还不是原始类型,则报错。若另一运算子是数值或布尔类型,则会调用Number方法。Number方法也是调用valueOf和toString方法,只不过是先调用valueOf方法再调用toString方法


相关文章:

  • 解决*.props打开失败问题
  • selector在手机上或浏览器显示各种姿势(虚拟下拉菜单)
  • 使用benchmarkSQL测试数据库的TPCC
  • 8.C(内存管理)
  • 产品上线后,出现BUG的处理流程
  • Greenplum修改GPCC的密码
  • 2019第十一周编程总结
  • 设计模式--Singleton_(1)(C#版)
  • 数据结构与算法-数组(Array)
  • Linux-01初级学习
  • Go语言中时间函数及定时器的使用
  • react——jsx源码解析
  • 拿Proxy可以做哪些有意思的事儿
  • centos7 安装 rabbitmq
  • 如何快速学习Java?
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • CSS 三角实现
  • go append函数以及写入
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • LintCode 31. partitionArray 数组划分
  • Linux后台研发超实用命令总结
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • vue-loader 源码解析系列之 selector
  • WebSocket使用
  • 编写高质量JavaScript代码之并发
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 手写一个CommonJS打包工具(一)
  • 算法---两个栈实现一个队列
  • 线性表及其算法(java实现)
  • 优化 Vue 项目编译文件大小
  • puppet连载22:define用法
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #控制台大学课堂点名问题_课堂随机点名
  • (4)Elastix图像配准:3D图像
  • (NSDate) 时间 (time )比较
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (多级缓存)缓存同步
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (接口封装)
  • (算法)求1到1亿间的质数或素数
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)创业家杂志:UCWEB天使第一步
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET DataGridView数据绑定说明
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET NPOI导出Excel详解
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .NetCore项目nginx发布