Array.find(), for of Array problem

zenibako.lee
4 min readMar 9, 2021

--

오늘 발견하였던 나의 실수 사항에 대해 기록을 남겨본다.
개인적으로 javascript의 for문을 사용할 때,
for…of 문을 굉장히 선호하는 편이었다.

그 이유는 코드의 가독성이 매우 높아진다고 느꼈기 때문이다.

동일한 Object의 Array를 순회하는 for문을 두가지 방식으로 사용해 보았다.
예시로 든 반복문의 대상이 되는 Array는 개별 원소의 depth가 매우 얕아
차이가 잘 느껴지지 않을 수도 있지만,
여러가지 정보를 담고 깊은 depth를 갖는 경우
오브젝트를 명시적으로 선언하여
반복문 내부에서 바로 변수명으로 사용할 수 있어서 for..of문을 선호했다.

그러나 이 for…of 문에 대한 맹신이 에러를 발생시켰다.

문제가 되는 상황이다.

해당 코드의 10번라인의 index1에 해당하는 object의 num은 무엇이었을까?

나는 당연히 100으로 변경된 값일 것이라고 생각했다.

왜냐하면, Array와 Object는 메모리의 주소가 변수에 저장이 되고

for 문에서 let으로 선언한 numObject 는 arrayOfObject의 개별 아이템들의
메모리주소를 받아왔다고 생각했다.

따라서 numObject에 새로운 Object를 할당하면
원본 Array가 참조하고 있던 메모리 주소를 변경하는 동작이 발생하여
arrayOfObject의 동일 인덱스의 value에 할당되었던
메모리주소가 새로운 메모리 주소로 변경될 것이라 생각했기 때문이다.

https://medium.com/@ethannam/javascripts-memory-model-7c972cd2c239

javascript의 변수는 크게
원시타입(primitive)과 참조타입(non-primitives) 으로 나눌 수 있다.

원시타입의 경우
위 사진의 마지막 myArray라는 변수명을 제외한 변수들의 value들이 저장되는 방식처럼
String이나 Number타입의 value가 콜스택에 저장되고
콜스택에 value가 저장된 address를 변수에 저장한다.

Array의 prototype을 물고 올라가면
Array 는 Object를 프로토타입으로 갖는다.
따라서 Object 클래스의 instance의 value는 heap 메모리에 저장되고,
heap메모리의 address를 콜스택 value로 저장,
그리고 해당 콜스택의 address를 변수에 저장한다.

문제의 코드로 돌아가보자.

for …of 문에서 매 순회마다

numObject라는 변수에 할당되는 것은
arrayOfObject의 원소의 실제 값이 있는 heap memory의
value에 저장되어 있는
또다른 Array 내부 Object의 call Stack address이다.

따라서, numObject에 다른 값을 선언해 봐야,
numObject에 할당된 메모리 주소값이 변경될 뿐이었다.

Array.find() 역시 동일한 방식으로 사용할 경우 문제가 발생한다.

Array 내부의 아이템을 mutate하기 위해서는,

기존의 for문 혹은 Array.findIndex()를사용하여,

인덱스를 찾고, mutate하려는 Array의 인덱스를 지정하여 수정하는는 방법이 옳다.

혹은 Functional 한 방식으로,
Array.map()과 같은 방식으로 변경된 새로운 Array instance를 return하여,
새로운 Array가 변경을 반영하도록 하는것이 좋아보인다.

--

--

zenibako.lee
zenibako.lee

Written by zenibako.lee

backend engineer, JS, Node, AWS

No responses yet