함수와 함수 호출의 차이, 고차 함수

라용·2022년 9월 24일
0

유튜브 ZeroCho 인간 JS 엔진 되기 영상을 보고 정리한 내용입니다.

함수 선언과 호출의 차이를 이해하고, 함수와 함수 호출이 헷갈릴 경우 리턴값으로 대체해서 생각하면 합니다. 우선 기본적인 함수 형태를 살펴보면 아래와 같고

// 화살표 함수
const add = (a, b) => a + b;

// 일반 함수 선언
function calculator(func, a, b) {
	return func(a, b);
}

화살표 함수를 조금 더 살펴보면,

// 화살표 함수는 이렇게 축약된 것
const add = (a, b) => a + b;
const add = (a, b) => (a + b);
const add = (a, b) => {
	return a + b;
};

// 객체를 리턴한다면 이렇게 써야 함, 그냥 {} 만 해버리면 함수의 바디로 인식
const add = (a, b) => ({a + b});

위와 같이 함수를 선언할 수 있고 함수를 호출할 때는 함수 이름 뒤에 () 괄호를 넣어주면 됩니다. 문제가 되는 경우는 아래와 같이 선언한 함수가 아닌 함수의 호출을 바로 넣어주는 경우입니다.

// 이렇게 넣는다면
document.querySelector('#header').addEventListener('click', add())

// 아무런 인자를 전달하지 않은 add 함수의 리턴값을 넣는 것
document.querySelector('#header').addEventListener('click', undefined + undefined)

만약 아래와 같은 고차함수(함수 안에 함수가 있는)라면 리턴 값으로 함수가 들어가므로 문제가 없습니다.

// 고차함수
const onClick = () => () => {
	console.log('hello');
};

// 풀어쓰면 이런 모양
const onClick = () => {
	return () => {
		console.log('hello');
	}
}

document.querySelector('#header').addEventListener('click', onClick())

이렇게 호출이 보일 때 리턴값으로 바꾸어서 생각해보면 오류가 있는지 쉽게 확인 할수 있습니다. 고차함수라 인자를 어디에 넣어야할지 헷갈릴 경우에도 리턴값을 해당 자리에 넣어서 확인해 보면 알 수 있습니다.

// before
const onClick = (event) => () => {
	console.log('hello');
};

document.querySelector('#header').addEventListener('click', () => {console.log('hello')})

// after
const onClick = () => (event) => {
	console.log('hello');
};

document.querySelector('#header').addEventListener('click', (event) => {console.log('hello')})

리액트 예제로 살펴보면,

import { useCallback } from 'react';

export const App = () => {
	const onClick = useCallback((e) => {
		console.log(e.target)
	}, []);
	
	return (
		<div onClick={onClick()}></div>
	)
} 

위처럼 온클릭 함수의 실행을 넣으면 해당 함수의 리턴값을 바로 넣어버렷기 때문에 (인자가 전달되지 않은 상태로) 언디파인드가 됩니다.

<div onClick={console.log(e.target)}></div>
<div onClick={undefined}></div>

아래처럼 고차함수로 작성해야 동작합니다.

import { useCallback } from 'react';

export const App = () => {
	const onClick = useCallback(() => (e) => {
		console.log(e.target)
	}, []);
	
	return (
		<div onClick={onClick()}></div>
	)
} 
profile
Today I Learned

0개의 댓글