해당 포스팅은 위키북스의 "모던 자바스크립트 Deep Dive"라는 책을 독학하며 기록하는 글입니다.

함수란?

함수는 자바스크립트에서 가장 중요한 핵심 개념으로 '일련의 과정을 문으로 구현하고 코드 블록으로 감싼 하나의 실행 단위'라고 한다.

함수는 함수 내부로 입력을 전달받는 변수인 매개변수, 입력인 인수, 출력인 반환값을 가지고 있다. 또한 함수는 함수 정의를 통해 생성되며 호출을 통해 실행된다.

이상적인 함수는 한 가지 일만 해야 하며, 가급적 작게 만들어야 한다.

함수를 사용하는 이유는 다음과 같다.

  1. 코드의 재사용
  2. 유지보수의 편의성(코드의 신뢰성)
  3. 코드의 가독성

함수 리터럴

함수는 객체 타입의 값이다. 따라서 리터럴을 통해서 생성할 수 있으며, 리터럴은 function키워드, 함수 이름, 매개변수목록, 함수몸체로 이루어져 있다.

var f = function add(x, y) {
  return x + y;
};
//add는 함수이름, x와 y는 매개변수목록, 중괄호로 묶인 것은 함수 몸체이다.

함수 이름은 생략할 수 있으며, 이름이 있으면 기명함수, 없으면 익명함수라 한다.


함수 정의

함수를 정의하는 방법에는 4가지가 있으며 다음과 같다.

  1. 함수 선언문
    함수 선언문은 함수의 이름을 생략할 수 없으며 표현식이 아닌 문이기 대문에 변수에 할당할 수 없다.

    하지만 아래의 코드와 같이 할당이 가능한 것처럼 보이는데 이는 자바스크립트 엔진이 코드의 문맥에 따라 해석을 달리 하기 때문이다.(결국 가능하다는 말이다.)

    자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당한다.(식별자가 명시되어 있지 않은 경우에만) 또한 함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출한다. 위의 함수를 호출하기 위해서는 add(2, 5)가 아니라 f(2, 5)를 해야 된다는 말이다.

var f = function add(x, y) {
  return x + y;
};
  1. 함수 표현식
    앞에서 언급했듯이 자바스크립트의 함수는 객체 타입의 값이다. 하지만 자바스크립트의 함수는 값처럼 변수에 할당할 수도 있고 프로퍼티 값이 될 수도 있으며 배열의 요소가 될 수도 있다. 이처럼 값의 성질을 값는 객체를 일급 객체라 한다.

    함수 표현식의 함수 리터럴은 아래와 같이 함수 이름을 생략하는 것이 일반적이다.

    함수 선언문은 "표현식이 아닌 문"이고, 함수 표현식은 "표현식인 문"이다. 이는 생성시점에 있어서 중요한 차이가 있다. 함수 선언문은 변수 호이스팅과 마찬가지로 런타임이전에 생성되어 정의되기 때문에 코드상에서 함수 선언문이 호출보다 뒤에 있어도 사용할 수 있다. 하지만 함수 표현식은 런타임에 변수에 함수를 할당하면서 이루어지면서 생성되기 때문에 코드상에 호출보다 뒤에 있으면 에러가 난다.

var f = function(x, y) {
  return x + y;
};
  1. Function 생성자를 이용한 함수

    생략

  2. 화살표 함수
    ES6에서 도입된 화살표 함수는 function키워드 대신 =>를 사용해 좀 더 간략한 방법으로 함수를 선언할 수 있으며 항상 익명 함수로 정의한다.

    하지만 화살표 함수는 생성자 함수로 사용할 수 없으며, 기존 함수와 this바인딩 방식이 다르고 prototype 프로퍼티가 없으며 arguments 객체를 생성하지 않는다.

var f = (x, v) => x + y;

함수 호출

함수를 실행하기 위해 필요한 값을 함수 외부에서 함수 내부로 전달할 필요가 있는 경우, 매개변수를 통해 인수를 전달한다. 인수는 함수를 호출할 때 지정하며, 개수와 타입에 제한이 없다.

매개변수로 전달되는 값들은 각 값들에 따라 이전 시간에 배운 값에 의한 전달, 참조에 의한 전달을 따른다. 즉, 값에 의해 전달되면 함수 외부에 영향을 끼치지 않지만 참조에 의해 전달되면 함수 내부의 활동이 외부에 영햘을 끼친다.

또한 함수는 매개변수의 개수와 인수의 개수가 일치하는지 체크하지 않으며 다음의 규칙을 따른다.

  1. 매개변수 > 인자
    인수가 할당되지 않은 매개변수의 값은 undefined
  2. 매개변수 < 인자
    넘치는 인자는 무시, 사용되지 않으나 암묵적으로 arguments객체의 프로퍼티로 보관된다.

함수는 return 키워드와 표현식으로 이뤄진 반환문을 사용해 실행 결과를 함수 외부로 반환할 수 있다. return의 역할은 다음과 같으며, 만약 반환값이 없다면 암묵적으로 undefined가 반환된다.

  1. 함수의 실행을 중단하고 함수 몸체를 탈출, 이후의 문들은 무시
  2. 뒤에 오는 표현식을 평가해 반환

다양한 함수의 형태

  1. 즉시 실행 함수
    함수 정의와 동시에 즉시 호출되는 함수를 즉시 실행 함수라고 하며, 단 한 번만 호출되며 다시 호출할 수 없다.
    즉시 실행 함수는 ()로 감싸며 함수의 작성 끝에 ()을 붙혀 즉시 실행임을 명시한다. 다음의 사용법을 보자.
(function add() {
  console.log("즉시 실행 함수입니다.");
}());
  1. 재귀 함수
    재귀 함수란 자기 자신을 호출하는 함수를 뜻한다. A함수안에 A함수를 호출하는 문이 존재하며, 이 경우 반드시 함수를 빠져나가는 기저사례를 포함하고 있어야 한다.
function countdown(x) {
  if(x <= 0) return;  //기저사례
  console.log(x);
  countdown(x-1);
};

countdown(5);  //5, 4, 3, 2, 1 출력
  1. 중첩 함수
    함수 내부에 정의된 함수를 중첩 함수, 또는 내부 함수라고 부른다.

    ES6전에는 함수는 항상 코드의 최상위, 또는 다른 함수 내부에서만 정의할 수 있었으나 ES6부터는 다양한 코드 블록안에서 정의할 수 있게 되었다.

    하지만 이는 호이스팅으로 인하여 혼란을 가져올 수 있으며 가급적 사용을 피하는 것이 좋다.

  2. 콜백 함수
    함수 내에서 사용된다는 점에서 중첩 함수와 비슷하다고 느낄 수 있으나 다르다.

    함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수를 콜백 함수라 하며, 이러한 콜백 함수를 전달받은 함수를 고차 함수라 한다.

    따라서 콜백 함수는 고차 함수에 의해 호출이 되며, 이때 고차 함수는 필요에 따라 콜백 함수에 인수를 전달 할 수 있다. 콜백 함수에 대해서는 뒤에 자세하게 알아보도록 하자.

  3. 순수 함수와 비순수 함수
    순수 함수는 어떤 외부 상태에 의존하지 않으며, 외부 상태를 변경하지도 않는 함수이다.

    비순수 함수는 순순 함수와 다르게 외부 상태에 의존하거나 외부 상태를 변경하는 함수이다.

profile
I Will be Relaxed Person

0개의 댓글