JavaScript中的可变(Mutable)、不可变(Immutable)和变量的赋值介绍

JavaScript中的可变(Mutable)、不可变(Immutable)和变量的赋值介绍

一、可变(Mutable)与不可变(Immutable)

在JavaScript中,可变(Mutable)、不可变(Immutable)主要是指数据类型的特性。

【可变指即使没有创建一个全新的值,也可以更改它。在 JavaScript 中,对象和数组默认都是可变的,但是原始值是不可变的——一旦创建原始值,它就不能被更改,尽管持有它的变量可能会再次重新分配到其它值。https://developer.mozilla.org/zh-CN/docs/Glossary/Mutable

除了 Object 以外,所有类型都定义了表示在语言最低层面的不可变值。我们将这些值称为原始值。在JavaScript中,对象是唯一可变的值。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures

在 JavaScript 中,原始数据类型(primitive data type)原始数值(primitive value)是一种既非对象也无方法或属性的数据。】

在JavaScript中,数据类型是否可变主要取决于它是原始(Primitive)类型还是对象类型(Object)。在JavaScript中,大多数对象都是可变的,少许例外,内置对象Map和Set是可变的,但内置对象Math对象就是不可变的;正则表达式是对象类型,但它们的模式和标志在创建后是不可变的。

可变(Mutable):如果一个数据类型是可变的,那么它的值可以在创建后被改变。在JavaScript中,对象、数组和函数是可变的。

引用数据类型的值是可变的,意味着你可以修改它们的属性或元素。这是因为引用数据类型的值实际上是存储在内存中的对象,变量只是指向这个对象的引用。当你修改引用数据类型的值时,实际上是在修改对象本身,而不是修改变量的值。

例如:

let obj = { name: 'John' };
obj.name = 'Jane'; // 可以改变对象的属性值
console.log(obj); // 输出 {name: 'Jane'},对象已经被改变

let arr = [1, 2, 3];
arr[0] = 4; // 可以改变数组的第一个元素
console.log(arr); // 输出 [4, 2, 3],数组已经被改变

函数也是JavaScript中的可变类型。你可以在运行时添加、修改或删除函数的属性。下面是一个例子:
// 定义一个函数
function greet() {
    console.log("Hello, world!");
}
// 给函数添加一个属性
greet.language = "English";
// 输出为函数新添加的属性
console.log(greet.language);  // 输出 "English"

在JavaScript中,大多数对象确实是可变的。这意味着我们可以更改对象的属性或者添加新的属性。比如,我们可以创建一个空的对象,然后给它添加属性:

let obj = {};

obj.name = "John";

然后我们还可以修改这个属性:

obj.name = "Jane";

但是,有一些对象是不可变的。比如,你提到的Math对象和正则表达式对象。Math对象是一个内置对象,提供了一些数学常数和函数。我们不能更改这个对象。正则表达式对象在创建后也是不可变的。

另外,虽然Map和Set是可变的,但是它们的键是不可变的。即我们可以添加或删除键值对,但是不能更改已经存在的键。

不可变(Immutable):如果一个数据类型是不可变的,那么它的值在创建后就不能被改变。在JavaScript中,原始数据类型(如字符串、数字、布尔值、null、undefined和Symbol)是不可变的。

原始(基本)数据类型的值是不可变的,意味着你不能直接修改它们的值。当你尝试修改原始数据类型的变量值时,实际上是创建了一个新的值,并将其赋给变量。

需要注意,JavaScript中的字符串是不可变的,例如:

let str = 'Hello';

str[0] = 'W'; // 这不会改变str的值,str仍然是'Hello'

console.log(str); // 输出 'hello',原字符串并未改变

在这个例子中,尽管我们试图改变字符串的第一个字符,但是字符串的值并没有改变。这是因为在JavaScript中,字符串是不可变的。

二、JavaScript变量的赋值

JavaScript变量的赋值是按值传递的,对于原始(Primitive:原始,基本)数据类型是复制值,对于引用数据类型(对象类型)是复制引用。

当执行到变量赋值语句时,JavaScript引擎会将赋值操作的右侧表达式计算出一个值,并将该值赋给变量。赋值操作可以使用赋值运算符 =,也可以使用其他赋值运算符(如 +=、-= 等)。
变量赋值是一个按值传递的过程。对于基本数据类型(如数字、字符串、布尔值等),赋操作会将值复制给变量。而对于引用数据类型(如对象、数组等),赋值操作会将引用(指向对象的内存地址)复制给变量,而不是复制对象本身。这意味着,当你修改一个引用类型的变量时,实际上是修改了引用所指向的对象。
 

原始类型的变量值是存放在栈内存(Stack)中

let a,b;
a = "xyz";
b = a;
console.log(a);   // xyz
console.log(b);   // xyz
a = "Hi";       // 改变 a 的值,并不影响 b 的值
console.log(a);   // Hi
console.log(b);   // xyz

解析图示如下:

红色❌,表示"xyz"这个值不再被变量a引用,若一个值不再被任何变量引用,可以被垃圾回收器标记为可回收的,具体的垃圾回收时间是由JavaScript引擎决定的。

引用数据类型的值是保存在堆内存(Heap)中

let a,b; 
a = {name:"percy"};
b = a;
a.name = "Jack";
console.log(b.name);    // Jack
b.age = 22;
console.log(a.age);     // 22

解析图示如下:

附录
JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较 https://blog.youkuaiyun.com/cnds123/article/details/134219139

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习&实践爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值