12장 함수 ⭐⭐⭐⭐
12.1 함수란?
함수는 JS에서 가장 중요한 핵심 개념이다. JS에서 중요한 개념들이 모두 함수와 관련이 있어 함수는 JS를 정확히 이해하고 사용하기 위해 피해갈 수 없는 핵심 중의 핵심이라 할 수 있다.
함수는 일련의 과정을 문으로 구현하고 코드 블록으로 감싸 하나의 실행 단위로 정의한 것이다.
함수 내부로 입력을 전달받는 매개변수, 입력을 인수, 출력을 반환값이라 하며, 함수는 값이기에 여러 개 존재할 수 있고, 특정 함수를 구별하기 위해 식별자인 함수 이름을 사용할 수 있다.
함수는 함수 정의를 통해 생성된다. 그리고 인수를 매개변수를 통해 함수에 전달하면서 함수의 실행을 명시적으로 지시하는 것을 함수 호출이라 한다. 함수를 호출하면 코드 블록에 담긴 문들이 일괄적으로 실행되고 결과인 반환값을 반환한다.
12.2 함수를 사용하는 이유
코드의 재사용성 - 함수는 필요할 때 몇번이든 여러 번 호출 할 수 있다.
코드의 신뢰성 - 코드의 중복을 억제하고 재사용성을 높이는 함수는 유지보수의 편의성을 높이고 실수를 줄여 코드의 신뢰성을 높인다.
코드의 가독성 - 함수는 객체 타입의 값이기에 이름을 붙일 수 있다. 적절한 이름은 함수의 역할을 파악할 수 있게 도와줘 가독성을 높인다.
12.3 함수 리터럴
함수는 객체 타입의 값이다. 따라서 함수를 함수 리터럴로 생성할 수 있다. 함수 리터럴은 function 키워드, 함수 이름, 매개 변수 목록, 함수 몸체로 구성된다.
함수 이름 ㄴ 식별자, 네이밍 규칙을 준수해야함. ㄴ 함수 몸체 내에서만 참조할 수 있는 식별자 ㄴ 생략 가능
매개변수 목록 ㄴ 0개 이상의 매개변수를 소괄호로 감싸고 쉼표로 구분한다. ㄴ 각 매개변수에는 함수를 호출할 때 지정한 인수가 순서대로 할당된다. ㄴ 함수 몸체 내에서 변수와 동일하게 취급된다. 식별자 네이밍 규칙을 준수해야함
함수 몸체 ㄴ 함수가 호출되었을 때 일괄적으로 실행될 문들을 하나의 실행 단위로 정의한 코드 블록 ㄴ 함수 몸체는 함수 호출에 의해 실행된다
12.4 함수 정의
JS에는 함수를 정의하는 4가지 방법이 있다.
12.4.1 함수 선언문
함수 선언문은 표현식이 아닌 문이다.
함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출한다. 함수 선언문으로 생성한 함수를 호출하는 것은 함수 이름 add가 아니라 식별자 add인 것이다.
12.4.2 함수 표현식
JS 함수는 일급 객체다. 값의 성질을 갖는 객체를 일급 객체라 한다. 이 말은 함수를 값처럼 자유롭게 사용할 수 있다는 의미다. 함수 리터럴로 생성한 함수 객체를 변수에 할당하는 방식을 함수 표현식이라 한다.
함수 리터럴의 함수 이름은 생략할 수 있다. 이러한 함수를 익명 함수라 한다. 함수 표현식의 함수 리터럴은 함수 이름을 생략하는 것이 일반적이다.
함수 선언문은 표현식이 아닌 문이고 함수 표현식은 표현식인 문이라는 차이가 있다.
12.4.3 함수 생성 시점과 함수 호이스팅
var로 정의한 함수 선언문은 선언 이전에 호출할 수 있다. 하지만 표현식으로 정의한 함수는 불가능하다. 이는 함수 선언문으로 정의한 함수와 함수 표현식으로 정의한 함수의 생성 시점이 다르기 때문이다. 함수 선언문으로 함수를 선언하면 런타임 이전에 객체가 먼저 생성되어 코드의 선두로 끌어 올려진 듯 동작하는 함수 호이스팅이 발생한다.
함수 표현식은 변수에 할당되는 값이 리터럴인 문이다. 따라서 함수 표현식은 변수 선언문과 변수 할당문을 한 번에 기술한 축약 표현과 동일하게 동작한다. 변수 선언은 런타임 이전에, 변수 할당문의 값은 할당문이 실행되는 런타임에 평가되므로 함수 표현식의 함수 리터럴도 할당문이 실행되는 시점에 평가되어 함수 객체가 된다. 따라서 함수 표현식은 변수 호이스팅이 발생한다.
12.4.4 Function 함수 생성자 함수
일반적이지 않으며 바람직하지 않은 방법이다.
이렇게 생성된 함수는 클로저를 생성하지 않는 등 함수 선언문이나 함수 표현식으로 생성한 함수와 다르게 동작한다.
12.4.5 화살표 함수
ES6에서 도입된 화살표 함수는 ⇒를 사용해 간략한 방법으로 함수를 선언할 수 있다. 화살표 함수는 항상 익명 함수로 정의한다.
화살표 함수는 기존의 방법을 대체하기 위한 방법이 아니다. 따라서 기존 함수와 다른 부분이 있다.
12.5 함수 호출
함수는 함수를 가리키는 식별자와 함수 호출 연산자로 호출한다. 함수를 호출하면 현재 실행 흐름을 중단하고, 호출된 함수로 실행 흐름을 옮긴다. 이때, 매개변수에 인수가 순서대로 할당되고 함수 몸체의 문들이 실행되기 시작한다.
12.5.1 매개변수와 인수
매개변수의 스코프는 함수 내부.
함수는 매개변수의 개수와 인수의 개수가 일치하는지 체크하지 않는다. 인수가 매개변수보다 적으면 매개변수는 undefined로 초기화되고, 인수가 매개변수보다 많으면 암묵적으로 arguments 객체의 프로퍼티로 보관된다.
12.5.2 인수 확인
JS 는 동적 타입 언어로 매개변수의 타입을 사전에 지정할 수 없다. (⇒ 타입스크립트)
그래서 함수를 사용할 때, 적절한 인수가 전달되었는지 확인할 필요가 있다.
매개변수 기본값을 이용하면 매개변수에 인수를 전달하지 않거나 undefined를 전달할 때 인수 체크 및 초기화를 간소화 할 수 있다.
12.5.3 매개변수의 최대 개수
매개변수의 최대 개수는 명시적으로 제한되어 있지 않다. 하지만 이상적인 매개변수의 개수는 0개로, 함수가 한 가지 일만 할 수 있도록 가급적 작게 만들어야 한다.
객체를 인수로 사용하는 경우 프로퍼티 키만 정확히 지정하면 매개변수의 순서를 신경쓰지 않아도 된다. 하지만 함수 내부에서 값을 변경하면 함수 외부 객체가 변경되는 부수 효과가 발생하기에 주의해야 한다.
12.5.4 반환문
함수는 return 키워드와 표현식으로 이루어진 반환문을 사용해 실행 결과를 함수 외부로 반환할 수 있다. 반환문의 역할은 다음과 같다.
함수의 실행을 중단하고 함수 몸체를 빠져나간다. ㄴ 반환문 이후의 다른 문은 실행되지 않고 무시된다.
return 키워드 뒤에 오는 표현식을 평가해 반환한다. ㄴ 반환값으로 사용할 표현식을 명시적으로 지정하지 않으면 undefined가 반환된다.
12.6 참조에 의한 전달과 외부 상태의 변경
매개변수는 함수 내부에서 변수와 동일하게 취급된다. 따라서 매개변수도 타입에 따라 값에 의한 전달, 참조에 의한 전달 방식을 그대로 따른다.
따라서 함수 내부에서 객체 타입의 매개변수를 다룰 때는 조심해야 한다. 객체의 변경을 추적하려면 옵저버 패턴 등을 통해 객체 참조를 공유하는 추가 대응이 필요하다.
혹은 객체를 불변 객체로 만드는 방법도 있다. 객체의 깊은 복사를 통해 새로운 객체를 생성하고 재할당을 통해 교체한다. 이를 통해 부수 효과를 없애는 것이다. 이처럼 외부 상태를 변경하지 않고 외부 상태에 의존하지 않는 함수를 순수 함수라 한다. 순수 함수를 통해 부수 효과를 최대한 억제하여 오류를 피하고 프로그램의 안정성을 높이려는 프로그래밍 패러다임을 함수형 프로그래밍이라 한다.
12.7 다양한 함수의 형태
12.7.1 즉시 실행 함수
즉시 실행 함수는 함수 정의와 동시에 즉시 호출되는 함수를 말한다. 단 한번만 호출되며 다시 호출할 수 없다.
일반적으로 익명 함수를 사용하고, 반드시 그룹 연산자 (…)로 감싸야 한다.
12.7.2 재귀 함수
재귀 함수는 재기 호출을 수행하는 함수를 말한다. 함수 표현식으로 정의한 함수 내부에서는 함수 이름은 물론 함수를 가리키는 식별자로도 자기 자신을 재귀할 수 있다. 단, 함수 외부에서 함수를 호출할 때는 반드시 함수를 가리키는 식별자로 해야 한다. 그리고, 스택 오버플로를 막기 위해 반드시 탈출 조건을 설정해야 한다.
12.7.3 중첩 함수
함수 내부에 정의된 함수를 중첩 함수 또는 내부 함수라 한다. 그리고 중첩 함수를 포함한 함수를 외부 함수라 한다. 중첩 함수는 외부 함수 내부에서만 호출할 수 있으며, 일반적으로 외부 함수를 돕는 헬퍼 함수의 역할을 한다.
12.7.4 콜백 함수 ⭐⭐⭐⭐
함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수를 콜백 함수라고 하며, 매개변수를 통해 함수 외부에서 콜백 함수를 전달받은 함수를 고차 함수라고 한다. 즉, 고차 함수는 콜백 함수를 자신의 일부분으로 합성한다. 콜백 함수는 고차 함수에 의해 호출되며 이때 고차 함수는 필요에 따라 콜백 함수에 인수를 전달할 수 있다.
콜백 함수는 함수형 프로그래밍 패러다임뿐아니라 비동기 처리에 활용되는 중요한 패턴이다.
콜백 함수는 배열 고차 함수에서도 사용되는 중요한 개념이다.
12.7.5 순수 함수와 비순수 함수
순수 함수 - 어떤 외부 상태에 의존하지도 않고, 변경하지도 않는 부수 효과가 없는 함수 ㄴ 동일한 인수가 전달되면 언제나 동일한 값을 반환하는 함수
비순수 함수 - 외부 상태에 의존하고, 변경하는 부수 효과가 있는 함수
⭐⭐⭐
함수형 프로그래밍은 순수 함수와 보조 함수의 조합을 통해 외부 상태를 변경하는 부수 효과를 최소화해 불변성을 지향하는 프로그래밍 패러다임이다. 로직 내 존재하는 조건문과 반복문을 제거해서 복잡성을 해결하며, 변수 사용을 억제하거나 생명주기를 최소화해 상태 변경을 피해 오류를 최소화하는 것을 목표로 한다. 결국, 함수형 프로그래밍은 순수 함수를 통해 부수 효과를 최대한 억제해 오류를 피하고 프로그램의 안정성을 높이려는 노력의 일환이다.
Last updated
Was this helpful?