JavaScript 中的类型转换机制以及==和===的区别
目录
- 一、概述
- 二、显示转换
- Number()
- parseInt()
- String()
- Boolean()
- 三、隐式转换
- 自动转换成字符串
- 自动转换成数值
- 四、== 和 === 区别
- 1、等于操作符
- 2、全等操作符
- 3、区别
- 小结
一、概述
我们知道,JS中有六种简单数据类型:undefined、null、boolean、string、number、symbol,以及引用类型:object
但是我们在声明的时候只有一种数据类型,只有到运行期间才会确定当前类型
let x = y ? 1 : a;
上面代码中,x的值在编译阶段是无法获取的,只有等到程序运行时才能知道
虽然变量的数据类型是不确定的,但是各种运算符对数据类型是有要求的,如果运算子的类型与预期不符合,就会触发类型转换机制
常见的类型转换有:
- 强制转换(显示转换)
- 自动转换(隐式转换)
二、显示转换
显示转换,即我们很清楚可以看到这里发生了类型的转变,常见的方法有:
- Number()
- parseInt()
- String()
- Boolean()
Number()
将任意类型的值转化为数值,先给出类型转换规则:
实践一下:
Number(324) // 324// 字符串:如果可以被解析为数值,则转换为相应的数值
Number('324') // 324// 字符串:如果不可以被解析为数值,返回 NaN
Number('324abc') // NaN// 空字符串转为0
Number('') // 0// 布尔值:true 转成 1,false 转成 0
Number(true) // 1
Number(false) // 0// undefined:转成 NaN
Number(undefined) // NaN// null:转成0
Number(null) // 0// 对象:通常转换成NaN(除了只包含单个数值的数组)
Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
从上面可以看到,Number转换的时候是很严格的,只要有一个字符无法转成数值,整个字符串就会被转为NaN
parseInt()
parseInt相比Number,就没那么严格了,parseInt函数逐个解析字符,遇到不能转换的字符就停下来
parseInt('32a3') //32
String()
可以将任意类型的值转化成字符串,给出转换规则图:
实践一下:
// 数值:转为相应的字符串
String(1) // "1"//字符串:转换后还是原来的值
String("a") // "a"//布尔值:true转为字符串"true",false转为字符串"false"
String(true) // "true"//undefined:转为字符串"undefined"
String(undefined) // "undefined"//null:转为字符串"null"
String(null) // "null"//对象
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
Boolean()
可以将任意类型的值转为布尔值,转换规则如下:
实践一下:
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true
三、隐式转换
在隐式转换中,我们可能最大的疑惑是 :何时发生隐式转换?
我们这里可以归纳为两种情况发生隐式转换的场景:
- 比较运算 (==、!=、>、<)、if、while 需要布尔值地方
- 算术运算 (+、-、*、/、%)
除了上面的场景,还要求运算符两边的操作数不是同一类型
#自动转换为布尔值
在需要布尔值的地方,就会将非布尔值的参数自动转为布尔值,系统内部会调用Boolean函数
可以得出个小结:
- undefined
- null
- false
- +0
- -0
- NaN
- “”
除了上面几种会被转化成false,其他都换被转化成true
自动转换成字符串
遇到预期为字符串的地方,就会将非字符串的值自动转为字符串
具体规则是:先将复合类型的值转为原始类型的值,再将原始类型的值转为字符串
常发生在+运算中,一旦存在字符串,则会进行字符串拼接操作
'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
自动转换成数值
除了+有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值
'5' - '2' // 3
'5' * '2' // 10
true - 1 // 0
false - 1 // -1
'1' - 1 // 0
'5' * [] // 0
false / '5' // 0
'abc' - 1 // NaN
null + 1 // 1
undefined + 1 // NaN
null转为数值时,值为0 。undefined转为数值时,值为NaN
四、== 和 === 区别
1、等于操作符
等于操作符用两个等于号( == )表示,如果操作数相等,则会返回 true
前面文章,我们提到在JavaScript中存在隐式转换。等于操作符(==)在比较中会先进行类型转换,再确定操作数是否相等
遵循以下规则:
如果任一操作数是布尔值,则将其转换为数值再比较是否相等
let result1 = (true == 1); // true
如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等
let result1 = ("55" == 55); // true
如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法取得其原始值,再根据前面的规则进行比较
let obj = {valueOf:function(){return 1}}
let result1 = (obj == 1); // true
null和undefined相等
let result1 = (null == undefined ); // true
如果有任一操作数是 NaN ,则相等操作符返回 false
let result1 = (NaN == NaN ); // false
如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true
let obj1 = {name:"xxx"}
let obj2 = {name:"xxx"}
let result1 = (obj1 == obj2 ); // false
下面进一步做个小结:
-
两个都为简单类型,字符串和布尔值都会转换成数值,再比较
-
简单类型与引用类型比较,对象转化成其原始类型的值,再比较
-
两个都为引用类型,则比较它们是否指向同一个对象
-
null 和 undefined 相等
-
存在 NaN 则返回 false
2、全等操作符
全等操作符由 3 个等于号( === )表示,只有两个操作数在不转换的前提下相等才返回 true。即类型相同,值也需相同
let result1 = ("55" === 55); // false,不相等,因为数据类型不同
let result2 = (55 === 55); // true,相等,因为数据类型相同值也相同
undefined 和 null 与自身严格相等
let result1 = (null === null) //true
let result2 = (undefined === undefined) //true
3、区别
相等操作符(==)会做类型转换,再进行值的比较,全等运算符不会做类型转换
let result1 = ("55" === 55); // false,不相等,因为数据类型不同
let result2 = (55 === 55); // true,相等,因为数据类型相同值也相同
null 和 undefined 比较,相等操作符(==)为true,全等为false
let result1 = (null == undefined ); // true
let result2 = (null === undefined); // false
小结
相等运算符隐藏的类型转换,会带来一些违反直觉的结果
'' == '0' // false
0 == '' // true
0 == '0' // truefalse == 'false' // false
false == '0' // truefalse == undefined // false
false == null // false
null == undefined // true' \t\r\n' == 0 // true
但在比较null的情况的时候,我们一般使用相等操作符==
const obj = {};if(obj.x == null){console.log("1"); //执行
}
等同于下面写法
if(obj.x === null || obj.x === undefined) {...
}
使用相等操作符(==)的写法明显更加简洁了
所以,除了在比较对象属性为null或者undefined的情况下,我们可以使用相等操作符"“,其他情况建议一律使用全等操作符”="
参考:
- https://vue3js.cn/interview/JavaScript/%20_=.html#%E4%B8%80%E3%80%81%E7%AD%89%E4%BA%8E%E6%93%8D%E4%BD%9C%E7%AC%A6
- https://vue3js.cn/interview/JavaScript/type_conversion.html#%E4%B8%80%E3%80%81%E6%A6%82%E8%BF%B0
相关文章:

JavaScript 中的类型转换机制以及==和===的区别
目录一、概述二、显示转换Number()parseInt()String()Boolean()三、隐式转换自动转换成字符串自动转换成数值四、 和 区别1、等于操作符2、全等操作符3、区别小结一、概述 我们知道,JS中有六种简单数据类型:undefined、null、boolean、string、number、…...

RocketMQ基础篇(一)
目录一、发送消息类型1、同步消息2、异步消息3、单向消息4、顺序消费5、延迟消费二、消费模式1、集群模式2、广播模式3、消费模式扩展4、如何配置三、其他用法1、事务消息2、过滤消息1)Tag过滤2)SQL方式过滤源码放到了GitHub仓库上,地址 http…...
Android前沿技术—gradle中的build script详解
build.gradle是gradle中非常重要的一个文件,因为它描述了gradle中可以运行的任务,今天本文将会带大家体验一下如何创建一个build.gradle文件和如何编写其中的内容。 project和task gradle是一个构建工具,所谓构建工具就是通过既定的各种规则…...
深入浅出PaddlePaddle函数——paddle.zeros_like
分类目录:《深入浅出PaddlePaddle函数》总目录 相关文章: 深入浅出PaddlePaddle函数——paddle.Tensor 深入浅出PaddlePaddle函数——paddle.ones 深入浅出PaddlePaddle函数——paddle.zeros 深入浅出PaddlePaddle函数——paddle.full 深入浅出Padd…...
物料-零部件分类属性
离散制造业的研发、生产跟产品零部件紧密联系在一起,从企业业务流程来说零部件涉及研发、采购、仓储、生产、质量、售后和配件等多个部门,为了更好地管理零部件,下面我们一起来看看零部件概念及分类。 1、按行业属性分类 (1&…...
TypeError: cannot pickle ‘module‘ object
创建python对象时报错: TypeError: cannot pickle module object 原因: 很大可能是类成员错误的使用了第三方包(别名)等,具体排查方法可参考: import redisimport pickle from pprint import pformat as …...

[MySQL索引]3.索引的底层原理(二)
索引的底层原理(二)InnoDB的主键和二级/辅助索引树(涉及回表)MyISAM存储引擎的主键和二级索引树InnoDB的主键和二级/辅助索引树(涉及回表) 看下面这张student数据库表: 场景一:uid…...
JavaScript混淆——逆向思维的艺术
在本文中我们将介绍三种常见的JavaScript混淆技术。 1.混合名称 通过将函数名称和变量名混合使用,我们可以使代码更难读。下面是一个使用名称混合的JavaScript函数。 function c(a){var b[2,4,8,a],db[0]b[1]b[2]b[3],ed""a;return e}混合名称技术通过…...

数据库管理-第六十期 监听(20230309)
数据库管理 2023-03-09第六十期期 监听1 无法访问2 监听配置3 问题复现与解决4 静态监听5 记不住配置咋整总结第六十期期 监听 不知不觉又来到了一个整10期数,我承认上一期有很大的划水的。。。嫌疑吧,本期内容是从帮群友解决ADG前置配置时候的一个问题…...

概率论与数理统计相关知识
本博客为《概率论与数理统计--茆诗松(第二版)》阅读笔记,目的是查漏补缺前置知识数学符号连乘符号:;总和符号:;“任意”符号:∀;“存在”符号&…...
SOC计算方法:卡尔曼滤波算法
卡尔曼滤波算法是一种经典的状态估计算法,它广泛应用于控制领域和信号处理领域。在电动汽车领域中,卡尔曼滤波算法也被广泛应用于电池管理系统中的电池状态估计。其中,电池的状态包括电池的剩余容量(SOC)、内阻、温度等…...
【C语言】自定义类型、枚举类型与宏定义
目录一、自定义类型二、宏定义三、枚举类型一、自定义类型 自定义类型关键字:typedef,用新的类型名称代替原有的类型名。 例如: typedef char u8; u8 x;表示指定u8为新的类型名,代替char,作用与char相同,…...

Java进阶(下篇2)
Java进阶(下篇2)一、IO流01.File类的使用1.1、File类的实例化1.2、File类的常用方法11.3、File类的常用方法21.4、课后练习02、IO流原理及流的分类2.1、IO流原理2.2、流的分类2.3、IO 流体系03、节点流(或文件流)3.1、FileReader读入数据的基本操作3.2、…...
03单链表
、# 单链表 单链表是一种链式存储的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。单链表中的每个结点包含一个数据域和一个指针域,数据域存放数据元素,指针域存放下一个结点的地址。单链表的第一个结点称为头结点,…...

ESLint、Prettier插件的安装与使用
在统一代码风格这一块,通常大家都会用到ESLint。虽然 ESLint 本身具备自动格式化代码的功能,但ESLint 的主要优势在于代码的风格检查并给出提示,而在代码格式化这一块 Prettier 做的更加专业,因此在实际项目开发中我们经常将 ESLi…...

matlab在管理学中的应用简matlab基础【三】
规划论及MATLAB计算 1、线性规划 问题的提出 例1. 某工厂在计划期内要安排甲、乙两种产品的生产,已知生产单位产品所需的资源A、B、C的消耗以及资源的计划期供给量,如下表: 问题:工厂应分别生产多少单位甲、乙产品才能使工厂获…...

NDK JNI 变声器实现
Android NDK 导入 C库的开发流程学习;通过使用fmod的C库,实现变声器功能。导入库文件1)复制fmod的C库到cpp目录下2)复制fmod的so库到jniLibs目录下3)复制fmod的jar库到libs目录下4)将声音文件复制到assets目…...
VMLogin防关联指纹浏览器的主帐号和子账号区别介绍
VMLogin主账户管理子账户,主要用于团队协作,分账户登录使用,主账户相当于老板,子账户相当于员工。 主账户创建并管理子账户; 主账户可以修改子账户的密码; 主账户可以设置子账户是否有创建配置文件权限&a…...

Apache DolphinScheduler GitHub Star 突破 10000!
点击蓝字 关注我们今天,Apache DolphinScheduler GitHub Star 突破 10000,项目迎来一个重要里程碑。这表明 Apache DolphinScheduler 已经在全球的开发者和用户中获得了广泛的认可和使用。DolphinScheduler 旨在解决公司日常运营中的大数据处理工作流调度…...

程序员中的女性力量——做不被定义的自己
她是office lady,亦是程序媛,程序员界的靓丽色彩,不可或缺。 “只有那些疯狂到以为自己能够改变世界的人——才能真正改变世界。” 女性该如何定义自己?程序媛怎么发挥自己最大的价值。 争取自己做选择,经济和思想都独…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...