자바스크립트 완벽가이드 8장에 해당하는 부분이고, 읽으면서 자바스크립트에 대해 새롭게 알게된 부분만 정리한 내용입니다.
Function()
생성자의 특징
const scope = 'global';
function constructFunction() {
const scope = 'local';
return new Function('return scope');
}
constructFunction()(); // ReferenceError: scope is not defined
이
Function()
생성자는 전역 스코프를 사용하는eval()
이고 자신만의 비공개 스코프에 새 변수와 함수를 정의한다고 생각하면 된다. 이 생성자를 사용할 일은 아마 없을 것이다.
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))
앞에서본 합성과 부분 적용을 위한 함수들을 만들어 함수형 프로그래밍을 할 수 있다.
→ 클로저를 사용하여 외부에서 그 값에 접근할 수 없게 만들고, 함수를 통해서만 값을 변경하여 불변성을 지킴.