
관련 권장사항: 자바스크립트 튜토리얼
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 기타 관련 기사에 주목해주세요!