本文已参与「新人创作礼」活动,一起开启掘金创作之路
本人在学习JavaScript的时候当再次回顾知识点的时候还是会把==和===的用法特点弄混淆 但是去掘金社区上面搜寻不到自己满意的知识解答 故分享出个人的理解给各位小伙伴们 希望给和我有相同疑惑的小伙伴们提供帮助 本文章主要梳理了值类型和引用类型分别在使用==和===判断时的不同之处 先通过引出值类型和引用类型再来说说 == 和 ===比较时的区别
首先我们区分一下何为值类型,引用类型
常见值类型
const s = 'abc'//字符串类型
const n = 100//数字类型
const b = true//布尔类型
const s = Symbol('s')//symbol类型
常见引用类型
const obj = {x:100}//对象
const arr = ['a', 'b', 'c']//数组
const n = null//特殊引用类型 指针指向空地址
function fn(){}
在这里说一下函数类型不一定是引用类型 也可以单独划分为一类 但是具有引用类型的特点 (const为es新增不知道的小伙伴可以去B站上面搜尚硅谷es6课程)
堆栈模型图
栈模型
值类型的数据都是通过栈类型来存储的即 key(变量名字)-value(值)的形式
即a b被存储到栈类型中的时候 变量直接指向的是对应的值
堆栈类型
引用类型的数据是通过堆栈类型一起来存储的
栈是从上往下存 堆是从下往上存
比如给a赋值一个对象的时候 const a = {age:1}
a的值{age:1} 是被先存储到堆里面的 由一个新开辟的内存地址key(内存地址)-value({age:1})与其对应 而后在栈中a对应的是内存地址 故引用类型a 其实存储的并不是对应的值 而是一个地址 这个地址再去指向对应的值
值类型和引用类型的特点?
首先我们来看一下代码
const a = 100
const b = a
b = 200
console.log(a,b)//100 200
那么请问 b改变了 a会改变吗?为什么? 希望小伙伴们先思考再往下面看 很明显a b是两个值类型数据即number类型 它们的存储形式是上面的栈模型 即a,b指向各自的值 它们互相的改变是互相不影响的
我们再来看看代码
const obj1 = {age:20}
const obj2 = obj1
obj2.age = 21
console.log(obj1.age,obj2.age)//21 21
请问obj1.age 改变了会影响obj2.age吗?为什么吗?还是先思考一下再看下面 const obj2 = obj1 把obj1的值赋给了obj2是属于浅拷贝 即obj2拿到拷贝后的值没有在内存空间新开辟一个地址去存放拷贝的值 而是和obj1共同使用一个地址 再通过这个地址去改变对应的值 故其中一个改变了的话 另外一个再通过内存地址去找对应的值的话 这个值肯定是已经改变了的
请问下面两个引用类型的改变互相影响吗?
const obj3 = {age:21}
const obj4 = {age:21}
obj4.age = 22
console.log(obj3.age,obj4.age)
即使是没了解过的小伙伴们可能都知道吧 但是你能结合堆栈模型说说吗? 原因也很简单 这里其实 两个引用类型的数据在声明的时候其实就开辟了两个不同的内存空间去存放值 故存放的地址不同那么改变之后它们肯定也是互相不影响的
==和===
我们先看看它们在值类型比较时的区别
首先看看代码 回答一下问题
const a = 10
const b = 10
const c = 10
const d = '10'
console.log(a==b,c==d,a===b,c===d)
你能回答出控制台输出的是什么吗? 答案是true true true false
- a==b 结合值类型的栈模型 它们的key value一致 故相等
- c==d 结合值类型的栈模型 它们的value不一致为什么还会相等? 所以就引出了==的特点 在值类型在进行比较的时候它会先把类型转换成一致然后再去进行比较 这里的字符类型'10' 被转换了成了数字类型10 故再去比较的时候就相同了
- a===b 原因和a==b一样
- c===d 之所以不同是因为 ===在进行比较的时候不会进行类型转换 所以就不同了 它要求数据和数据类型都一致
我们再看看它们在引用类型比较时的区别
还是先看看代码 回答一下问题
const obj1 = {age:20}
const obj2 = {age:20}
const obj3 = obj1
console.log(obj1 == obj2 ,obj1 == obj3,obj2 == obj3)
console.log(obj1 === obj2 ,obj2 === obj3,obj1 === obj3)
猜猜输出?
- obj1 == obj2 false 之所以为false是因为它们都是新定义的对象 内存地址不一样 上面已经讲到了
- obj1 == obj3 true const obj3 = obj这一步是属于浅拷贝的浅拷贝上面有说到 即它们的内存空间地址一样指向的值也一样 故它们也是相等的
- obj2 == obj3 false obj3和obj1相等 obj1和obj2不相等 那么obj2和obj3就是不相等的
**故== 和 === 在同一引用类型的数据里面进行比较的时候 是要进行地址比较的 而地址比较又会牵扯到深浅拷贝 **