JavaScript 中的可变和不可变

原文:Mutable and immutable in JavaScript
https://blog.devgenius.io/mutable-and-immutable-in-javascript-78a3cbc6187c

根据 Mozilla 的定义-

可变(Mutable)是一种可以更改的变量。 在 JavaScript 中,只有对象和数组是可变的,原始值不可变。

可变对象是在创建后可以修改其状态的对象。

不可变对象一旦创建,其状态无法更改。

让我们分解以上定义

JavaScript 中有两种数据类型——原始类型(值类型)和非原始类型(引用类型)。

在这里插入图片描述

值类型

值类型存储在我们内存的中。 栈只是具有“LIFO”(后进先出)数据结构的数据堆栈。 它没有太多空间(与其他数据结构相比),但由于它的工作方式,它的访问速度非常快。

当在内存中存储一个值类型时,它会将一个元素添加到栈顶部,其中包含新创建的变量的值。 当创建一个新变量并将第一个变量分配给新变量时,它会在栈顶添加一个新元素,其中包含新变量的值(即第一个被创建的变量的值)。

通过创建

var name = "Maya";
var newName = name;

第一个变量 — name 与变量的值一起进栈。 然后,newName 与变量的值一起进入栈中的新内存位置。
在这里插入图片描述

引用类型

引用类型存储在上。 堆与栈无关,它没有存储数据的顺序。你可以将其视为随机存储数据,其中每个数据都有自己的地址。 堆的访问速度较慢,但空间更大,因为它处理更复杂的变量。

在内存中存储引用类型时,会在顶添加一个新元素,其值是一个指向已存储在上的对象地址的指针/引用。

通过创建

var Person = {name: "Maya", age: "29"}
var newPerson = Person;

一个新元素进栈,其值即一个指针/引用指向已存储在堆上的 Person 对象。
在这里插入图片描述

当创建一个 newPerson 对象并将前一个Person 对象赋给它时,它会在顶添加一个新元素,该元素的值是指向已存储在上的Person 对象的指针/引用
在这里插入图片描述

让我们看一些代码

让我们创建一个以字符串为值的变量。 然后,我们创建一个新变量并将第一个变量分配给它。 然后,我们将更改第一个变量的值。 我们将在创建每个变量后打印它。

var name = 'Maya';
console.log(name);
var newName = name;
console.log(newName);
name = 'Joe';
console.log(newName);

毫不奇怪,我们将在控制台中看到以下输出。

在这里插入图片描述

现在,让我们创建一个对象变量。 然后,我们将创建一个新的对象变量并将第一个对象分配给它。 然后,我们将更改第一个对象的数据。 同样,我们将在创建每个变量后打印它。

var person = {name:'Maya', age:29};
console.log(person);
var newPerson = person;
console.log(newPerson);
person.name = 'Joe';
console.log(newPerson);

这一次,我们将在控制台中看到
在这里插入图片描述

可变和不可变

你是否看到更改值类型 name 不会影响 newName,但更改 Person 对象时会影响 newPerson

发生这种情况是因为数据的存储方式。

每次创建值类型时,都会有一个新元素进入栈顶并存储该变量的数据。 另一方面,当创建一个引用类型时,一个新元素进入栈顶,但这一次,它存储的是指向存储在堆中的对象的地址位置的引用/指针。 然后,当我们将创建的对象分配给一个新的对象变量时,一个新元素进入栈顶,但是具有指向第一个对象的相同引用/指针。

因此,当更改已创建对象的数据时,指向堆上相同地址位置的所有其他对象也被更改。

考虑到这一点,我们可以说值类型是不可变的,而引用类型是可变的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值