2022 铁人赛|Day5 【Javascript】const 失灵? 关于 Data types

附上为何铁人赛文章会出现在这里的说明:2022 铁人赛|Day1 报名失败,还是要开赛吧!

背景脉络

不知道大家有没有产生过这样的疑问..

const person = {    bodyHeight: 180,    favColor: 'black'};person.favColor = 'blue';console.log(person);  // print: {bodyHeight: 180, favColor: 'blue'}

。 为什么里面的值变了?
。 不是用 const 了吗?
。 说好的宣告后不可更改的特性失灵了吗?

今天学到的内容刚好替我解决的这样的疑惑,原来跟 Data types 有关!以下整理~~


主题笔记

一、Data Types 分两类

根据储存位置不同,可以分成 Primitive Types & Reference Types(或者可以说 Primitives & Objects)
Primitive Types 的值储存在 Call Stack,而 Reference Types 的值储存在 Heap

img

⬆️ 图片来自于Jonas Schmedtmann的课程讲义

二、Data Types 储存方式

img

⬆️ 图片来自于Jonas Schmedtmann的课程讲义,下面解说(打完发现好长呀!希望有表达清楚)

.
Primitive Types

宣告age = 30,JS engine 会在 Call Stack 上创造一个 age identifierage identifier 指向存着「30」的「Stack memory address」接着宣告oldAge = age,JS engine 会在 Call Stack 上创造 oldAge identifieroldAge identifier 指向与 age identifier 同一个 「Stack memory address」接着重新为 age 赋值age = 31,已存在的 age identifier 会重新指向存着「31」的「Stack memory address」所以 log 时,ageoldAge都有它们各自指向的值

.

Reference Types

宣告me = {...},JS engine 会在 Heap 创造出存着「物件值」的「Heap memory address」然后 Call Stack 上会创造 me identifierme identifier 指向存着「Heap memory address值」的「Stack memory address」而这个「Heap memory address值」会指向 Heap 中的 「Heap memory address」,进而对应到「物件值」接着宣告friend = me,Call Stack 上会创造 friend identifierfriend identifier 指向与 me identifier 同一个 「Stack memory address」,有着同样的「Heap memory address值」指向 Heap 中的 「Heap memory address」,对应到同一个「物件值」这时若对friend进行修改 ex.friend.age = 27,将会修改到 Heap 中的「物件值」所以 console.log(me.age)时,也将会是 27, 因为mefriend是指向同一个「物件值」

三、const 没有失灵!

理解两种 Data Types 的储存方式,就会发现用 const 宣告的 object(Reference Types),如果只是改变
object 中的值,它在 stack 中的指向确实没有改变(都是存着「Heap memory address值」的「Stack memory address」)!但如果我们在宣告 object 后,重新赋值新的 object,就不行啰!

const me = {  name: 'Kim',  hobby: 'jogging',};me = {}; // Uncaught TypeError: Assignment to constant variable.

四、如何複製出新 object,而不是指向同一个?

使用Object.assign

⬇️ 合併两个 object,创造新 object

const me = {  name: 'Kim',  hobby: 'jogging',};const newMe = Object.assign({}, me);console.log(newMe); // print: {name: 'Kim', hobby: 'jogging'}

⬇️ 这两个变数最终指向不同的「Heap memory address」

newMe.hobby = 'eating';console.log(newMe); // {name: 'Kim', hobby: 'eating'} (newMe的hobby改变console.log(me); // {name: 'Kim', hobby: 'jogging'}  (me的hobby没变

参考资料

The Complete JavaScript Course 2022: From Zero to Expert! Unit 99 & 100


以上是今天的分享,谢谢看完的你!


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章