Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.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
既然const在JavaScript中创建不可变数组是无用的(我不知道确切的原因),那么创建不可变数组的最佳方法是什么?_Javascript - Fatal编程技术网

既然const在JavaScript中创建不可变数组是无用的(我不知道确切的原因),那么创建不可变数组的最佳方法是什么?

既然const在JavaScript中创建不可变数组是无用的(我不知道确切的原因),那么创建不可变数组的最佳方法是什么?,javascript,Javascript,在我看来,这个问题与javascript无关,我只是想了解javascript核心的一些行为,我不想要库之类的东西 我试图理解为什么这段代码实际上修改了const originalArray const originalArray = [0, 2, 1, 1, 1]; var newArray = originalArray; var removed = newArray.splice(0,3); console.log(originalArray);//return [ 1, 1 ]

在我看来,这个问题与javascript无关,我只是想了解javascript核心的一些行为,我不想要库之类的东西

我试图理解为什么这段代码实际上修改了
const originalArray

const originalArray = [0, 2, 1, 1, 1];

var newArray = originalArray;

var removed = newArray.splice(0,3);

console.log(originalArray);//return [ 1, 1 ]
但与此同时,这是不可能的:

const originalArray = [];
originalArray = [1];  
那么,在没有库的情况下,如何创建一个真正不可变的数组呢?

您可以使用它

const arr=Object.freeze([1,2,3]);
控制台日志(arr);
arr[1]=7;

控制台日志(arr)
修改
newArray
也修改
originalArray
的原因是JavaScript中的变量只是对对象的引用。当您说
newArray=originalArray
时,您不是在复制数组,而是在复制引用。因此,当您说
newArray.splice(0,3)
时,您是在修改
newArray
引用的数组,而
originalArray
也引用了该数组

类似地,在JavaScript中,单词
const
指的是常量引用,而不是底层对象。也就是说,您可以在
const
变量上调用突变方法,如
.splice
,而不会出现任何问题。当您尝试使用
=
或类似方法重新分配变量时,您会遇到错误

正如其他人所注意到的,
Object.freeze(41;
将使其无法修改内部对象,从而实现“不变性”,因为您将无法修改底层对象

例如,如果您执行以下操作:

const originalArray = Object.freeze([1, 2, 3]);
let newArray = originalArray; // you can easily use `const` here, but I don't want to confuse the two concepts
newArray.splice(0, 3); // TypeError: Cannot add/remove sealed array elements

如果您想要阵列的副本,可以在不修改原始阵列的情况下进行修改,
Object.freeze
单独使用将无助于您。您需要“深度复制”数组,这可以通过各种方法完成(很容易通过谷歌搜索,因此我将对它们进行编辑,因为这个答案比预期的要长)。

const并不像您所想的那样创建常量变量,它创建了不可变的绑定。如果您先编写const arr=[],然后再编写arr={},就会得到错误。偶数对象。仅冻结顶层。例如:

const x = Object.freeze([1, 2, 3, [3, 4, 5]]);
x[3].push(20);
console.log(x)
您将得到[1,2,3,3,4,5,20]],如果您希望它完全不可变,您必须递归地冻结它,但它会影响性能。 您还可以像这样创建数组的副本并使用新的副本

const x = [1,2,3,4,5]
const y = x.slice(0, x.length)

您是否尝试过对象冻结(arr)?@jornsharpe不是一个重复的问题,我编辑了这个问题以避免混淆。我认为这不是问题主体的正确答案,问题主体是当您修改新数组时,为什么原始数组会受到影响。谢谢@Tamas,但我不理解const的这种行为。为了澄清,如果将示例第二条语句中的
let
替换为
const
,则将实现相同的行为。如果您将
let
替换为
const
并删除
对象。冻结
,则允许使用
拼接
,其行为将与原始问题中的代码相同。谢谢@River您的解释非常清楚。我认为代替Object.freeze的更好方法是
var newArray=originalArray.splice()这是深度复制浅数组的好方法。也就是说,如果元素只是数字或不可变的对象,这将起作用。但是,如果数组中有可变对象并修改单个对象,则它们仍将在原始数组中修改。为了确保您不会意外地创建对同一对象的多个引用,我建议使用lodash。谢谢@Vlaev这绝对是反对
对象的一个要点。冻结