对象和对象进行比较的时候:比较的是空间地址,如果空间地址相同就是 true,不同就是 false
{}=={}(false)
不同的数据类型再进行比较的时候,除了以下的,剩下的都是先转换为数字在比较:
对象和字符串进行比较的时候,把对象转换为字符串,再进行比较
null 和 undefined 永远不等于任何一种数据类型,但是
null==undefined(true)
null===undefined(false)
NaN 永远不等于任何一种数据类型,包括它自己
可以使用
Object.is(NaN, NaN)->true
检测
1 | ![] == true // false ![]=>false转为布尔取反 |
对象数据转换规则
原始值:number string boolean null undefined symbol bigint
对象数据转换规则:
- 首先检测对象
Symbol.toPrimitive
这个属性,获取其原始值 - 如果没有这个属性,继续调用它的
valueOf
,也是获取原始值 - 如果值不是原始值,则继续调用
toString
转换字符串 - 如果需要转换数字,再把字符串基于 Number 转换为数字
1 | let obj = { |
- 了解数据转换规则后,来看一道题
1 | var a = ? |
第一类方法:隐式进行数据类型转换
修改
Symbol.toPrimitive
、valueOf
、toString
任意一个即可
1 | // 通过 ++i 改值 |
第二类方法:ES6 数据劫持
用
defineProperty
定义- 第一个参数是对象
- 第二个参数是属性名
- 第三个参数是特征值
1 | var i = 0; |
其他类型转换为数字
Number
一般用于隐式转换【数学运算、isNaN、==比较…】
- 字符串:
- 如果是空字符穿,转换结果 0
- 如果说字符串中包含非有效数字,转换结果就是 NaN
- 布尔类型
- true:转换为1
- false:转换为0
- null:转换为0
- undefined:NaN
- Symbol:报错
- BigInt :正常转换
- 对象:遵循对象数据转换规则
1 | Number("123px") // NaN |
parseInt
parseInt([val], [radix])
- [val] 必须是一个字符串,如果不是,也要默认转换为字符串
- [radix] 不设置(写零):按十进制处理,如果字符串以
0x
开头,默认是16进制
从左往右查找 [val] 中,找到所有符合 [radix] 进制的内容,直到遇到不符合的停止查找(不论后面是否还有符合的)
1 | parseInt('12px') // 12 |
- radix 2-36 之间
1 | let arr = [27.2, 0, "0013", "14px", 123]; |
其他类型转换为字符串
toString()
null、undefined 没有toString()
这个方法,用了会报错,可以使用String()
需要排除
Object.prototype.toString
检测数据类型字符串/模板字符串拼接(
+
除了数学运算还有字符串拼接)
+ 字符串拼接
情况1:+
左右两边有一边出现字符串或部分对象,则按照字符串拼接处理
- 特殊:
{} + 10 -> 10
{} 看做代码块(ES6块级上下文)
注意:不是所有对象都是字符串拼接
- 先去调取对象的
Symbol.toPrimitive
属性值,如果没有这个属性 - 再去调取对象的
valueOf
获取原始值,如果不是原始值 - 再去调用对象的
toString
转换为字符串(如果是想转换为数字,则还会调用 Number 处理)
1 | 10 + "10" // "1010" |
情况2:只有一边有 +
+
只有一边或++x
或x++
,都是数学运算10+(++x)
先把x累加1,然后和10运算10+(x++)
先把x的值和10运算,然后x累加1注意:
x++
只会进行数学运算,x+=1
和x=x+1
不仅会进行数学运算还可能进行字符串拼接
1 | +"10" // 10 |
- 了解数据转换规则和字符串拼接后,来看一道题
1 | let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false; |
其他类型转换为布尔
![值] 转换为布尔并取反
!![值] 转换为布尔
除了以下几种结果都是false,剩余的都是true
- NaN
- 0
- “”
- null
- undefined