매개변수(parameter)는 함수를 만들 때 괄호 안에 적는 이름이고, 인자(argument)는 부를 때 괄호 안에 넘기는 값입니다. 함수를 부르면 새 칸이 생기고, 그 칸에서 매개변수가 넘긴 인자에 차례로 붙습니다. 인자가 모자라면 짝이 없는 매개변수는 undefined에 붙습니다.
앞 레슨의 greet()는 부를 때마다 같은 인사만 찍었습니다. 괄호 안에 매개변수를 두면 한 함수가 부를 때마다 다른 값으로 일합니다. console.log('커피')에서 괄호 안에 넘긴 '커피'도 인자였습니다.
이 레슨에서는 매개변수가 어느 칸에서 어떤 값에 붙는지, 인자 수가 맞지 않으면 어떻게 되는지 봅니다.
1매개변수는 적은 차례대로 인자에 붙는다
매개변수는 쉼표로 나눠 여럿 둘 수 있고, 부를 때도 인자를 쉼표로 나눠 넘깁니다.
function order(item, qty) {
return `${item} ${qty}잔`;
}
console.log(order('커피', 2));
console.log(order(2, '커피'));
커피 2잔
2 커피잔5번 줄이 order를 부르면 새 칸이 생기고, 첫째 매개변수 item은 첫째 인자 '커피'에, qty는 둘째 인자 2에 붙습니다(규칙 5). 6번 줄은 인자의 차례가 바뀌어 item이 2에, qty가 '커피'에 붙습니다. 자바스크립트는 item이 메뉴라는 뜻을 모르고 차례만 봅니다(규칙 6). 인자는 매개변수를 적은 차례대로 넘깁니다.
함수에 넘어가는 것은 이름이 아니라 값입니다. const drink = '라테';를 두고 order(drink, 1)로 부르면, 괄호 안의 drink를 먼저 계산한 값 '라테'가 넘어가 새 칸의 item이 그 값에 붙습니다. 그래서 바깥 이름이 매개변수 이름과 달라도 됩니다.
2인자가 모자라면 undefined에 붙는다
그림의 코드입니다. 이번에는 인자를 하나만 넘겼습니다.
function order(item, qty) {
return `${item} ${qty}잔`;
}
const msg = order('라테');
console.log(msg);
라테 undefined잔5번 줄이 부르면 새 칸에서 item은 '라테'에 붙습니다. 짝지을 인자가 없는 qty는 '아직 아무 값도 정해지지 않았다'는 값 undefined에 붙습니다. 자바스크립트는 인자가 모자라도 멈추지 않고 2번 줄을 그대로 실행해, 글자 undefined가 든 '라테 undefined잔'을 돌려줍니다.
함수가 끝나면 칸이 사라지고, 칸에 생긴 이름 item과 qty도 함께 사라집니다. 그림 끝에서 '라테'를 가리키는 이름이 없는 까닭입니다.
이번에는 수를 더하는 함수에 인자를 하나만, 또 셋을 넘깁니다. 무엇이 찍힐까요? 답을 정한 뒤 펼쳐 보세요.
function add(a, b) {
return a + b;
}
console.log(add(1));
console.log(add(1, 2, 3));
실행 결과 보기
NaN
3예상과 다르면 그곳이 배울 곳입니다.
5번 줄은 b가 undefined에 붙어 2번 줄이 1 + undefined를 계산합니다. undefined를 수로 바꾸면 '수가 아님' NaN이 되어 결과도 NaN이고, 이번에도 오류는 나지 않습니다.
6번 줄은 셋째 인자 3과 짝지을 매개변수가 없어, 3은 버려지고 1 + 2만 계산합니다.
예제
영수증 한 줄 찍기
인자 자리에는 식도 쓸 수 있습니다. 식을 먼저 계산한 값 하나가 넘어갑니다.
function receipt(item, won) {
console.log(item, `${won}원`);
}
receipt('커피', 4000);
receipt('라테', 4500 * 2);
커피 4000원
라테 9000원6번 줄은 4500 * 2를 계산한 9000을 넘겨, 새 칸에서 won이 9000에 붙습니다(규칙 2).
자주 틀리는 곳
틀린 생각: 인자를 빠뜨리면 그 줄에서 오류가 나 바로 알 수 있다.
값이 빠졌으니 멈출 것 같지만, 2절에서 보았듯 짝이 없는 매개변수는 undefined에 붙고 계산은 NaN이나 'undefined잔'으로 이어집니다. 틀린 값은 그 값을 쓰는 줄에서야 드러납니다.
맞는 규칙: 인자가 모자라면 짝이 없는 매개변수가 undefined에 붙고, 함수는 멈추지 않습니다. 결과가 이상하면 부른 줄의 인자 수부터 봅니다(규칙 5).
틀린 생각: 매개변수보다 많이 넘긴 인자도 함수 안 어딘가에 쓰인다.
넘긴 값은 다 쓰일 것 같지만, 2절의 add(1, 2, 3)이 3을 돌려준 것처럼 셋째 인자는 짝지을 매개변수가 없어 버려집니다.
맞는 규칙: 인자는 매개변수와 차례대로 짝지어지고, 짝이 없는 인자는 버려집니다. 이때도 오류는 나지 않습니다.
틀린 생각: 함수 안에서 찍은 글자가 부른 자리로 돌아온다.
화면에 '민지 님'이 보이니 그 글자가 함수의 결과처럼 보입니다.
function greet(name) {
console.log(name, '님');
}
const x = greet('민지');
console.log(x);
민지 님
undefined'민지 님'은 2번 줄이 화면에 쓴 것이고, x가 붙은 값은 greet가 돌려준 undefined입니다.
맞는 규칙: 함수 안의 console.log는 화면에 쓸 뿐이고, 값을 돌려받는 것은 return입니다(규칙 5).
틀린 생각: 매개변수와 바깥 이름이 같으면 한 이름표다.
같은 글자로 쓴 이름이니, 함수 안에서 다시 붙이면 바깥 이름도 따라갈 것 같습니다.
let qty = 1;
function add(qty) {
qty = qty + 1;
return qty;
}
console.log(add(qty));
console.log(qty);
2
1매개변수 qty는 add를 부를 때 새 칸에 따로 생겨 넘긴 값 1에 붙습니다. 3번 줄은 그 칸의 qty만 2에 다시 붙이고, 바깥 qty는 1 그대로입니다.
맞는 규칙: 매개변수는 부를 때마다 새 칸에 따로 생기는 이름이라, 바깥에 같은 이름이 있어도 다른 이름표입니다(규칙 5).
확인 문제
1. 예제 코드의 6번 줄을 receipt('라테', 4500 + 500);으로 바꿨습니다. 무엇이 찍힐까요? 두 줄을 글자 그대로 쓰세요.
function receipt(item, won) {
console.log(item, `${won}원`);
}
receipt('커피', 4000);
receipt('라테', 4500 + 500);
힌트
6번 줄에서 둘째 인자 자리의 식을 먼저 계산하고, 그 값에 어느 매개변수가 붙는지 봅니다.
정답
커피 4000원
라테 5000원6번 줄은 4500 + 500을 계산한 5000을 넘기고, 새 칸에서 won이 5000에 붙습니다.
흔한 오답은 라테 4500 + 500원입니다. 인자 자리의 식이 계산되지 않고 글자처럼 넘어간다고 본 것입니다(식이 저장된다는 생각). 넘어가는 것은 식을 계산한 값 하나입니다(규칙 2).
2. 빈칸을 채워 코드를 완성하세요.
(가) 낸 돈과 값을 받아 거스름돈을 돌려주는 함수입니다. '2. 계산하기'의 빈칸을 채우세요. 다 채운 코드는 5000과 1500을 두 줄로 찍어야 합니다.
// 1. 받을 값 정하기
function change(paid, price) {
// 2. 계산하기
const left = ____;
// 3. 돌려주기
return left;
}
console.log(change(9000, 4000));
console.log(change(5000, 3500));
힌트
9번 줄에서 paid와 price가 각각 어느 인자에 붙는지 먼저 적습니다.
정답
paid - price입니다.
빈칸에 5000을 바로 쓰면 첫 줄은 맞지만, 둘째 줄도 5000이 찍혀 1500이 되지 않습니다. 인자가 바뀌면 따라 바뀌도록 매개변수로 계산합니다.
흔한 오답은 price - paid입니다. -5000과 -1500이 찍힙니다. 첫째 매개변수 paid는 첫째 인자 9000에 붙습니다(규칙 6).
(나) 함께 낸 금액을 사람 수로 나누는 함수입니다. '1. 받을 값 정하기'를 통째로 채우세요. 다 채운 코드는 4000과 2500을 두 줄로 찍어야 합니다.
// 1. 받을 값 정하기
// 2. 계산하기
const each = total / count;
// 3. 돌려주기
return each;
}
console.log(share(12000, 3));
console.log(share(10000, 4));
힌트
빈 줄에는 function 줄 하나가 들어갑니다. 함수 이름은 9번 줄에, 매개변수 이름은 4번 줄에 있습니다.
정답
function share(total, count) {입니다.
9번 줄의 첫째 인자 12000에 total이, 둘째 인자 3에 count가 붙어야 12000 / 3 = 4000입니다.
흔한 오답은 function share(count, total) {입니다. count가 12000, total이 3에 붙어 3 / 12000을 계산하므로 0.00025와 0.0004가 찍힙니다. 매개변수는 인자를 넘기는 차례대로 적습니다(규칙 6).
3. 요일과 걸음 수를 찍는 함수입니다. 무엇이 찍힐까요? 두 줄을 글자 그대로 쓰세요.
function walk(day, n) {
console.log(day, `${n}걸음`);
}
walk('월', 5000);
walk('화');
힌트
6번 줄에서 n과 짝지을 인자가 있는지 봅니다.
정답
월 5000걸음
화 undefined걸음6번 줄은 인자가 하나라 day만 '화'에 붙고, 짝이 없는 n은 undefined에 붙습니다. 템플릿 문자열은 그 값을 글자 undefined로 넣어 찍습니다.
흔한 오답은 둘째 줄 대신 오류로 멈춘다고 쓰는 것입니다. 인자가 모자라면 오류가 난다고 본 것입니다(없으면 오류라는 생각). 짝이 없는 매개변수는 undefined에 붙고 함수는 끝까지 돕니다(규칙 5).
컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요.
1절 코드(여섯 줄)를 main.js에 저장해 돌립니다. 그다음 5번 줄의 order('커피', 2)에서 '커피'를 빼고 order(2)로 부르면 무엇이 찍힐지 먼저 적고, 바꿔 돌려서 맞춰 봅니다.
저장하고 돌리는 법은 내 컴퓨터에서 돌려 보기에 있습니다.