JavaScript == 和 ===

简介: JavaScript == 和 ===

== 操作符(Equality,相等操作符)

相等操作符会做类型转换。

我们先来看看什么是类型转换(type coercion)

当操作符两边的操作数是不同类型时,其中一个操作数将转换为另一个操作数同类型的“等效”值。比如:

12 - '3' // 9, 将 string 类型转换成 number 类型,相当于 12 - Number('3')
12 - 'hello' // NaN, 因为 Number('hello') 为 NaN,12 - NaN 为 NaN
'3' - 12 // -9, 同样转成 number 类型
12 - true // 11, Number(true) 为 1
false - 12 // -12, Number(false) 为 0
12 + '3' // 123, 将 12 转换成 string 类型,再连接 '3'

看上去很简单对不对?减法将非 number 类型的转换成 number 类型的,加法将 number 类型转换成 string 类型的,真的这样吗?看下面:

12 + true // 13,这里将布尔类型 true 转换成数值类型 1,相当于 12 + Number(true)

从上面可以看出,“加法将 number 类型 转换成 string 类型”这个总结并不正确,事实上,类型转换并不单单看操作符,也就是并不只是看你做加法还是做减法,还要看你的类型,我们从上面的规律中做下总结:

  • number - string 将 string 转换成 number
  • string - number 将 string 转换成 number
  • number - boolean 将 boolean 转成 number
  • boolean - number 将 boolean 转成 number
  • number + string 将 number 转成 string
  • number + boolean 将 boolean 转成 number
  • ...

有点眼花,也不是很有规律。有时候类型转换还可能会调用 toString 方法,加上操作符有很多,像 +、-、*、/、%、、= 等等,再加上 5 种基本数据类型 Number、String、Undefined、Null、Boolean,还有引用类型 Object,这样组合起来,类型转换的规律就很难掌握了。

比如下面这个:

[1] - 3 // -2, 相当于 Number([1].toString()) - 3
[1, 2, 3] - 3 // NaN, 这里 toString 之后 会得到 '1,2,3',转成 number 就是 NaN
[[]] - 3 // -3, [[]].toString 是 "","" 转成 number 类型是 0
5 * '1' // 5, Number('1') 为 1
5 * 'true' // NaN, Number('true') 为 NaN
5 * true // 5, Number(true) 为 1

是不是觉得规则已经比较难记忆了?

回到我们的 == 操作符

相等操作符在比较时,如果左右两边的类型不同,也会将左边或者右边的操作数转换成与对方同类型的等效值。比如:

12 == "12" // true, string 类型转换成 number 类型
1 == true // true, boolean 类型转换成 number 类型
true == '1' // true, 两者都转换成 number 再比较? 还是 '1' 转换成 boolean 类型?
true == '2' // false?? Boolean('2') 可是等于 true 哦,结合上面一条语句,可以得出应该是两者都转换成 number 再比较

再来看看 == 操作符的传递性

0 == '' // true
0 == '0' // true
'' == '0' // false

可以看出,== 操作符不满足传递性

再来看几个例子:

false == 'false'    // false
false == '0'        // true
false == undefined  // false
false == null       // false
null == undefined   // true
' \t\r\n ' == 0     // true

是不是觉得还能理解,但可能记不住了?所以,如果你不了解所有的规则,最好不要使用相等操作符,而是使用恒等操作符

规则这么多,掌握不好容易出错。

=== 操作符(Identity,恒等操作符)

很多人认为恒等操作符代表值相等,并且有相同的类型,但这是不对的,来看下面的例子:

var a = [1, 2, 3],
    b = [1, 2, 3],
    c = {},
    d = {};
console.log(a === b); // false
console.log(c === d); // false

可见,即使是相同的类型,而且值相等,也不一定恒等。

恒等

恒等操作符有三种情况:

  1. 两个操作数都是引用类型,他们都引用同一个 object,即地址相同,则恒等成立。
  2. 两个操作数都是基本数据类型 (Boolean、Number、String、Undefined、Null),如果值相同,则恒等成立。
  3. 一个操作数是引用类型,另一个是基本数据类型,恒等不成立。

上面的例子不等是因为地址不同。我们再来看看比较特殊的 String:

String 的基本数据类型和基本包装类型

我们知道,基本数据类型不是引用类型,应该是没有方法的,比如 'hello world',但你确实可以用 'hello world'.split("") 分割字符串,这是因为调用 split 这个方法的时候,后台就会创建一个基本包装类型的对象 (new String('hello world')),我们实质上是从这个基本包装类型里获取的方法,这样的基本包装类型还有 Boolean 和 Number。

要明确,'hello world' 只是一个基本数据类型,不管它是拼接而成还是直接以字面量的形式形成,比如:

var a = 'hello' + ' world',
    b = 'hello world';
console.log(a === b); // true

因为 a、b都是基本数据类型,所以直接比较值,是相等的,那么恒等成立。

但如果是这样:

var a = 'hello world',
    b = new String('hello world');
console.log(a === b); // false, 因为 a 是基本数据类型,b 是引用类型,恒等不成立。

来看一下恒等操作符的比较情况:

所以 Douglas Crockford 建议我们永远不使用 == 操作符,而是使用 === 操作符

另外,在引用类型的比较上 == 和 === 的表现还是一致的,因为不论是否有类型转换,值都是地址,即比较的都是地址,地址相同则相同,如有不对,还望指出:

var a = [1, 2, 3],
    b = [1, 2, 3],
    c = {},
    d = {},
    e = a;
console.log(a === b); // false
console.log(c === d); // false
console.log(a == b); // false
console.log(c == d); // false
console.log(a == e); // true
console.log(a === e); // true
console.log([0] == (new String("0"))); // false
console.log([0] === (new String("0"))); // false


目录
相关文章
|
2天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
254 116
|
17天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
11天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
650 220
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
886 61
|
9天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1478 157
|
6天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
282 139
|
8天前
|
存储 安全 固态存储
四款WIN PE工具,都可以实现U盘安装教程
Windows PE是基于NT内核的轻量系统,用于系统安装、分区管理及故障修复。本文推荐多款PE制作工具,支持U盘启动,兼容UEFI/Legacy模式,具备备份还原、驱动识别等功能,操作简便,适合新旧电脑维护使用。
594 109