Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript는 값에 의한 전달일까요, 참조에 의한 전달일까요?

JavaScript는 기본적으로 값에 의한 전달(pass by value) 방식으로 동작하는 언어입니다. 다만 객체(Object)의 경우 그 '값'이 곧 참조(reference)라는 점이 특별합니다. 예를 들어, 함수에 숫자를 인자로 전달한 뒤 함수 내부에서 그 값을 증가시켜도, 호출자 쪽의 원본 값은 변경되지 않습니다.

예제: 원시 타입의 값에 의한 전달

let i = 0;
function increment(x) {
    x = x + 1;
    console.log(x);
}
increment(i);
console.log(i);

출력 결과

1
0

함수 내부에서 x는 1로 증가하여 "1"이 출력되지만, 원본 변수 i의 값은 여전히 0으로 유지됩니다. 이는 함수 호출 시 변수의 복사본이 전달되기 때문입니다.

객체 전달 시의 동작

객체를 함수에 전달할 때는 상황이 조금 다릅니다. 함수 내부에서 전달받은 매개변수를 다른 객체로 재할당하면 원본 객체에는 아무런 영향을 주지 않습니다. 하지만 매개변수가 참조하고 있는 객체의 내부 속성을 변경(변이)하면, 그 변경 사항은 원본 객체에 그대로 반영됩니다.

예제: 객체 참조와 변이

let obj = {'foo': 'bar'};
function updateRef(x) {
    // 지역 변수 x의 참조만 변경되며, obj에는 영향 없음
    x = {}
}
function addHelloWorld(y) {
    // y가 참조하는 객체에 새 속성 추가
    y['hello'] = 'world';
}
console.log(obj)
updateRef(obj)
console.log(obj)
addHelloWorld(obj)
console.log(obj)

출력 결과

{ foo: 'bar' }
{ foo: 'bar' }
{ foo: 'bar', hello: 'world' }

결과 분석

첫 번째 함수 updateRef에서는 지역 변수 x가 새로운 빈 객체로 재할당되었을 뿐입니다. 이는 x의 지역 참조만 바뀌는 것이므로 원본 obj에는 어떠한 영향도 미치지 않았습니다.

반면 두 번째 함수 addHelloWorld에서는 y가 여전히 obj 객체를 참조하고 있었고, y를 통해 해당 객체의 내부 상태를 변경했습니다. 그 결과 hello: 'world'라는 새로운 속성이 원본 객체에 추가된 것입니다.

정리

JavaScript는 항상 값에 의한 전달 방식으로 동작하지만, 객체의 경우 그 값이 곧 메모리상의 참조이기 때문에 함수 내부에서 객체의 내용을 수정하면 원본에도 영향을 줍니다. 반대로 매개변수 자체를 재할당하는 것은 원본과 완전히 무관합니다. 이러한 동작 방식을 정확히 이해하면 불변성(immutability) 패턴이나 함수형 프로그래밍을 활용할 때 큰 도움이 됩니다.