LHJ

I'm a FE developer.

6.3 함수와 매개변수

28 Apr 2020 » js_lj

함수를 호출해서 값을 얻는 방법을 배웠습니다.
그렇다면 함수에 정보를 전달하려면 어떻게 해야 할까요?
함수를 호출하면서 정보를 전달할 때는 함수 매개변수(argument, parameter) 를 이용합니다.
매개변수는 함수가 호출되기 전에는 존재하지 않는다는 점을 제외하면 일반적인 변수나 마찬가지입니다.
숫자형 매개변수 두 개를 받고 그 평균을 반환하는 함수를 생각해 봅시다.

function avg(a, b) {
	return (a + b)/2;
}

이 함수 선언에서 a와 b를 정해진 매개변수(formal argument) 라고 합니다.
함수가 호출되면 정해진 매개변수는 값을 받아 실제 매개변수(actual argument) 가 됩니다.

avg(5, 10); // 7.5

이 예제에서 정해진 매개변수 a와 b는 각각 5와 10을 받아 실제 매개변수가 됩니다.
실제 매개변수는 변수와 매우 비슷하지만, 함수 바디 안에서만 존재합니다.

초보자들은 같은 이름의 변수가 함수 바깥에 존재하는데도 매개변수가 함수 안에서만 존재한다는 말에 어리둥절해하곤 합니다. 다음 예제를 보십시오.

const a = 5, b = 10;
avg(a, b);

첫 행의 변수 a, b는 함수 avg의 매개변수인 a, b와 같은 이름이지만, 엄연히 다른 변수입니다.
함수를 호출하면 함수 매개변수는 변수 자체가 아니라 그 값을 전달받습니다.
다음 코드를 보십시오.

function f(x) {
	console.log(`f 내부 : x = ${x}`);
	x = 5;
	console.log(`f 내부 : x = ${x} (할당 후)`);
}

let x = 3;
console.log(`f를 호출하기 전 : x = ${x}`);
f(x);
console.log(`f를 호출한 다음 : x = ${x}`);

이 예제를 실행한 결과는 다음과 같습니다.

f를 호출하기 전 : x = 3
f 내부 : x = 3
f 내부 : x = 5 (할당 후)
f를 호출한 다음 : x = 3

여기서 중요한 것은 함수 안에서 x에 값을 할당하더라도 함수 바깥의 변수 x에는 아무 영향도 없다는 겁니다.
이름은 같지만, 둘은 다른 개체입니다.

함수 안에서 매개변수에 값을 할당해도 함수 바깥에 있는 어떤 변수에도 아무런 영향이 없습니다.
하지만 함수 안에서 객체 자체를 변경하면, 그 객체는 함수 바깥에서도 바뀐 점이 반영됩니다.
다음 예제를 보십시오.

function f (o) {
	o.message = `f 안에서 수정함 (이전 값 : '${o.message}')`;
}
let o = {
	message: "초기 값"
}
console.log(`f를 호출하기 전 : o.message = "${o.message}"`);
f(o);
console.log(`f를 호출한 다음 : o.message = "${o.message}"`);

앞의 코드를 실행한 결과는 다음과 같습니다.

이 예제를 보면 함수 f 안에서 객체 o를 수정했고, 이렇게 바꾼 내용은 함수 바깥에서도 o에 그대로 반영되어 있음을 알 수 있습니다.
이것이 원시 값객체핵심적인 차이입니다.
원시 값은 불변이므로 수정할 수 없습니다.
원시 값을 담은 변수는 수정할 수 있지만(다른 값으로 바꿀 수 있지만) 원시 값 자체는 바뀌지 않습니다.
반면 객체는 바뀔 수 있습니다.

좀 더 명확하게 말해봅시다.
함수 안의 o와 함수 바깥의 o는 서로 다른 개체입니다.
하지만 그 둘은 같은 객체를 가리키고 있습니다.
할당을 이용해서 차이점을 다시 알아봅시다.

function f(o) {
	o.message = "f에서 수정함";
	o = {
		message: "새로운 객체!"
	};
	console.log(`f 내부: o.message = "${o.message}" (할당 후)`);
}

let o = {
	message: '초기 값'
};

console.log(`f를 호출하기 전 : o.message="${o.message}"`);
f(o);
console.log(`f를 호출한 다음 : o.message="${o.message}" `);

이 예제를 실행한 결과는 다음과 같습니다.

이 예제를 이해하는 핵심은 함수 내부의 매개변수 o와 함수 바깥의 변수 o가 다르다는 겁니다.
f를 호출하면 둘은 같은 객체를 가리키지만, f 내부에서 o에 할당한 객체는 새로운, 전혀 다른 객체입니다.
함수 바깥의 o는 여전히 원래 객체를 가리키고 있습니다.

NOTE_
컴퓨터 과학에서는 자바스크립트의 원시 값을 값 타입(value type) 이라고 말합니다.
원시 값을 전달할 때 값이 복사되기 때문입니다.
객체는 참조 타입(reference type) 이라 부릅니다.
객체를 전달할 때 두 변수는 같은 객체를 가리키기 때문입니다.