admin管理员组文章数量:1400749
I would like to work with an array passed to a function while leaving the original array untouched. Here is a simple example of the problem.
function whyDoesArrChange(arr) {
var newArr = arr;
newArr.push(4);
return arr;
}
console.log(whyDoesArrChange([1,2,3]));
// OUT: [1,2,3,4]
I would like only newArr
to be changed, but the arr
(from the arguments) returns the pushed value as well (returns [1,2,3,4]
). How can I avoid this?
I would like to work with an array passed to a function while leaving the original array untouched. Here is a simple example of the problem.
function whyDoesArrChange(arr) {
var newArr = arr;
newArr.push(4);
return arr;
}
console.log(whyDoesArrChange([1,2,3]));
// OUT: [1,2,3,4]
I would like only newArr
to be changed, but the arr
(from the arguments) returns the pushed value as well (returns [1,2,3,4]
). How can I avoid this?
- The answer is going to depend upon whether the elements in the array need to be untouched as well. As Marcos Casagrande has already suggested, you can use slice to generate a subset of the original array. Doing so, will copy any objects in that array by reference. – Jon Trauntvein Commented May 1, 2017 at 22:23
4 Answers
Reset to default 7When passing an array to a function, the value of that array is a reference, you have to clone it to break the reference.
There are multiple ways to achieve this:
1 - Using .slice();
var newArr = arr.slice();
2 - Using .concat
var newArr = arr.concat([]);
3 - Using JSON.parse & JSON.stringify
var newArr = JSON.parse(JSON.stringify(arr));
You can check more ways and see how they perform in this jsperf I found.
While Marcos' answer is correct, no doubt. There are more pure Array functions that can be used (A pure function is a function that doesn't alter data outside of its' scope).
Usually, if you'd like to do multiple actions on the array, I would go with Marcos' answer and then do those changes as usual. But when that's not the case, the following information may be useful:
- Adding:
arr.concat([1]);
- Subarray (i to j):
arr.slice(i, j + 1);
- Removing (i to j):
arr.slice(0, i).concat(arr.slice(j + 1));
Also, filter
and map
are pure function that will not alter the array.
In JavaScript, when you use (=) to assign a value from a variable to another one, you're just passing the entire variable, so each time one or another changes, the other will change too.
According to your question, the best way that works for me is using the native .slice() JavaScript method to the arrays object. For your code:
function whyDoesArrChange(arr) {
var newArr = arr.slice();
newArr.push(4);
return arr;
}
Because reference types (arrays and objects) can get modified inside functions when passed as arguments, while primitive types (numbers, strings, booleans etc.) don't.
You can make a shallow copy the array with .slice()
and work on that array, or return a new array with the .concat
method.
function whyDoesArrChange(arr) {
return arr.concat(4);
}
本文标签:
版权声明:本文标题:How to manipulate a JavaScript array passed to a function without changing the original argument array? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744280757a2598639.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论