다중 매개변수와 다중 반환값
- 인자 개수 > 매개변수 개수 일 때 초과하는 인자는 전달 안 됨
ex ) 아래의 코드에서 2는 전달 안 됨
function add2(n1, n2) {
return n1 + n2;
}
var r1 = add2(5, 9, 2);
매개변수가 3개인 새로운 함수를 만들 것인가?
만약 n개의 정수 합을 구해주는 함수를 만들어야 한다면?
하나의 함수에서 매개변수 개수가 동적이라면 더 효율적일 것
== > 파라미터에 집합자료형(배열, 객체)를 전달
ES6 - spread 문법
- 여러 인자를 하나의 배열로 매개변수에 전달
- spread 문법을 두 번 쓸 수는 없음
어디까지가 numbers 매개변수인지 구분할 수 없기 때문
// ES6 - spread 문법
function addAllES6(...numbers) {
console.log(numbers); // [ 10, 20, 30 ]
var total = 0;
for (var n of numbers) {
total += n;
}
return total;
}
var r3 = addAllES6(10, 20, 30);
console.log(`r3: ${r3}`); // r3: 60
function addAllES6(...numbers, ...others) { } // 불가
function addAllES6(first, second, ...numbers) { } // 가능
다중 반환값
- 파라미터가 여러 개여도 리턴은 하나의 값만 가능
- 리턴 값으로 두 가지 값을 보낼 때 마지막 값만 전달됨
- 집합 자료형을 리턴하면 하나의 집합자료형이라서 여러 결과값 모두 전달 가능
function arithmeticOperate(n1, n2) {
var subResult = n1 - n2;
var multiResult = n1 * n2;
var divResult = n1 / n2;
return {
add: add2(n1, n2), // add2 함수 재사용
div: divResult,
multi: multiResult,
sub: subResult,
};
}
** 함수의 리턴값이 객체라면 바로 프로퍼티(마침표 표기법)으로 가져와도 됨
var r6 = arithmeticOperate(5, 3).multi;
** 프로퍼티 이름을 생략하고 변수명을 값으로 사용하면
자동으로 변수명을 프로퍼티 이름으로 사용
function calcNumbersTotalAndAverage(...numbers) {
var total = 0;
for(var n of numbers) {
total += n;
}
return {
total, // ES6문법 변수명을 키로 자동으로 사용함
avg: total / numbers.length,
};
}
콜백 함수
콜백
- 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수를 콜백 함수
- 매개 변수를 통해 외부에서 콜백 함수를 전달받은 함수를 고차 함수라고 함
** 코드를 읽는 시점 말고 나중에 호출
= 함수 만들어 놓고 특정 상황에 호출 ( ex. 마우스 클릭, 키보드 d키 다운, … )
짝수를 구하는 함수
function showEvenNumber(n) {
for (var i = 1; i <= n; i++) {
if (i % 2 === 0) {
console.log(i);
}
}
}
홀수를 구하는 함수
function showOddNumber(n) {
for (var i = 1; i <= n; i++) {
if (i % 2 === 1) {
console.log(i);
}
}
}
이 두 함수를 보면 i % 2 === [____] → 이 대괄호 자리에 0 또는 1만 바뀌고 있음
하나의 함수로 만들면 더 효율적인 코드이지 않을까 의문이 발생
0 과 1 을 파라미터로 받는 방법이 있음
function showOddOrEvenNumber(n, delimiter) {
for (var i = 1; i <= n; i++) {
if (i % 2 === delimiter) { --------- @@
console.log(i);
}
}
}
그런데 3의 배수를 출력하려면?
6의 배수면서 12의 배수가 아닌 것을 출력하려면?
위 코드의 @@에 해당하는 if(조건식) 의 조건식만 변경하면 될 것 같다는 생각이 든다
일종의 틀을 함수(미완성)에 만들어 두고
함수를 호출하는 곳에서 조건식을 전달하는 방법이 콜백함수
콜백의 핵심 : 동작을 파라미터화
- if문에 들어있는 조건식들만 파라미터로 전달한다면 쉽게 해결되는 문제
- 단순히 0과 1같은 숫자가 아닌 조건식 자체를 함수에게 전달해줄 수는 없을까?
- 자바스크립트의 함수는 함수에게 다른 코드를 전달하는 것이 가능
- 단, 전달할 코드가 함수에 묶여있어야 한다는게 포인트
ex) 4의 배수이면서 8의 배수는 아닌 수
조건을 표현해보면
i % 4 === 0 && i % 8 !== 0
condition 으로 showNumber 함수에 조건식을 전달
// 콜백을 이용한 솔루션
// 정수 n을 전달하면 1 ~ n까지의 정수를 조건에 맞게 출력
function showNumber(n, condition) {
const nums = []
for(let i = 1; i <= n; i++) {
if(condition(i)) {
nums.push(i);
}
}
console.log(nums);
}
showNumber(50);
ex ) 템플릿 함수에 콜백 활용
레시피 템플릿만 함수에 작성하고 요리법 마다 내용만 바꿔가며 출력
ex ) 필터링 함수에 콜백 활용
급여가 400만원 이상이면서 나이가 30세 이상인 사람만 추출
서울 살면서 직업이 개발자인 사람만 추출
콜백 함수의 흐름
** 함수 호출하면 리턴 값이 호출한 곳으로 돌아온다는 점을 참고
프로그램 실행 (map 함수는 메모리에 저장만 된 상태)
(1) map 함수 호출
(2) user ⇒ user.userName 함수가 map 함수의 매개변수인 callback 자리에 전달
*** 어떤 실행도 하지 않은 상태
(1) map 함수 코드 실행 시작
(1) map 함수 내부의 for문 1회차 시작
1. (3) callback(user)에서 for문 userList의 첫 번째 user를 인자로 대입 후 호출
2. 아래의 (2) user ⇒ user.userName 함수로 이동
3. (2)함수를 실행하여 첫 번째 user의 userName 리턴값 연산
4. 위의 호출한 곳(3)에 리턴 값인 첫 번째 user의 userName을 대입
5. 1회차 종료
(1) map 함수 내부의 for문 2회차 시작
1. (3) callback(user)에서 for문 userList의 두 번째 user를 인자로 대입 후 호출
2. 아래의 (2) user ⇒ user.userName 함수로 이동
3. (2)함수를 실행하여 두 번째 user의 userName 리턴값 연산
4. 위의 호출한 곳(3)에 리턴 값인 두 번째 user의 userName을 대입
5. 2회차 종료
… 반복
(1) 코드 실행 완료하여 mappedArray 값 리턴 후 map 함수 종료
(1) map 함수 호출한 자리로 리턴된 mappedArray 값이 전달 되어 const nameList에 저장