[TIL / Deep Dive] 함수

Changyun Go·2022년 2월 21일
0
post-thumbnail

「모던 자바스크립트 Deep Dive」를 읽고 새롭게 알게 된 내용

변수 선언과 함수 정의

변수는 선언(declaration)이지만 함수는 정의(definition)한다고 표현한다.

  • 선언은 메모리 위치를 가리키지만 값을 포함하지 않는다.
  • 정의는 유효한 값을 할당한다.

함수 선언문과 표현식

함수 리터럴을 변수에 할당하거나 피연산자로 사용하면 표현식으로 해석된다.

(function bar() { console.log('bar'); });
bar(); // ReferenceError: bar is not defined

함수 이름은 함수 몸체 내에서만 참조할 수 있기 때문에 bar 함수를 호출할 수 없다.

function foo() { console.log('foo'); }
foo(); // foo

단, 함수 선언문은 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당한다. → 함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출하는 것이다.

함수 호이스팅

console.dir(add); // ƒ add(x, y)
console.log(add(2, 5)); // 7

function add(x, y) {
  return x + y;
}

함수 선언문으로 함수를 정의하면 런타임 이전에 함수 객체가 먼저 생성되는 함수 호이스팅이 발생한다.

console.dir(sub); // undefined
console.log(sub(2, 5)); // TypeError: sub is not a function

var sub = function (x, y) {
  return x - y;
};

함수 표현식은 함수 호이스팅이 아닌 변수 호이스팅이 발생하여 할당문이 실행되는 시점에 함수 객체가 된다. → 함수를 호출하기 전에 함수를 선언해야 한다는 규칙이 준수된다.

때문에 함수 선언문 대신 함수 표현식 사용이 권장된다.

매개변수와 인수

  • 자바스크립트의 함수는 매개변수와 인수의 개수가 일치하는지 확인하지 않는다.
  • 자바스크립트는 동적 타입 언어다. 따라서 매개변수의 타입을 사전에 지정할 수 없다.

그래서 함수를 정의할 때 적절한 인수가 전달되었는지 확인해야 한다.

function add(x, y) {
  if (typeof x !== 'number' || typeof y !== 'number') {
    throw new TypeError('인수는 모두 숫자 값이어야 합니다.');
  }

  return x + y;
}

console.log(add(2));        // TypeError: 인수는 모두 숫자 값이어야 합니다.
console.log(add('a', 'b')); // TypeError: 인수는 모두 숫자 값이어야 합니다.

인수가 전달되지 않은 경우에는 단축 평가나 매개변수 기본값을 사용해 매개변수에 기본값을 할당할 수 있다.

// 단축 평가 사용
function add(a, b, c) {
  a = a || 0;
  b = b || 0;
  c = c || 0;
  return a + b + c;
}
// 매개변수 기본값 사용
function add(a = 0, b = 0, c = 0) {
  return a + b + c;
}

console.log(add(1, 2, 3)); // 6
console.log(add(1, 2)); // 3
console.log(add(1)); // 1
console.log(add()); // 0

매개변수의 개수

  • 매개변수는 코드를 이해하는 데 방해되는 요소이므로 적을수록 좋다.
  • 3개 이상 필요할 경우 객체를 인수로 전달하는 것이 좋다.

다양한 함수의 형태

즉시 실행 함수

즉시 실행 함수 내에 코드를 모아 두면 혹시 모를 변수나 함수 이름의 충돌을 방지할 수 있다.

재귀 함수

stack overflow의 위험성이 있으므로 가독성이 더 우수한 경우에만 반복문 대신 재귀 함수를 사용하는 것이 좋다.

콜백 함수

repeat(5, function (i) {
  if (i % 2) console.log(i);
}); // 1 3

콜백 함수가 고차 함수 내부에만 호출된다면 보통 익명 함수 리터럴로 전달한다.

  • 다른 곳에서도 호출할 필요가 있거나 자주 호출될 경우 외부에서 정의한다.

외부 상태의 변경

객체 타입 인수는 함수에서 참조 값을 통해 객체를 변경할 경우 원본이 훼손되는 side effect가 발생한다.

  • 함수가 외부 상태를 변경하면 상태 변화를 추적하기 어려워진다.

해결 방법

deep copy를 통해 객체를 불변 객체(immutable object)로 만들어 사용한다.

순수 함수와 함수형 프로그래밍

외부 상태를 변경하지 않고 외부 상태에 의존하지도 않는 함수를 순수 함수(pure function)라 하며, 이러한 불변성(immutability)을 지향하여 오류를 피하고 프로그램의 안정성을 높이는 것을 함수형 프로그래밍이라 한다.

Reference


0개의 댓글