자바스크립트에서 고차 함수 - Lee-hyuna/33-js-concepts-kr GitHub Wiki

자바스크립트의 특징 중 하나는 함수형 프로그래밍에 고차원 함수를 적용할 수 있다는 사실입니다. 고차 함수는 다른 함수를 인자로 사용할 수 있거나 함수의 결과로 반환하는 함수 입니다.

일급 클래스 함수

자바스크립트가 함수를 일급 시민으로 취급한다고 들었을 것입니다. 이것이 의미하는 것은 자바스크립트의 함수가 객체로 취급된다는 것입니다. 자바스크립트는 객체 타입을 가지고, 변수의 값으로 할당될 수 있으며, 다른 참조 변수처럼 전달되고 반환될 수 있습니다.

이 기본 함수는 함수형 프로그래밍과 관련하여 자바스크립트에 특별한 기능을 제공합니다. 함수는 객체이기 때문에 언어는 함수형 프로그래밍에 대한 매우 자연스러운 접근 방식을 지원합니다. 사실, 너무 자연 스럽기 때문에 생각조차 하지 않고 상요했을 것입니다.

함수를 인수로 사용

웹기반 자바스크립트 프로그래밍이나 프론트 엔드 개발을 많이 수행했다면 콜백을 사용하는 함수를 적용했을 것입니다. 콜백함수는 다른 모든 작업이 완료되면 작업이 끝날 때 실행되는 함수 입니다. 일반적으로 콜백 함수는 함수의 마지막 인자로 전달 됩니다. 종종 익명 함수로 인라인으로 정의 됩니다.

자바스크립트는 단일 스레드이므로 한 번에 하나의 작업만 발생하므로 발생하는 각 작업은 이 단일 스레드를 따라 대기합니다. 부모 함수의 나머지 작업이 완료된 후 실행될 함수를 전달하는 전략은 고차함수를 지원하는 언어의 기본 특성 중 하나 입니다. 비동기 동작을 허용하므로 결과를 기다리는 동안 스크립트를 계속 실행할 수 있습니다. 정의 되지 않은 시간 이후에 결과를 반환할 수 있는 리소스를 처리할 때는 콜백함수를 전달하는 기능이 중요합니다.

이 것은 스크립트가 Ajax 요청을 서버로 전송한 다음 도착할 때마다 응답을 처리해야하는 웹프로그래밍 환경에서 매우 유용합니다. 서버에서 네트워크 대기 시간이나 처리 시간에 대한 사전 정보는 존재하지 않습니다. Node.js는 콜백을 자주 사용하여 서버 리소스를 가장 효율적으로 사용합니다. 이 방법은 함수가 실행되기 전에 사용자 입력을 기다리는 앱의 경우에 유용합니다.

예를 들어, 버튼에 이벤트 리스너를 추가하는 간단한 자바스크립트 스니펫을 작성한다고 가정합니다.

<button id="clicker">So Clickable</button>

document.getElementById("clicker").addEventListener("click", function() {
  alert("you triggered " + this.id);
});

스크립트는 익명 인라인 함수를 사용하여 경고를 표시합니다. 그러나 별도로 정의된 함수를 쉽게 사용할 수 있었으며 정의된 함수를 addEventListener의 메소드에 전달 했습니다.

var proveIt = function() {
  alert("you triggered " + this.id);
};

document.getElementById("clicker").addEventListener("click", proveIt);

proveIt()이 아닌 proveIt을 addEventListener 함수에 전달했습니다. 괄호없이 이름으로 함수를 전달하면 함수 객체 자체가 전달됩니다. 괄호로 전달하면 해당 함수 실행 결과가 전달됩니다.

약간의 proveIt() 함수는 주위의 코드와 구조적으로 독립적이며, 트리거 된 요소의 'id'를 항상 반환합니다. 이 코드는 요소의 'id'로 경고를 표시하려는 모든 컨텍스트에 존재할 수 있으며 모든 이벤트 리스너에서 호출할 수 있습니다.

인라인 함수를 개별적으로 정의하고 명명된 함수로 대체할 수 있는 함수는 다양한 세계를 보여줄 수 있습니다.(기능을 제공합니다?) 외부 데이터를 변경하지 않는 순수 함수를 개발하고 매번 동일한 입력에 대해 동일한 결과를 반환하고, 시도하려고 할 때 어떤 애플리케이션에서나 일반적으로 사용할 수 있는 작고 타겟이 지정된 함수 라이브러리를 개발하는데 필요한 도구 중 하나를 가지게 됩니다.

결과값으로써 함수의 반환

자바스크립트는 함수를 인자로 취하는 것 외에도 함수가 결과적으로 다른 함수를 반환할 수 있게 합니다. 이것은 함수가 단순히 객체이기 때문에 다른 값과 동일한 값으로 반환될 수 있으므로 완벽하게 의미가 있습니다.

하지만 그 결과의 함수를 반환한다는 것은 무엇을 의미할까요? 함수를 다른 함수의 결과값으로 정의하면 템플릿으로 사용할 수 있는 함수를 만들어 새 함수를 만들 수 있습니다. 그것은 함수형 자바스크립트 마법의 또 다른 세계로 통하는 문을 열어 줍니다.

예를 들어, 'Millennials'의 특징에 관한 모든 기사를 읽는데 지쳤다고 상상해보세요. 그리고 'Millennials' 이라는 단어를 'Snake People'이라는 단어로 변경하고 싶다고 정합니다. 전달한 어떤 텍스트든 그 텍스트를 변경을 수행하는 함수를 호출하는 것일 수도 있습니다.

var snakify = function(text) {
  return text.replace(/millenials/ig, "Snake People");
};
console.log(snakify("The Millenials are always up to something."));
// The Snake People are always up to something.

하지만 이 한가지 상황에 대해서는 아주 구체적입니다. Baby Boomer에 대한 내용도 위와 동일합니다. Baby Boomer도 커스텀 함수를 적용 하고 싶습니다. 그러나 간단한 함수를 가지고, 작성한 코드를 반복할 필요가 없습니다.

var hippify = function(text) {
  return text.replace(/baby boomers/ig, "Aging Hippies");
};
console.log(hippify("The Baby Boomers just look the other way."));
// The Aging Hippies just look the other way.

원래 문자열의 케이스를 유지하기 위해 더 나은 것을 구현하려고 한다면? 이 부분을 적용하기 위해서는 두 개의 함수를 모두 수정 해야합니다. 이 부분은 번거로우며 코드를 좀 더 읽기 쉽게할 수 있습니다.

어떤 단어를 템플릿 함수에서 다른 용어로 replace할 수 있는 유연성이 있어야하며, 그 행동을 모든 커스텀 함수를 생성할 수 있는 기본 함수로 정의할 수 있습니다.

자바스크립트는 값 대신 함수를 반환할 수 있는 함수를 통해 해당 시나리오를 훨씬 편리하게 만들 수 있는 방법을 제공합니다.

var attitude = function(original, replacement, source) {
  return function(source) {
    return source.replace(original, replacement);
  };
};

var snakify = attitude(/millenials/ig, "Snake People");
var hippify = attitude(/baby boomers/ig, "Aging Hippies");

console.log(snakify("The Millenials are always up to something."));
// The Snake People are always up to something.
console.log(hippify("The Baby Boomers just look the other way."));
// The Aging Hippies just look the other way.

실제 작업을 하는 코드를 origin 문구와 replace의 문구를 사용하여 일부 attitude에서 입력 문자열을 수정하는데 필요한 모든 작업을 캡슐화하여 대양하고 확장 가능한 attitude 함수를 분리하는 것이 자바 스크립트가 값대신 함수를 반환할 수 있는 함수를 통해 해당 시나리오를 훨씬 편리하게 만드는 방법 입니다.

처음 두가지 주장으로 미리 채워진 attitude 함수에 대한 참조로 새로운 함수를 정의하면, 새로운 함수는 처음 두개의 인수로 미리 채워져 새 함수가 전달하는 인자를 가져와서 attitude에 의해 내부 함수의 source의 text로 사용할 수 있습니다.

여기서는 자바스크립트 함수가 원래 정의된 것과 동일한 개수의 인자를 전달했는지에 대한 여부를 신경쓰지 않는 다는 사실을 이용하고 있습니다. 인수가 없으면 함수는 누락된 인자를 undefined로 취급합니다.

반면에 추가되어진 인자는 이전에 입증한 방법으로 정의 되었을 때, 인자 하나(또는 그 이상) 정의되지 않은 채 다른 함수에서 반환된 함수에 대한 참조로, 추가된 인자는 나중에 전달 될 수 있습니다.

필요하다면 몇 번 더 검토해서 무슨일이 일어나고 있는지 충분이 이해해야합니다. 다른 함수를 반환하는 템플릿 기능을 만들고 있습니다. 그리고 나서 새로 반환된 함수, 즉 하나의 속성을 뺀 것을 템플릿 함수의 커스텀 함수로 정의하고 있습니다. 이렇게 만들어진 모든 기능은 템플릿 함수에서 동일한 작업 코드를 상속하지만, 다른 기본 인자를 사용하여 미리 정의할 수 있습니다.

이미 하고 있는 일입니다.

고차 함수는 자바스크립트의 작동 방식에 매우 기초적이기 때문에 이미 사용하고 있습니다. 익명함수나 콜백함수를 전달할 때마다 실제로 전달된 함수가 반환하는 값을 취하여 그것을 다른 함수에 대한 인자로 이용하는 것입니다.

함수가 다른 함수를 반환하는 기능은 자바스크립트의 편리함을 확장하여 공유 템플릿 코드로 특수한 작업을 수행하는 커스텀 함수를 만들 수 있습니다. 이 작은 함수들 각각은 원래 코드에서 개선된 부분을 상속 받을 수 있으므로 코드 중복으 피하고 소스를 깨끗하고 읽기 쉽게 유지할 수 있습니다.

추가로, 함수가 순수한지 확인하여 외부 값을 변경하지 않고 주어진 입력에 대해 항상 동일한 값을 반환하면 좋은 테스트 코드를 만들어 낼 수 있게 합니다. 코드 변경으로 템플릿 함수를 업데이트할 때 의존하고 있는 것은 없습니다.

프로젝트에서 이 접근 방식을 활용할 수 있는 방법에 대해 생각해보세요. 자바스크립트의 가장 큰 장점 중 하나는 이미 익숙한 코드와 함수적인 기술을 혼합할 수 있다는 것입니다. 몇가지 실험을 해보세요. 고차 함수로 약간의 작업을 수행하면 코드를 쉽게 향상시킬 수 있는지에 대해 더 알 수 있습니다.

⚠️ **GitHub.com Fallback** ⚠️