관련 권장사항: 자바스크립트 튜토리얼
apply(context,[arguments])
, call(context,param1,param2,...)
.커링(Currying)은 여러 매개변수를 받는 함수를 단일 매개변수(원래 함수의 첫 번째 매개변수)를 받는 함수로 변환하고, 나머지 매개변수를 받아 결과를 반환하는 새로운 함수를 반환하는 기술이다.
예를 들어, 여기에 전달된 매개변수(param1, params2,...)의 추가 및 합계를 처리하는 데 사용되는 함수인 add()
함수가 있습니다.
// 여기에 두 개의 매개변수 `x`, `y`가 있는 첫 번째 `add(x, y)` 함수가 있습니다. function add(x, y){ x + y를 반환합니다. } // `add()` 함수를 호출하고 두 개의 매개변수 `4`와 `6`을 제공합니다. 추가(4,6); // 컴퓨터 작동을 시뮬레이션하고 첫 번째 단계에서 첫 번째 매개변수 4를 전달합니다. 함수 추가(4, y){ 4 + y를 반환합니다. } // 컴퓨터 작동을 시뮬레이션하고 두 번째 단계에서 첫 번째 매개변수 6을 전달합니다. 함수 추가(4, 6){ 4 + 6을 반환합니다. }
add()
함수를 커리하면 어떤 모습일까요? 다음은 간단한 구현입니다:
// 커리된 add() 함수는 일부 매개변수를 허용할 수 있습니다 function add(x,y){ if (typeof y === '정의되지 않음') { 반환 함수(newy){ x + newy를 반환합니다. } } // 전체 애플리케이션 return x + y; } // 테스트 호출 console.log(typeof add(4)) // [Function] console.log(add(4)(6)); // 10 // 저장 함수를 생성할 수 있습니다. let saveAdd = add(4); console.log(saveAdd(6)); // 10
위의 간단한 카레 add()
함수에서 볼 수 있듯이 함수는 일부 함수를 수락한 다음 새 함수를 반환하여 나머지 함수를 계속 처리할 수 있습니다.
여기서는 공개 커링 함수를 작성하므로 함수를 작성할 때마다 내부에 복잡한 커링 프로세스를 구현할 필요가 없습니다.
//createCurry 함수 정의 function createCurry(fn){ var 슬라이스 = Array.prototype.slice, 저장된_args = 슬라이스.call(인수,1); 반환 함수 () { new_args = Slice.call(인수), args = 저장된_args.concat(new_args); return fn.apply(null,args); }}
위의 공개 커링 함수에서
arguments
실제 배열이 아니라 length
속성을 가진 객체이므로 arguments
실제 배열로 변환하는 데 도움이 되도록 Array.prototype
에서 slice
메서드를 빌려와 더 나은 작업을 용이하게 합니다.createCurry
함수를 처음 호출할 때, stored_args
변수는 첫 번째 매개변수를 제외한 매개변수를 보유합니다. 첫 번째 매개변수가 우리가 카레에 필요한 함수이기 때문입니다.createCurry
함수에서 반환된 함수를 실행하면 new_args
변수가 매개변수를 가져와서 배열로 변환합니다.stored_args
변수에 저장된 값에 액세스하고 new_args
변수의 값을 새 배열로 병합한 후 이를 args
변수에 할당합니다.fn.apply(null,args)
메서드가 호출되어 카레 함수를 실행합니다.// 일반 함수 add()를
테스트해 보겠습니다
.함수 추가(x, y){ x + y를 반환합니다. } // 새로운 함수를 얻기 위한 Curry var newAdd = createCurry(add,4); console.log(newAdd(6)); // 10 //또 다른 간단한 방법 console.log(createCurry(add,4)(6));// 10
물론 이는 두 매개변수의 커링에만 국한되지 않고 여러 매개변수도 가능합니다.
// 다중 매개변수 일반 함수 함수 add (a,b,c,d){ a + b + c + d를 반환합니다. } // 함수를 커리하여 새 함수를 얻습니다. 여러 매개변수를 마음대로 나눌 수 있습니다. console.log(createCurry(add,4,5)(5,6)) // 20 // 2단계 카레 let add_one = createCurry(add,5); console.log(add_one(5,5,5));// 20 let add_two = createCurry(add_one,4,6); console.log(add_two(6)); // 21
위의 예를 통해 제한 사항을 찾을 수 있습니다. 즉, 매개 변수가 두 개이든 여러 매개 변수이든 다음 공식과 같이 두 단계로만 실행할 수 있습니다.
더 유연해지고 싶다면:
어떻게 구현하나요?
위의 연습을 통해 우리가 만든 커리 함수에 특정 제한이 있음을 발견했습니다. 함수가 여러 단계로 실행될 수 있기를 바랍니다.
// 여러 단계로 실행될 수 있는 커리 함수 만들기 , 매개변수 수가 충족되면 실행합니다. // 함수식: fn(x,y,z,w) ==> fn(x)(y)(z)(w); createCurry = (fn,...params)=> { args = parsms []; let fnLen = fn.length; // 카레 함수의 매개변수 길이를 지정합니다. 반환 (...res)=> { // 범위 체인을 통해 이전 매개변수를 모두 가져옵니다. let allArgs = args.slice(0); // 후속 작업의 영향을 피하기 위해 클로저가 공유하는 args 매개변수를 심층 복사합니다(참조 유형). allArgs.push(...res); if(allArgs.length < fnLen){ // 매개변수 개수가 원래 함수의 매개변수 길이보다 작을 경우 createCurry 함수를 재귀적으로 호출합니다. return createCurry.call(this,fn,...allArgs); }또 다른{ // 매개변수 개수가 충족되면 함수 실행을 트리거합니다. return fn.apply(this,allArgs); } } } // 여러 매개변수가 있는 일반 함수 function add(a,b,c,d){ a + b + c + d를 반환합니다. } //커링 함수 테스트 let curryAdd = createCurry(add,1); console.log(curryAdd(2)(3)(4)); //
우리는 10년 넘게 유연한 커링 기능을 구현해 왔지만 여기서 또 다른 문제를 발견했습니다.
curryAdd(add,1,2,3,4)()
;add()
함수를 호출하면 된다고 말할 수도 있습니다. 이것도 단방향이지만 여기서는 매개변수 수를 만족하므로 이 상황을 처리합니다.여기서는 함수를 반환하기 전에 판단만 하면 됩니다:
let createCurry = (fn,...params)=> { args = parsms []; let fnLen = fn.length; // 카레 함수의 매개변수 길이를 지정합니다. if(길이 === _args.length){ //판단 추가. 처음으로 매개변수 개수가 충분하면 함수를 직접 호출하여 결과를 가져옵니다. return fn.apply(this,args); } 반환 (...res)=> { allArgs = args.slice(0); allArgs.push(...res); if(allArgs.length < fnLen){ return createCurry.call(this,fn,...allArgs); }또 다른{ return fn.apply(this,allArgs); } }}
위의 내용은 유연한 커리 함수라고 볼 수 있지만 여기서는 실행 시기를 제어할 수 없기 때문에 매개 변수 수가 충분하면 자동으로 실행되기 때문에 그다지 유연하지 않습니다. 실행을 제어할 수 있는 타이밍을 얻으려면 어떻게 해야 합니까?
여기서 함수 공식을 직접 설명하겠습니다.
// 매개변수가 충족되면 함수 호출 let createCurry = (fn,...params)=> { args = parsms []; let fnLen = fn.length; // 카레 함수의 매개변수 길이를 지정합니다. //물론 여기에서의 판단은 주석 처리되어야 합니다. 그렇지 않으면 처음으로 매개변수 수가 충분할 때 결과가 직접 실행됩니다. //if(length === _args.length){ // 판단을 추가합니다. 처음으로 매개변수 수가 충분하면 함수를 직접 호출하여 결과를 얻습니다. //return fn.apply(this,args); //} 반환 (...res)=> { allArgs = args.slice(0); allArgs.push(...res); // 여기서는 입력 매개변수가 0보다 큰지 판단합니다. 0보다 크면 매개변수 개수가 충분한지 판단합니다. // 여기서는 &&를 사용할 수 없습니다. &&를 사용하면 매개변수 개수가 충분할 때 결과가 실행됩니다. if(res.length > 0 || allArgs.length < fnLen){ return createCurry.call(this,fn,...allArgs); }또 다른{ return fn.apply(this,allArgs); } } } // 여러 매개변수가 있는 일반 함수 function add(a,b,c,d){ a + b + c + d를 반환합니다. } // 제어 가능한 커링 함수 테스트 let curryAdd = createCurry(add,1); console.log(curryAdd(2)(3)(4)); // 함수 console.log(curryAdd(2)(3)(4)()); // 10 console.log(curryAdd(2)(3)()); // 매개변수가 충분하지 않은 경우 NaN을 반환합니다.
관련 권장사항:
JavaScript 함수 커링에 대한 자세한 내용은 다음을 참조하세요. 중국 웹사이트의 PHP 기타 관련 기사에 주목해주세요!