==和===运算符区别
JavaScript 提供了严格(===, !==) 和类型转换(==, !=) 相等比较。严格运算符考虑变量的类型,而非严格运算符根据变量的值进行类型校正/转换。
# 严格运算符
- 当两个字符串具有相同的字符序列、相同的长度和对应位置的相同字符时,它们是严格相等的。
- 当两个数字在数值上相等时,它们是严格相等的。即具有相同的数值。这里面有两种特殊情况:
- NaN 不等于任何东西,包括 NaN。
- 正零和负零彼此相等。
- 如果两个布尔操作数都为真或都为假,则两个布尔操作数严格相等。
- 如果两个对象引用同一个对象,则它们是严格相等的。
- Null 和 Undefined 类型不等于 ===,但等于 ==。即,null===undefined --> false 但 null==undefined --> true
0 == false // true
0 === false // false
1 == "1" // true
1 === "1" // false
null == undefined // true
null === undefined // false
'0' == false // true
'0' === false // false
[]==[] or []===[] //false, refer different objects in memory
{}=={} or {}==={} //false, refer different objects in memory
2
3
4
5
6
7
8
9
10
# Object.is()
Object.is() 方法判断两个值是否为同一个值。返回一个布尔值。如果满足以下任意条件则两个值相等:
- 都是 undefined
- 都是 null
- 都是 true 或都是 false
- 都是相同长度、相同字符、按相同顺序排列的字符串
- 都是相同对象(意味着都是同一个对象的值引用)
- 都是数字且
- 都是 +0
- 都是 -0
- 都是 NaN
- 都是同一个值,非零且都不是 NaN
Object.is()
与==
不同,Object.is()
不会对两边的变量进行强制转换。
Object.is()
与 ===
也不相同,差别是它们对待有符号的零和 NaN 不同。
Object.is(NaN, NaN); // true
Object.is(+0, -0); // false
console.log(NaN === NaN); // false
console.log(+0 === -0); // true
2
3
4
5
# 非严格运算符
非严格运算符根据变量的值进行类型校正/转换。
我们先复习 JS 的类型知识:JS 中的值有两种类型:基本类型和对象类型(引用类型)。
# 基本类型
基本类型包括:Undefined、Null、Boolean(布尔值)、Number(数值)、String(字符串)、Symbol(ES6 引入的,表示独一无二的)。它们有以下特点:
- 基本类型的访问是按值访问的;
- 不能添加属性和方法;
- 基本类型的变量是存放在栈区的,包括变量标识符和变量的值(栈区不会设置太大,主要用来存基本类型)
- 基本类型的复制就是在栈内存中开辟一个新的存储区域来存储新的变量;
- 基本类型的比较是值比较的。
提示
在 JS 中,数字是用 64 为浮点数的形式存储的;而字符串是用类似 UTF-8 存储的(UCS-2,是 UTF-8 的子集),英文占 1 个字节,一般中文占 2 个字节。
# 引用类型
JS 的引用类型包含三类:
- 基本引用类型:Object(对象)、Array、RegExp、Data、Function
- 基本包装类型:String、Number、Boolean
- 单体内置对象:Global、Math
JS 的引用类型有以下特点:
- 引用类型的值是按引用访问的;
- 引用类型可以拥有属性和方法,且可以动态改变;
- 存储需要内存的栈区和堆区,其中栈区保存变量标识符和指向内存中该对象的指针;
- 引用类型的比较是引用的比较;
- 引用类型的复制将赋值引用地址。
# 类型转换规则
接下来就是关于不同类型之间比较时,类型是怎么转换的呢?
# 1. Undefined 和 Null
两者相等,但两者与其他类型不相等。
console.log(null == undefined) // true
# 2. 存在 Object 时
当对象与一个非对象比较时,需要将对象转为原始类型,通过valueOf()和toString()方法。
toString()方法用来得到对象的一段文字描述,而valueOf()方法用来得到对象的特征值。
当为数组时候,valueOf()方法会返回自身,则会继续调用toString()方法,会转成字符串并用,依次连接起来:
[] == false //true
[1] == true //true
[1,2] == '1,2' // true
2
3
4
5
当为对象时,会调用toString()方法,返回的是字符串:
console.log({} == '[object Object]') //true
# 3. Boolean
当布尔值与其他类型值比较时,布尔值会转换为数字,true转换为1,false转换为0。
console.log(true == 1) //true
console.log(true == 2) //false
console.log(false == 0) //true
console.log(false == -1) //false
2
3
4
5
# 4. String
在字符串和数字作比较时,会把字符串转化为数字,相当于先执行Number(x)操作。
console.log('' == 0) //true
console.log('123' == 123) //true
console.log('123ab' == 123) //false
2
3
参考文章: