Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/451.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 重新分配、变异、引用类型和值类型_Javascript_Variables_Reference_Immutability_Key Value - Fatal编程技术网

Javascript 重新分配、变异、引用类型和值类型

Javascript 重新分配、变异、引用类型和值类型,javascript,variables,reference,immutability,key-value,Javascript,Variables,Reference,Immutability,Key Value,您如何恰当地解释这两个例子的不同之处 // Reassignment let a = 1; let b = a; a = 2; console.log(b); // → 1 // Mutation let myArray = [1, 2, 3]; let ourArray = myArray; ourArray[2] = 10; console.log(myArray); // → [1, 2, 10] 关于为什么变量标签在这两种类型之间的行为不同,许多参考资料声称这是因为引用类型和值类型之

您如何恰当地解释这两个例子的不同之处

// Reassignment
let a = 1;
let b = a;
a = 2;
console.log(b); // → 1

// Mutation
let myArray = [1, 2, 3];
let ourArray = myArray;
ourArray[2] = 10;
console.log(myArray); // → [1, 2, 10]
关于为什么变量标签在这两种类型之间的行为不同,许多参考资料声称这是因为引用类型和值类型之间的差异。但是,这不是只适用于值本身之间的差异吗

当明确讨论变量标签时(即,为什么第一个示例中的标签不跟踪值的更改,而第二个示例中的标签跟踪值的更改),真正的区别不是与变异与重新分配有关吗

毕竟,我们可以很容易地重新分配myArray或ourArray,它们都不会有任何持续的链接。而且,如果基本值在JavaScript中理论上是可变的,那么第一个示例的行为与第二个示例相同

后续问题 我也读过关于原语值在内存中是否只存在一次的冲突信息。例如,如果数字1在内存中只存在一次,那么将变量标签可视化为名称标签是合适的,每个引用数字1的名称标签都“固定”在同一个数字1上,对吗

同样,如果数字1能够变异,那么每个名称标签都会跟踪数字1的相同变化。但由于其中一个是不可变的,所以名称标签可以继续引用同一个数字,也可以去掉并粘贴到不同的值(重新分配)


我的思路正确吗?

在你的问题中,你将实现细节(“内存中存在一次”)与评估策略(“引用类型和值类型”)和特定表达式(“变异vs.重新分配”)混为一谈。各种浏览器的实现细节各不相同,将来可能会发生变化

Javascript中有两种评估策略:

let s = "abc";
let t = s;

s[0] = "x";
s; // "xbc";
t; // "abc";
  • 按值复制(调用函数时按值传递)
  • 按引用复制(调用函数时按引用传递)
值类型

值类型始终按值复制。假定字符串在Javascript中是可变的:

let s = "abc";
let t = s;

s[0] = "x";
s; // "xbc";
t; // "abc";
基于值类型的变量(或标识符或名称绑定)直接包含其值。如果这样一个可变字符串发生变异,那么只有相应标识符的值会受到影响

与字符串不同,数字是原子的。对于原子原语,突变和重新分配没有实际区别:

let n = 0;
n = 1, n++, n = n + 1; // all reassignments
参考类型

持有引用类型的变量仅包含对该类型的引用,该类型在Javascript中是一个复杂的值(对象)。如果两个变量引用同一对象,则每个变量都保存该引用的副本,而不是直接别名。因此,如果两个变量中的一个被重新分配,这不会影响另一个

引用类型具有标识,即它们的标识不再与值绑定:

let xs = [1];
xs === [1]; // false
当明确地谈论变量标签时,真正的区别不是与变异和重新分配有关吗

当然。我想你的意思是一个人变异对象并分配变量。但你不能总是这样区分它们。我还可以说我指定了对象属性(在第二个示例中)或修改了“变量标记”的内存单元(在第一个示例中)。真的有区别吗

但事实上,变量(标签、内存单元、寄存器)的工作方式总是一样的,不管它是保存原语值还是引用值

我不断阅读关于原语值在内存中是否只存在一次的冲突信息

好吧,关键是这并不重要,因为原始值(根据定义)是不可变的。JS实现可以复制它们或共享引用,但脚本无法区分这种行为


在现实世界中,数字和布尔值通常是复制的,而字符串通常是(共享的)。

我认为您错过了使用低级语言(指针)的体验。5天与pascal的斗争将为你节省50天与JS的斗争时间,一切都会变得更加清晰。是的,这是一个变异与重新分配可变值与不可变值的问题。内存中一次是否只存在一个9的实例?很可能,假设它是实际值,而不是指定了其他属性的值,但这完全取决于编译器如何处理它。