본문 바로가기
JavaScript/JavaScript

Javascript) 함수를 매개인자로 사용, 함수를 리턴 값으로 사용

by 박채니 2022. 5. 21.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


함수를 매개인자로 사용

- 함수는 1급 객체 (값과 동일)

- 함수를 값으로써 사용

 

HTML 코드

<button onclick="test10();">함수고급 - 함수를 매개인자로 사용1</button>

 

Javscript 코드

const test10 = () => {
    const f = () => {console.log('안녕')};
    runner(f);
};

const runner = (f) => {
    console.log(typeof f, f);
};

console.log('안녕')을 출력하는 함수를 변수 f에 담고 runner함수의 매개인자로 넘겨 주었습니다.

runner는 매개변수 (f)로 전달 받은 후 f의 type과 f를 확인해보면, function 타입과 넘겨준 함수 () => {console.log('안녕')}이 출력 되는 것을 확인할 수 있습니다.

 

그렇다면 매개변수로 넘겨받은 인자가 함수이기 때문에 매개변수();로 함수를 호출해줄 수도 있습니다.

const test10 = () => {
    const f = () => {console.log('안녕')};
    runner(f);	// 매개인자
};

const runner = (f) => {
    // console.log(typeof f, f);
    f();
};

 

개념이 낯설게 느껴질 수도 있지만 아래와 같은 개념입니다.

// 원시값을 변수에 대입
const x = 100;
const y = x;
console.log(x);
console.log(y);

// 변수를 함수에 대입
const a = () => {console.log('안녕')};
const b = a;
a();
b();

 

자바스크립트는 타입을 미리 지정해줄 수 없기 때문에 넘어오는 매개인자가 함수가 아닐 경우도 있을겁니다.

예를 들어 매개인자로 100을 넘겨주었다고 가정해보겠습니다.

const test10 = () => {
    const f = () => {console.log('안녕')};
    // runner(f);
    runner(100);
};

const runner = (f) => {
    console.log(typeof f, f);
    f();
};

number 타입의 100이 매개변수로 넘어왔는데 이를 f(); 호출하려고 하니 함수가 아니라는 오류 메세지가 발생한 것이죠.

"Uncaught TypeError: f is not a function"

 

이러한 상황을 대비하여 좀 더 안전하게 함수를 호출해줄 필요가 있습니다.

const test10 = () => {
    const f = () => {console.log('안녕')};
    runner(f);
    runner(100);
};

const runner = (f) => {
    typeof f === 'function' && f();
    // console.log(typeof f, f);
    // f();
};

type검사를 통해 넘어온 매개인자의 type이 'function'이라면 실행하도록 하여 비교적 안전하게 관리할 수 있게 되었습니다.

 

이번에는 안녕0, 안녕1, 안녕1, ~ 안녕9를 출력해보도록 하겠습니다.

const test10 = () => {
    const f = () => {console.log('안녕')};
    runner(f);
};

const runner = (f) => {
    // typeof f === 'function' && f();
    // console.log(typeof f, f);
    for(let i = 0; i < 10; i++) {
        f(i);
    }
};

반복문을 통해서 0 ~ 9까지의 숫자를 출력할 수 있지만, '안녕'과 함께 숫자를 출력해야 할 때는 어떻게 해야할까요?

 

매개변수로 넘어온 f에는 매개인자로 넘겨준 '() => {console.log('안녕')'이 대입된 것을 위에서 확인했습니다.

함수 자체가 넘어오게 된 것이므로, 매개변수 f 또한 함수인 셈입니다.

 

그렇다면 매개변수 f()의 매개인자로 값을 넘겨준다면 변수 f에서 매개변수로 이를 받아 값을 출력할 수 있겠죠?

const test10 = () => {
    const f = (n) => {console.log(`안녕${n}`)};
    runner(f);
};

const runner = (f) => {
    for(let i = 0; i < 10; i++) {
        f(i);
    }
};

이렇게 처리할 수 있습니다.

 

@실습 - 계산기 처리

HTML 코드

<button onclick="test11();">함수 고급 - 함수를 매개인자로 사용2</button>

 

Javascript 코드

const test11 = () => {
    calculator((a, b) => a + b, 10, 20); // 30
    calculator((a, b) => a - b, 10, 3); // 7
    calculator((a, b) => a * b, 3, 5); // 15
    calculator((a, b) => a / b, 10, 3); // 3.333 ...
};

const calculator = (f, a, b) => {
    console.log(f(a, b));
}

calculator() 함수에 매개인자로 ((a, b) => a + b 함수, 숫자, 숫자)를 넘겨주었습니다.

넘겨준 함수는 실행부가 한 줄이기 때문에 return과 {}가 생략된 형태이며, 또 다른 매개인자를 넘겨받아 연산 처리 후 값을 return해주는 함수로 보여집니다.

 

그렇다면, calculator함수에서는 매개변수 f, a, b로 각각 함수와 숫자 두 개를 받은 후 다시 넘겨받은 함수 f에 매개인자를 전달 하며 함수 호출하여 리턴 받은 값을 출력해줍니다.

(매개변수 f에는 ((a, b) => a + b) 함수가 들어있을 것이며 넘겨받은 숫자 두 개를 다시 매개인자로 넘겨준 후 값을 리턴 받아 출력)

 


함수를 리턴 값으로 사용

 

HTML 코드

<button onclick="test12();">함수 고급 - 함수를 리턴 값으로 사용</button>

 

Javascript 코드

const test12 = () => {
    const result = m();
    console.log(typeof result, result);
}

const m = () =>  {
    return () => console.log('안녕');
}

함수 m()을 호출하여 받은 리턴 값을 result에 담아주었습니다.

함수 m()은 console.log('안녕')을 실행하는 함수를 리턴하고 있기 때문에 result에는 함수 m()의 리턴 값인 '() => console.log('안녕')'의 함수를 갖고 있습니다.

따라서 result의 type은 function이며, '() => console.log('안녕')'이 담겨져있습니다.

 

그렇게 때문에 result를 호출해줄 수도 있습니다.

const test12 = () => {
    const result = m();
    // console.log(typeof result, result);
    result();
}

const m = () =>  {
    return () => console.log('안녕');
}

 

result()의 매개인자로 '메롱'을 넘겨주어 '안녕메롱'이 출력되도록 해보겠습니다.

const test12 = () => {
    const result = m();
    // console.log(typeof result, result);
    result('메롱');
}

const m = () =>  {
    return (a) => console.log('안녕' + a);
}

result에 '() => console.log('안녕')이 넘어왔었기 때문에 매개변수를 해당하는 함수에 입력해줘야 합니다.

 

이를 이용하여 아래와 같은 코드를 만들 수 있습니다.

const test12 = () => {
    const hello = funcMaker('안녕');
    hello('철수');
    
    const bye = funcMaker('잘가');
    bye('철수');
};

const funcMaker = (word) => {
    return (name) => {console.log(`${name}야~ ${word}`)};
}

hello에는 '(name) => {console.log(`${name}야~ ${word}`)} 함수가 담겨있기 때문에 커스터마이징한 hello함수를 호출할 때 매개인자로 '철수'를 넘겨주어 '철수야~ 안녕'을 리턴해주었습니다.

 

const hello = funcMaker('안녕');

const friends = ['철수', '영희', '진구', '태양'];
friends.forEach((name) => hello(name));

forEach() 함수를 이용해 여러 이름을 대입하여 사용할 수도 있습니다.

 

const hello = funcMaker('안녕');

const friends = ['철수', '영희', '진구', '태양'];
friends.forEach(hello);

이처럼 줄여쓸 수도 있습니다.