All of My Records

[JS] for문에서 객체 배열에 추가하기(초기화, JSON, Spread Syntax 사용)

by 캐떠린

Problem

JSON 데이터를 만들던 중 유저 수만큼 for문을 돌며 객체를 배열에 담고 확인해보니 배열에는 모두 같은 값의 객체가 들어가있었다. 문제가 발생한 코드는 아래와 같다.

var user = new Object();
var arrUser = new Array();

for (var i=0; i<arrUserId.length; i++)
{
    user["UserID"] = arrUserId[i];
    user["StartDate"] = StartDate;
    user["EndDate"] = EndDate;

    arrUser.push(user);
}

 

Cause

객체의 값을 변경하면서 배열에 추가할 때, 동일한 값만 배열에 들어갔던 이유는 객체의 참조(reference) 때문!

JS에서 객체는 참조타입이므로, 동일한 객체를 여러 번 배열에 추가하면 동일한 참조가 들어가게 된다. 따라서 배열 내 모든 요소가 동일한 값으로 들어갔던 것.

 

Solution

따라서 객체를 배열에 추가하기 전에 객체를 복사하여 새로운 참조를 생성시킨 후, 배열에 추가해야 한다.

또는 객체를 배열에 담은 후, 초기화 시키고 다시 담거나..(객체 초기화 시 새로운 객체 참조 생성)

 

1. 전개 구문(Spread Syntax) 사용

: push할 때, push({...obj}); 와 같은 방식으로 사용. 아래는 수정한 코드

var user = new Object();
var arrUser = new Array();

for (var i=0; i<arrUserId.length; i++)
{
    user["UserID"] = arrUserId[i];
    user["StartDate"] = StartDate;
    user["EndDate"] = EndDate;

    arrUser.push({...user});
}

 

2. for문 내부에서 객체 초기화

for (var i=0; i<arrUserId.length; i++)
{
    var user = {};
    user["UserID"] = arrUserId[i];
    user["StartDate"] = StartDate;
    user["EndDate"] = EndDate;

    arrUser.push(user);
}

 

3. Object.assign 사용

Object.assign(target, ...sources);

  • target: 목표 객체. 출처 객체의 속성을 복사해 반영한 후 반환할 객체
  • sources: 출처 객체. 목표 객체에 반영하고자 하는 속성들을 갖고 있는 객체
  • return값 → target(목표 객체)
for (var i=0; i<arrUserId.length; i++)
{
    user["UserID"] = arrUserId[i];
    user["StartDate"] = StartDate;
    user["EndDate"] = EndDate;

    arrUser.push(Object.assign({}, user));
}

 

4. JSON 사용

: 객체를 JSON.stringify를 사용하여 JSON 문자열로 변환하고 다시 JSON.parse를 사용하여 객체로 변환하는 방법

for (var i=0; i<arrUserId.length; i++)
{
    user["UserID"] = arrUserId[i];
    user["StartDate"] = StartDate;
    user["EndDate"] = EndDate;

    arrUser.push(JSON.parse(JSON.stringify(user)));
}

 

블로그의 정보

All of My Records

캐떠린

활동하기