[자바스크립트 완벽가이드] - 함수

Lee Jeong Min·2022년 6월 1일
2

자바스크립트

목록 보기
9/17
post-thumbnail

자바스크립트 완벽가이드 8장에 해당하는 부분이고, 읽으면서 자바스크립트에 대해 새롭게 알게된 부분만 정리한 내용입니다.

함수 프로퍼티, 메서드, 생성자

Funciton() 생성자

Function() 생성자의 특징

  • 런타임에 자바스크립트 함수를 동적으로 생성하고 컴파일 할 수 있다.
  • 호출될 때마다 함수 바디를 분석하고 새 함수 객체를 생성한다. 루프나 자주 호출되는 함수 안에서 생성자를 호출하는 것은 효율적이지 않다. 중첩된 함수와 함수 표현식은 루프 안에 있더라도 매번 재 컴파일 되지 않는다.
  • 생성자가 만드는 함수는 어휘적(Lexical) 스코프를 사용하지 않는다는 점이다. 생성자가 만드는 함수는 항상 최상위 함수로 컴파일 된다.
const scope = 'global';
function constructFunction() {
  const scope = 'local';
  return new Function('return scope');
}

constructFunction()(); // ReferenceError: scope is not defined

Function() 생성자는 전역 스코프를 사용하는 eval()이고 자신만의 비공개 스코프에 새 변수와 함수를 정의한다고 생각하면 된다. 이 생성자를 사용할 일은 아마 없을 것이다.

함수형 프로그래밍

higher-order function

higher-order function은 하나 이상의 함수를 인자로 받아 새 함수를 반환하는 함수이다.

// 인자를 f에 전달하고 f의 반환 값의 논리 부정을 반환하는 새 함수를 반환한다.
function not(f) {
  return function (...args) {
    const result = f.apply(this, args);
    return !result;
  };
}

const even = x => x % 2 === 0;
const odd = not(even);
console.log([1, 1, 3, 5, 5].every(odd)); // true

f와 g 두 함수를 받고 f(g())를 계산하는 새 함수 반환

// f와 g는 모두 h가 호출된 this값을 공유한다.
function compose(f, g) {
  return function (...args) {
    // f에는 g를 호출하고 난 후 결과값 하나만 전달하므로 call()을 썼고 g에는 값 배열을 전달하므로
    // apply()를 사용
    return f.call(this, g.apply(this, args));
  };
}

const sum = (x, y) => x + y;
const square = x => x * x;
console.log(compose(square, sum)(2, 3)); // 25

함수의 부분 적용

bind() 메서드는 지정된 컨텍스트에서 지정된 인자로 f를 호출하는 새 함수를 반환한다. 이는 함수를 객체에 결합하며 인자를 부분적으로 적용하는데(왼쪽에 있는 인자를 부분적으로 적용) 이와 반대로 동작하는 것을 코드로 만들어보자.

// 이 함수의 인자는 왼쪽에 전달된다.
function partialLeft(f, ...outerArgs) {
  return function (...innerArgs) {
    const args = [...outerArgs, ...innerArgs];
    return f.apply(this, args);
  };
}

// 이 함수의 인자는 오른쪽에 전달된다.
function partialRight(f, ...outerArgs) {
  return function (...innerArgs) {
    const args = [...innerArgs, ...outerArgs];
    return f.apply(this, args);
  };
}

// 이 함수의 인자는 템플릿 구실을 한다. 인자 리스트에서 정의되지 않은 값은
// 내부 세트의 값으로 채워진다.
function partial(f, ...outerArgs) {
  return function (...innerArgs) {
    const args = [...outerArgs];
    // console.log(args, innerArgs, outerArgs);
    let innerIndex = 0;
    // 인자를 순회하며 정의되지 않은 값을 내부 인자로 채운다.
    for (let i = 0; i < args.length; i++) {
      if (args[i] === undefined) args[i] = innerArgs[innerIndex++];
    }

    // 남은 내부 인자를 이어 붙인다.
    args.push(...innerArgs.slice(innerIndex));
    return f.apply(this, args);
  };
}

// 인자 세 개를 받는 함수
const f = function (x, y, z) {
  return x * (y - z);
};

console.log(partialLeft(f, 2)(3, 4)); // -2 (2 * (3-4))
console.log(partialRight(f, 2)(3, 4)); // 6 (3 * (4-2))
console.log(partial(f, undefined, 2)(3, 4)); // -6 (3 * (2-4))

앞에서본 합성과 부분 적용을 위한 함수들을 만들어 함수형 프로그래밍을 할 수 있다.
클로저를 사용하여 외부에서 그 값에 접근할 수 없게 만들고, 함수를 통해서만 값을 변경하여 불변성을 지킴.

profile
It is possible for ordinary people to choose to be extraordinary.

0개의 댓글