20일차(2)[value & reference / 실습 예제]

진하의 메모장·2025년 2월 4일
2

공부일기

목록 보기
26/66
post-thumbnail

2025 / 02 / 04

오늘은 수업 시간에 Call By Reference와 Call By Value에 대해 배웠습니다.
값에 의한 전달은 정확히 이해를 하고 있었는데 이상하게 참조에 의한 전달은 값을 변경하게 되면 두 변수가 모두 값이 변한다는 것을 까먹어서 항상 헷갈리는 것 같습니다.
이번 포스팅에서는 스프레드 오퍼레이터(Spread Operator)와 함께 값에 의한 전달과 참조에 의한 전달을 예시와 함께 다뤄보겠습니다.



💌 Call By Value

값에 의한 전달

  • 변수를 다른 변수에 할당할 때 그 값이 복사되어 전달되는 방식입니다.
  • 두 변수는 서로 독립적으로 값을 가지게 되며, 하나의 변수 값을 변경해도 다른 변수에는 영향을 미치지 않습니다.

1) 예시

  • score와 copy는 각각 80이라는 값을 가집니다.
  • score의 값을 100으로 변경하더라도 copy는 변하지 않고 여전히 80입니다.
  • score의 값이 copy에 복사되었기 때문입니다.
let score = 80;
let copy = score;

console.log(score); // 80
console.log(copy); // 80

score = 100;
copy = score;

console.log(score); // 100
console.log(copy); // 80

2) 요약

  • 원시값(숫자, 문자열, 불리언 등)을 다룰 때, 값이 복사되어 새로운 변수에 전달됩니다.
  • 한 변수의 값이 변경되어도 다른 변수의 값에는 영향을 미치지 않습니다.


💌 Call By Reference

참조에 의한 전달

  • 배열이나 객체와 같은 참조형 데이터가 변수에 할당될 때 발생합니다.
  • 참조형 데이터는 실제 값이 아닌 데이터가 저장된 위치(참조)를 변수에 할당합니다.
  • 두 변수가 동일한 객체나 배열을 참조하면, 하나의 변수에서 값을 변경하면 다른 변수의 값도 함께 변경됩니다.

1) 객체의 참조

  • idol과 idol2는 동일한 객체를 참조합니다.
  • idol2.name을 변경하면, idol의 값도 변경됩니다.
  • 두 변수가 동일한 객체를 참조하고 있기 때문입니다.
let idol = {
    name: "Boynextdoor",
};

let idol2 = idol;

console.log(idol); // { name: 'Boynextdoor' }
console.log(idol2); // { name: 'Boynextdoor' }

idol2.name = "보이넥스트도어";

console.log(idol); // { name: '보이넥스트도어' }
console.log(idol2); // { name: '보이넥스트도어' }


2) 객체 비교

  • person1과 person2는 속성 값은 동일하지만, 서로 다른 객체입니다.
  • person1 === person2는 false가 됩니다.
  • 객체 내의 name 값이 동일하므로 person1.name === person2.name는 true입니다.
let person1 = {
    name: "Lee",
};

let person2 = {
    name: "Lee",
};

console.log(person1 === person2); // false
console.log(person1.name === person2.name); // true


3) 요약

  • 객체나 배열은 값을 복사하는 것이 아니라 참조를 복사합니다.
  • 하나의 변수에서 값이 변경되면, 이를 참조하는 다른 변수도 영향을 받습니다.


💌 스프레드 오퍼레이터

Spread Operator

  • 스프레드 오퍼레이터는 객체나 배열을 복사하거나 새로운 객체를 만들 때 사용합니다.
  • 기존의 객체나 배열을 복사하여 새로운 변수로 전달할 수 있습니다.
  • 참조형 데이터는 얕은 복사(shallow copy)가 이루어지기 때문에, 중첩된 객체나 배열의 경우 내부 값은 여전히 참조합니다.

1) 객체 복사

  • person3는 idol 객체를 복사한 새로운 객체입니다.
  • idol의 name은 "Boynextdoor"로 유지되고, person3의 name만 "이한"으로 변경됩니다.
  • 두 객체는 독립적인 객체가 되어 서로 영향을 미치지 않습니다.
let person3 = {
    ...idol,
};

person3.name = "이한";
console.log(idol.name); // Boynextdoor
console.log(person3.name); // 이한


2) 객체 합치기

  • 스프레드 오퍼레이터를 사용해 idol 객체와 idol4 객체를 합쳤습니다.
  • idol4 객체는 idol 객체의 모든 속성을 가지면서, year라는 새로운 속성도 추가되었습니다.
let idol4 = {
    year: 2004,
    ...idol,
};

console.log(idol4); // { year: 2004, name: 'Boynextdoor' }


3) 배열 복사

  • numbers2에 numbers 배열을 할당했기 때문에, 동일한 참조를 공유하고 있습니다.
  • 하나의 배열에 값을 추가하면, 다른 배열도 영향을 받습니다.
const numbers = [1, 2, 3];
const numbers2 = numbers;

numbers2.push(4);

console.log(numbers); // [ 1, 2, 3, 4 ]
console.log(numbers2); // [ 1, 2, 3, 4 ]


4) Spread Operator 사용

  • numbers3는 numbers 배열을 복사하고, 5, 6, 7을 추가한 새로운 배열입니다.
  • numbers에 5를 추가해도 numbers3는 영향을 받지 않습니다.
  • numbers3가 새로 복사된 배열이기 때문입니다.
const numbers3 = [...numbers, 5, 6, 7];

numbers.push(5);

console.log(numbers); // [ 1, 2, 3, 4, 5 ]
console.log(numbers2); // [ 1, 2, 3, 4, 5 ]
console.log(numbers3); // [ 1, 2, 3, 4, 5, 6, 7 ]


5) 요약

  • 스프레드 오퍼레이터 ...를 사용하면 객체나 배열을 복사하거나 합칠 수 있습니다.
  • 객체나 배열을 복사할 때 얕은 복사가 이루어져서, 내부의 참조형 값은 여전히 동일한 객체나 배열을 참조합니다.


💌 실습 예제

쇼핑 카트 만들기

  • 객체를 사용하여 상품 정보를 저장합니다.
  • 배열을 사용하여 여러 상품을 관리할 수 있습니다.
  • 객체의 속성을 활용하여 총 금액 계산합니다.
  • 상품 추가하고 삭제도 할 수 있습니다.
  • 쇼핑 카트의 내용을 콘솔에 출력합니다.

1) 객체 생성

객체를 사용하여 상품 정보를 저장합니다.

  • newProduct라는 객체에는 name / price / count의 값이 담겨있습니다.
let newProduct = {
	name,
	price,
	count,
};


2) 배열 생성

배열을 사용하여 여러 상품을 관리할 수 있습니다.

  • 상품 목록을 담아줄 cart라는 빈 배열을 생성합니다.
  • newProduct에 담기는 값을 cart라는 배열에 push하여 넣습니다.
let cart = [];

let newProduct = {
	name,
	price,
	count,
};

cart.push(newProduct);


3) 총 금액 계산

객체의 속성을 활용하여 총 금액 계산합니다.

  • 총 금액을 계산해주는 getTotalPrice라는 함수를 생섭합니다.
  • 총 계산의 값을 담을 totalPrice라는 변수를 선언하고 0으로 초기화합니다.
  • for문을 활용하여 카트에 담긴 객체의 price와 count를 가져와 총 금액을 계산합니다.
  • 계산된 값이 담긴 totalPrice을 return해줍니다.
function getTotalPrice() {
    let totalPrice = 0;
    // 카트에 담긴 모든 상품의 가격과 수량을 곱해서 더함
    for (let i = 0; i < cart.length; i++) {
        totalPrice += cart[i].price * cart[i].count;
    }
    return totalPrice;
}


4) 상품 추가 & 삭제

상품 추가하고 삭제도 할 수 있습니다.

  • 상품을 추가하는 addProduct와 삭제하는 removeProduct라는 함수를 생성합니다.
  • addProduct는 매개변수로 name, price, count의 값을 받아옵니다.
  • removeProduct는 매개변수로 name, count의 값을 받습니다.
  • 삭제되는 함수에는 삼품의 count가 0일 경우 해당 삼품을 삭제할 수 있도록 합니다.
function addProduct(name, price, count) {
    let newProduct = {
        name,
        price,
        count,
    };
    cart.push(newProduct);
}

function removeProduct(name, count) {
    for (let i = 0; i < cart.length; i++) {
        if (cart[i].name === name) {
            cart[i].count -= count;

            // 수량이 0 이하라면 해당 상품 삭제
            if (cart[i].count <= 0) {
                cart.splice(i, 1);  
            }
            break;  // 해당 상품을 찾으면 반복 종료
        }
    }
}


5) 출력하기

쇼핑 카트의 내용을 콘솔에 출력합니다.

  • 임의의 값을 넣어 결과를 콘솔에 출력하고 확인합니다.
// 상품 추가 예시
addProduct("앨범1", 20000, 2); // { name: '앨범1', price: 20000, count: 2 }
console.log(cart); // [{ name: '앨범1', price: 20000, count: 2 }]

// 상품 수량 감소 예시
removeProduct("앨범1", 1); // 앨범1의 수량을 1개 감소
console.log(cart); // [{ name: '앨범1', price: 20000, count: 1 }]

console.log(cart);
// 전체 가격 출력
console.log("전체 가격은 " + getTotalPrice() + "원 입니다.");


💌 전체 코드

  • 위의 코드를 하나로 합쳐놓은 것입니다.
let cart = [];

function addProduct(name, price, count) {
    let newProduct = {
        name,
        price,
        count,
    };
    cart.push(newProduct);
}

function removeProduct(name, count) {
    for (let i = 0; i < cart.length; i++) {
        if (cart[i].name === name) {
            cart[i].count -= count;

            // 수량이 0 이하라면 해당 상품 삭제
            if (cart[i].count <= 0) {
                cart.splice(i, 1);  
            }
            break;  // 해당 상품을 찾으면 반복 종료
        }
    }
}

function getTotalPrice() {
    let totalPrice = 0;
    // 카트에 담긴 모든 상품의 가격과 수량을 곱해서 더함
    for (let i = 0; i < cart.length; i++) {
        totalPrice += cart[i].price * cart[i].count;
    }
    return totalPrice;
}

// 상품 추가 예시
addProduct("앨범1", 20000, 2); // { name: '앨범1', price: 20000, count: 2 }
console.log(cart); // [{ name: '앨범1', price: 20000, count: 2 }]

// 상품 수량 감소 예시
removeProduct("앨범1", 1); // 앨범1의 수량을 1개 감소
console.log(cart); // [{ name: '앨범1', price: 20000, count: 1 }]

console.log(cart);
// 전체 가격 출력
console.log("전체 가격은 " + getTotalPrice() + "원 입니다.");



20일차(2) 후기

  • 항상 html파일로 script 파일을 작성해서 그런지 결과값을 console로 출력되게 하려고 하다보니 이게 맞나 싶기도 하고 어려운 점이 있어서 시간이 좀 걸린 것 같습니다.
  • 실습 문제도 함께 풀면서 공부 하니까 처음보다는 함수와 객체를 원하는대로 사용할 수 있게된 것 같고 매개변수에 대한 이해도 어느정도 된 것 같습니다.
  • 다른 점은 다 괜찮아졌지만 여전히 "변수에 숫자의 합과 같은 값을 담을 때는 초기 값을 0으로 초기화해야 한다"는 것을 계속 까먹어서 큰일입니다. ㅠㅜ
  • 객체를 처음 배운 날에는 어려워서 걱정이었는데 문제도 풀고 매일 벨로그에 복습할 겸 정리하다보니까 생각보다 금방 적응하고 어려움이 줄어든 것 같습니다. ʕ •̀ ω •́ ʔ
profile
૮꒰ ྀི〃´꒳`〃꒱ა

0개의 댓글