336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

아래 코드를 보자. 

let total = 0;
let item = [
    {name : '새우깡', price: 100},
    {name : '고래밥', price: 200},
    {name : '꼬북칩', price: 300},
    {name : '하이트맥주', price: 400},
];

const addItem = (name, price) => {
    item.push({
        name : name,
        price : price
    });
}


addItem('땅콩', 400);

이전 글과 같은 이유로, addItem 은 액션이다. 

 - 암묵적 입/출력이 존재

 - 실행 시점 및 횟수에 영향을 받음

 

위를 "계산" 으로 바꾸려면 

 - 암묵적 입/출력을 명시적 입/출력으로 변경 

 - 실행 시점 및 횟수에 영향이 없도록 변경 

 

이전 글 처럼, 먼저 암묵적 입/출력을 명시적 입/출력으로 바꿔보면

let total = 0;
let item = [
    {name : '새우깡', price: 100},
    {name : '고래밥', price: 200},
    {name : '꼬북칩', price: 300},
    {name : '하이트맥주', price: 400},
];

const addItemCalc = (items, name, price) => {
    items.push({
        name : name,
        price : price
    });
    
    return items;
}

item = addItemCalc(item, '땅콩', 400);

console.log(item);

 명시적 입/출력으로 변경하였다. 암묵적 입/출력 문제가 사라진 듯 하지만, 암묵적 출력 문제는 존재한다.  

문제는 items 파라미터는 '참조' 로 전달이 되기 때문에, 함수 내 변경사항이 원본에 적용이 된다.

// items 파라미터는 참조로 전달된다, 즉 items 에 뭔가를 추가한다면,
// 파라미터로 전달된 원본도 같이 변경된다. 
// return 값이 존재하지만, 암묵적 출력은 여전히 남아있다.
const addItemCalc = (items, name, price) => {
    items.push({
        name : name,
        price : price
    });
    
    return items;
}

함수의 실행이, 함수 외부의 변수와 '완벽하게' 차단된다면 부수효과(side effect) 억제효과도 있고, 그만큼 테스트와 유지보수 용이성도 증가할 것이다. 

해결방법 중 하나는 '복사본 리턴' 이다. 

 

const addItemCalc = (items, name, price) => {
    let result = items.slice(); //여기서 복사본을 만든다.
    result.push({
        name : name,
        price : price
    });
    
    return result;
}

복사본을 만든 후, 배열을 변경 하고, 그 후에 변경된 배열을 리턴한다. 

 

위와같이 구현하면, 큰 자료구조라 하더라도, 조작 시, 로직과 데이터를 완벽하게 분리 해낼 수 있다. 

 

결론

동작을 계산으로 바꾸는 첫번째 방법 - 변경시에는 복사본을 사용하고 변경된 데이터를 리턴하라.

 

추가

- 객체 복사 시 성능 이슈가 있을 것이라 생각되는 분이 많을 듯 하다. 자바스크립트에서는 복사 시 기본적으로 얕은복사를 사용하고, 깊은 복사는 loadsh 등의 라이브러리를 사용하여 처리한다. 성능상의 이슈는 그리 크지 않은것으로 보이며, 필요할 경우에만 깊은 복사를 사용하면, 발생할 수 있는 성능상의 이슈를 줄일 수 있을 것이다. 

  참고 : https://jess2.xyz/JavaScript/copy/

블로그 이미지

캡틴토마스

그저 걷고 있는거지...

,