JavaScript에서 배열을 변경하면 배열 복사본에 영향을 미치는 이유는 무엇입니까?
다음 JavaScript를 작성했습니다.
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray.splice(0, 1);
alert(myArray); // alerts ['b','c']
alert(copyOfMyArray); // alerts ['b','c']
var myNumber = 5;
var copyOfMyNumber = myNumber;
copyOfMyNumber = copyOfMyNumber - 1;
alert(myNumber); // alerts 5
alert(copyOfMyNumber); // alerts 4
이 코드는 변수를 선언하고 myArray
배열 값으로 설정합니다. 그런 다음 두 번째 변수를 선언 copyOfMyArray
하고로 설정합니다 myArray
. 에서 작업을 수행 한 copyOfMyArray
다음 myArray
및 모두에 경고를 보냅니다 copyOfMyArray
. 어쨌든에서 작업을 수행하면 copyOfMyArray
에서 동일한 작업이 수행되는 것처럼 보입니다 myArray
.
그런 다음 코드는 숫자 값으로 동일한 작업을 수행합니다. 변수를 선언하고 myNumber
이를 숫자 값으로 설정합니다. 그런 다음 두 번째 변수를 선언 copyOfMyNumber
하고로 설정합니다 myNumber
. 에서 작업을 수행 한 copyOfMyNumber
다음 myNumber
및 모두에 경고를 보냅니다 copyOfMyNumber
. 여기에서 예상되는 동작을 얻습니다 . myNumber
및에 대한 다른 값입니다 copyOfMyNumber
.
배열을 변경하면 배열 복사본의 값이 변경되는 것처럼 보이는 JavaScript에서 배열과 숫자의 차이점은 무엇입니까? 숫자를 변경해도 숫자 복사본의 값이 변경되지는 않습니다.
어떤 이유로 배열은 참조로 참조되고 숫자는 값으로 참조되지만 그 이유는 무엇입니까? 다른 개체에서 예상되는 동작을 어떻게 알 수 있습니까?
JavaScript의 배열도 객체 이며 변수 는 객체 자체가 아닌 객체에 대한 참조 만 보유 합니다. 따라서 두 변수 모두 동일한 객체에 대한 참조를 갖습니다 .
숫자 예제와의 비교가 정확하지 않습니다. 에 새 값을 할당합니다 copyOfMyNumber
. 새 값을 할당 copyOfMyArray
해도 변경되지 않습니다 myArray
.
slice
[docs]를 사용하여 배열의 복사본을 만들 수 있습니다 .
var copyOfMyArray = myArray.slice(0);
그러나 이것은 얕은 복사본 만 반환합니다 . 즉, 배열 내부의 개체는 복제되지 않습니다.
유일하게 가능한 대답과 정답은 실제로 어레이를 복사하지 않는다는 것입니다. 당신이 쓸 때
var copyOfArray = array;
동일한 배열에 대한 참조 를 다른 변수에 할당하고 있습니다. 즉, 둘 다 같은 물체를 가리키고 있습니다.
그래서 여기있는 모든 사람들 이 왜 이런 일이 일어나는지 설명하는 훌륭한 일을했습니다. 저는 그저 줄을 끊고 제가 어떻게이 문제를 해결할 수 있었 는지 알려 드리고 싶었습니다 . 아주 쉽게 :
thingArray = ['first_thing', 'second_thing', 'third_thing']
function removeFirstThingAndPreserveArray(){
var copyOfThingArray = [...thingArray]
copyOfThingArray.shift();
return copyOfThingArray;
}
이것은 ... spread 구문을 사용하고 있습니다.
편집 : 이것의 이유 와 질문에 대답하려면 :
배열을 변경하면 배열 복사본의 값이 변경되는 것처럼 보이는 JavaScript에서 배열과 숫자의 차이점은 무엇입니까? 숫자를 변경해도 숫자 복사본의 값이 변경되지는 않습니다.
대답은 JavaScript에서 배열과 객체는 변경 가능 하고 문자열과 숫자 및 기타 기본 요소는 변경할 수 없다는 것입니다 . 다음과 같은 과제를 수행 할 때 :
var myArray = ['a', 'b', 'c']; var copyOfMyArray = myArray;
copyOfMyArray는 실제 사본이 아니라 실제로 myArray에 대한 참조 일뿐입니다.
이 기사를 추천합니다. 변경 불가능하고 변경 가능한 데이터 구조는 무엇입니까? , 주제를 더 깊이 파헤칩니다.
객체 또는 배열의 깊은 복제를 만드는 가장 쉬운 방법입니다.
const objectThatIWantToClone = { foo: 'bar'};
const clone = JSON.parse(JSON.stringify(objectThatIWantToClone));
이를 문자열 화함으로써 우리는 불변의 복사본을 만들고 다시 JSON으로 변환 할 수 있습니다.
https://codepen.io/Buts/pen/zWdVyv
개체 복제-
A는 loop / array.push
비슷한 결과로 생산 array.slice(0)
또는 array.clone()
. 값은 모두 참조로 전달되지만 대부분의 원시 데이터 유형은 변경 불가능 하므로 후속 작업은 원하는 결과 인 '복제'를 생성합니다. 물론 원래 참조를 수정할 수있는 객체 및 배열에는 해당되지 않습니다 (변경 가능한 유형 임).
다음 예를 살펴보십시오.
const originalArray = [1, 'a', false, {foor: 'bar'}]
const newArray = [];
originalArray.forEach((v, i) => {
newArray.push(originalArray[i]);
});
newArray[0] = newArray[0] + 1;
newArray[1] = 'b';
newArray[2] = true;
newArray[3] = Object.assign(newArray[3], {bar: 'foo'});
newArray 인덱스에서 실행되는 작업은 모두 원하는 결과를 생성합니다. 단, 최종 (객체)은 참조로 복사되기 때문에 originalArray [3]도 변경됩니다.
https://jsfiddle.net/7ajz2m6w/
참고 array.slice(0)
and array.clone()
이 같은 제한을 앓고 있습니다.
이를 해결하는 한 가지 방법은 푸시 시퀀스 중에 오브젝트를 효과적으로 복제하는 것입니다.
originalArray.forEach((v, i) => {
const val = (typeof v === 'object') ? Object.assign({}, v) : v;
newArray.push(val);
});
https://jsfiddle.net/e5hmnjp0/
건배
JS에서 연산자 "="는 포인터를 배열의 메모리 영역에 복사합니다. 배열을 다른 배열로 복사하려면 Clone 기능을 사용해야합니다.
정수의 경우 원시 유형이기 때문에 다릅니다.
에스.
원시 데이터 유형 (문자열 및 숫자 IIRC)을 제외한 모든 것은 참조로 복사됩니다.
arrayCopy에 원래 배열의 필터를 만듭니다. 따라서 새 어레이에 대한 변경 사항은 원래 어레이에 영향을주지 않습니다.
var myArray = ['a', 'b', 'c'];
var arrayCopy = myArray.filter(function(f){return f;})
arrayCopy.splice(0, 1);
alert(myArray); // alerts ['a','b','c']
alert(arrayCopy); // alerts ['b','c']
도움이 되었기를 바랍니다.
사본이 없습니다.
동일한 배열을 보유하는 여러 변수가 있습니다.
마찬가지로 동일한 숫자를 가진 여러 변수가 있습니다.
When you write copyOfMyNumber = ...
, you're putting a new number into the variable.
That's like writing copyOfMyArray = ...
.
When you write copyOfMyArray.splice
, you're modifying the original array.
That isn't possible with numbers because numbers are immutable and cannot be modified,
You can add some error handling depending on your cases and use something similar to the following function to solve the issue. Please comment for any bugs / issues / efficiency ideas.
function CopyAnArray (ari1) {
var mxx4 = [];
for (var i=0;i<ari1.length;i++) {
var nads2 = [];
for (var j=0;j<ari1[0].length;j++) {
nads2.push(ari1[i][j]);
}
mxx4.push(nads2);
}
return mxx4;
}
Another approach for copying array into temporary variable can be typecasting/changing your array into string and then retrieving it.
E.g.
var a = [1,2,3];
typeof(a) (this will give "object")
var b = JSON.stringify(a);
typeof(b) (this will give "string");
b = JSON.parse(b);
typeOf(b) (this will give "object")
and now chnage in value of b will not be reflected on a
An array, or an object in javascript always holds the same reference unless you clone or copy. Here is an exmaple:
http://plnkr.co/edit/Bqvsiddke27w9nLwYhcl?p=preview
// for showing that objects in javascript shares the same reference
var obj = {
"name": "a"
}
var arr = [];
//we push the same object
arr.push(obj);
arr.push(obj);
//if we change the value for one object
arr[0].name = "b";
//the other object also changes
alert(arr[1].name);
For object clone, we can use .clone() in jquery and angular.copy(), these functions will create new object with other reference. If you know more functions to do that, please tell me, thanks!
Your answer is here
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray.slice();
Basically, the slice() operation clones the array and returns a shallow copy.
copyOfMyArray.splice(0, 1);
alert(myArray); // alerts ['a', 'b', 'c']
alert(copyOfMyArray); // alerts ['b','c']
A clear Documentation can be found in the following link: Array.prototype.slice()
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = JSON.parse(JSON.stringify(myArray));
copyOfMyArray.splice(0,1);
console.log('orginal Array',myArray)
console.log('After Splic of copyOfMyArray',copyOfMyArray);
//If not using the JSON.parse(JSON.stringify (array)) at the time of assign the array change of the one array will affect another because of the reference.
The issue with shallow copy is that all the objects aren't cloned, instead it get reference.So array.slice(0) will work fine only with literal array, but it will not do shallow copy with object array. In that case one way is..
var firstArray = [{name: 'foo', id: 121}, {name: 'zoo', id: 321}];
var clonedArray = firstArray.map((_arrayElement) => Object.assign({}, _arrayElement));
console.log(clonedArray);
// [{name: 'foo', id: 121}, {name: 'zoo', id: 321}] // shallow copy
'Program Tip' 카테고리의 다른 글
Google 크롬 확장 프로그램-툴바 아이콘을 클릭하면 새 탭 열기 (0) | 2020.11.07 |
---|---|
jQuery를 사용하여 비디오 src를 어떻게 변경합니까? (0) | 2020.11.07 |
간단한 문자열 배열에 바인딩 (0) | 2020.11.07 |
jQuery의 부모에서 모든 자식 (모든 수준)을 선택하는 방법은 무엇입니까? (0) | 2020.11.07 |
bash가 파일에서로드 된 문자열에서 변수를 확장하도록 강제 (0) | 2020.11.07 |