JavaScript 반 코 리 화

24985 단어 JavaScript
자 바스 크 립 트 의 함수 uncurrying 반 코 리 화 분석
코 리 화
커 리 화 는 부분 적 인 값 을 구 하 는 것 이 라 고도 부 르 는데 그 의 미 는 함수 에 단계별 로 파 라 메 터 를 전달 하 는 것 이다. 매번 파 라 메 터 를 전달 한 후에 파 라 메 터 를 응용 하고 더욱 구체 적 인 함수 로 돌아 가 남 은 파 라 메 터 를 받 아들 이 는 것 이다. 이 중간 에 다 층 과 같은 일부 매개 변수 함 수 를 삽입 하여 마지막 결 과 를 되 돌 릴 수 있다.따라서 코 리 화의 과정 은 점차적으로 인삼 을 전달 하고 함수 의 적용 범 위 를 점차적으로 좁 히 며 점차적으로 해답 을 구 하 는 과정 이다.제 다른 블 로 그 를 만 나 보 세 요. 자 바스 크 립 트 의 함수 currying 코 리 화 분석
반 코 리 화
반면, 반 코 리 화 작용 은 함수 의 적용 성 을 확대 하여 원래 특정 대상 으로 가지 고 있 던 기능 의 함 수 를 임 의 대상 에 게 사용 할 수 있 도록 한다. 즉, 다음 과 같은 주어진 함수 에 서명 하 는 것 이다.
obj.func(arg1, arg2)

함수 형식 으로 전환 하여 다음 과 같이 서명 합 니 다.
func(obj, arg1, arg2)

이것 이 바로 반 코 리 화의 형식화 묘사 다.
물론 전제 가 있 습 니 다. 함수 y 는 언어 적 으로 오리 유형 을 지원 하고 위 키 오리 유형 에 서 는 대상 의 유형 자체 가 아니 라 어떻게 사용 하 는 지 에 주목 하고 있다.오리 유형의 언어 를 사용 할 때, 이러한 함 수 는 임의의 유형의 대상 을 받 아들 일 수 있 으 며, 그것 의 걷 기와 부 르 는 방법 을 호출 할 수 있다. 에서 인용 해 야 합 니 다.
예 를 들 어 다음 의 간단 한 실현:
Function.prototype.uncurrying = function() { var that = this; return function() { return Function.prototype.call.apply(that, arguments); } }; function sayHi () { return "Hello " + this.value +" "+[].slice.call(arguments); } var sayHiuncurrying=sayHi.uncurrying(); console.log(sayHiuncurrying({value:'world'},"hahaha"));

설명:
  • uncurryingFunction 에 정 의 된 prototype 방법 이기 때문에 모든 함수 에 이 방법 을 사용 할 수 있다.호출 시: sayHiuncurrying=sayHi.uncurrying() 그래서 uncurrying 중의 this 함 수 를 가리 키 는 것 입 니 다.(일반 원형 방법 중의 sayHi 은 원형 대상 this 을 가리 키 는 것 이 아니 라 호출 대상 을 가리 키 는 것 이다. 여기 서 호출 대상 은 다른 함수 이 고 자바 script 에서 함수 도 대상 이다)
  • prototype call.apply(that, arguments)that 방법의 문맥 로 설정 한 다음 에 callarguments l 방법 에 전달 하고 앞의 예, cal 실제 가리 키 기 때문에 호출 thatsayHi 에 해당 한다.
  • sayHiuncurrying(arg1, arg2, ...), sayHi.call(arg1, arg2, ...) 함 수 는 sayHi.call(arg1, arg2, ...)call 의 상하 문 으로 간주 하고 arg1 등 남 은 매개 변 수 를 sayHi 에 게 전달 하기 때문에 마지막 으로 sayHi 에 해당 한다.
  • 따라서 arg2,...arg1.sayHi(arg2,...) 과 같다.

  • 마지막 으로 우리 가 거꾸로 보면 사실은 반 코 리 화 는 원래 sayHiuncurrying(obj,args) 의 형식 을 obj.sayHi(args) 으로 전환 시 켜 sayHi(args) 의 사용 범 위 를 일반화 시 킨 것 과 같다.더욱 추상 적 으로 표현 하면 sayHiuncurrying(obj,args) 반 코 리 화 는 원래 sayHi 호출 을 uncurryinging 형식의 호출 으로 전환 할 수 있다.x '가 x 또는 다른 대상 이 라 고 가정 하면 함수 의 사용 범 위 를 확대 한다.
    통용 반 코 리 화 함수
    위의 예 에서 x.y(z)y(x',z) 에 썼 는데 이것 은 그다지 좋 지 않다. 우 리 는 사실 uncurrying 을 하나의 함수 로 포장 할 수 있다.
    var uncurrying= function (fn) { return function () { var args=[].slice.call(arguments,1); return fn.apply(arguments[0],args); } };

    위의 이 함 수 는 매우 뚜렷 하고 직접적 이다.사용 시 호출 prototype 하고 기 존 함수 uncurrying 를 전송 합 니 다. 반 코 리 화 함 수 는 새로운 함 수 를 되 돌려 줍 니 다. 이 새 함수 가 받 은 첫 번 째 실 삼 은 uncurrying 의 문맥 로 연결 되 고 다른 매개 변 수 는 fn 에 매개 변수 로 전 달 됩 니 다.
    따라서 반 코 리 화 에 대한 더욱 통속 적 인 해석 은 함수 의 차용 일 수 있 고 함수 가 다른 대상 을 받 아들 일 수 있 으 며 차용 범 화 를 통 해 함수 의 사용 범 위 를 확대 할 수 있다.
    그래서 fn 더 흔히 볼 수 있 는 용법 은 자 바스 크 립 트 에 내 장 된 다른 방법 에 대한 차출 이다.
    텍스트 설명 이 비교적 복잡 합 니까? 아니면 코드 를 계속 보 시 겠 습 니까?
    var test="a,b,c"; console.log(test.split(",")); var split=uncurrying(String.prototype.split); //[ 'a', 'b', 'c' ] console.log(split(test,',')); //[ 'a', 'b', 'c' ]
    this 에 게 fn 구체 적 인 uncurrying, 즉 split=uncurrying(String.prototype.split), uncurrying 함수 에 fn 기능 을 가 집 니 다. 함수 호출 String.prototype.split 시 들 어 오 는 첫 번 째 매개 변 수 는 split 실 행 된 문맥 이 고 나머지 매개 변 수 는 원 String.prototype.split 함수 에 전달 되 는 것 과 같 습 니 다.
    예 를 하나 더 보 자.
    var $ = {}; console.log($.push); // undefined var pushUncurrying = uncurrying(Array.prototype.push); $.push = function (obj) { pushUncurrying(this,obj); }; $.push('first'); console.log($.length); // 1 console.log($[0]); // first console.log($.hasOwnProperty('length')); // true

    'jquery 라 이브 러 리 유사' 가 실 현 될 때 Array 를 빌 리 는 split(test,',') 방법 을 모방 했다.우 리 는 대상 이 split 방법 이 없다 는 것 을 알 고 있 기 때문에 String.prototype.split 되 돌아 가기 pushpush 를 빌려 처리 할 수 있 고 console.log(obj.push) 원생 의 배열 방법 (js 엔진) 으로 위조 배열 대상 의 length 속성 과 배열 구성원 을 유지 할 수 있다.
    같은 이치 로 우 리 는 계속 있 을 수 있다.
    var indexof=uncurrying(Array.prototype.indexOf); $.indexOf = function (obj) { return indexof(this,obj); }; $.push("second"); console.log($.indexOf('first')); // 0 console.log($.indexOf('second')); // 1 console.log($.indexOf('third')); // -1

    예 를 들 어 우리 가 자신의 라 이브 러 리 를 실현 할 때 어떤 방법 이 원생 과 유사 하 다 면 undefined 원생 방법 을 빌려 쓸 수 있다.
    우 리 는 Array 방법 push 도 할 수 있다. 예 를 들 어:
    var call= uncurrying(Function.prototype.call); var fn= function (str) { console.log(this.value+str); }; var obj={value:"Foo "}; call(fn, obj,"Bar!"); // Foo Bar!

    이렇게 하면 함수 도 일반적인 '데이터' 로 사용 할 수 있 고 함수 식 프로 그래 밍 이 있어 서 일부 라 이브 러 리 에서 이런 용법 을 자주 볼 수 있다.
    유 니 버 설 uncurrying 함수 의 진격
    위의 uncurrying 함 수 는 사고방식 에 비교적 부합 되 고 이해 하기 쉬 운 버 전 입 니 다. 다음 에 들 어가 서 몇 가지 다른 버 전 을 보 겠 습 니 다.
    우선, B 칸 이 조금 높 으 면 Function.prototype.call/apply 도 이렇게 쓸 수 있 습 니 다.
    var uncurrying= function (fn) { return function () { var context=[].shift.call(arguments); return fn.apply(context,arguments); } };

    물론 B 칸 을 더 올 려 야 한다 면 그 럴 수도 있 습 니 다.
    var uncurrying= function (fn) { return function () { return Function.prototype.call.apply(fn,arguments); } };

    시작 하 는 split 의 예 를 들 어 위의 고 B 격 함수 가 어떻게 작 동 하 는 지 보 세 요. uncurring uncurrying
  • 전송 uncurrying var split=uncurrying(String.prototype.split);, fn 은 split(test,','); 의 문맥 에 응 용 된 다음 에 새로운 함수 에 봉 하여 되 돌려 줍 니 다.
  • 새 함 수 를 되 돌려 주 고 String.prototype.split, 호출 시 fn, Function.prototype.call split
  • 그 다음 에 폐쇄 적 으로 특정 저장 split(test,','), arguments call [test,','] fn. call (arguments) fn Function. prototype. split. call (test, ',') '
  • 이 때문에 첫 번 째 매개 변수 apply 대상 은 의 문맥 로 설정 되 었 고 나머지 매개 변수 test 함수
  • 에 전달 되 었 다.
    이 를 통 해 알 수 있 듯 이 Function.prototype.split',' 에 비해 응용 split 한 후에 자동 으로 Function.prototype.call.apply(fn,arguments) 을 첫 번 째 매개 변수 와 나머지 매개 변수 로 나 누 어 각각 응용 하 는 것 과 같다.앞의 두 가지 표기 법 이 첫 번 째 매개 변 수 를 분리 하 는 절 차 를 줄 였 다.
    자, B 칸 의 향상 을 추구 하 는 길 은 끝 이 없다. 그러면 지금 은 절정 에 이 르 렀 다.
    var uncurrying=Function.prototype.bind.bind(Function.prototype.call);

    나 는 이 코드 를 처음 보 았 을 때 바로 어 지 러 워 서 감탄 을 금치 못 했다. 과연 자 바스 크 립 트 의 각종 기예 가 음탕 하구 나!!
    How it works!
    이 몇 개의 영어 단 어 를 많이 봤 군요. 하하, 다시 한 번 말씀 드 리 겠 습 니 다. 어떻게 일 하 는 지 보 겠 습 니 다.
    여기 서 함수 의 두 가지 원형 방법 fn.apply(arguments[0],args) 을 사 용 했 습 니 다. call 이 두 함수 arguments 는 두 부분 으로 분해 할 수 있 습 니 다. 첫 번 째 매개 변 수 는 모두 함수 로 설정 되 어 문맥 을 집행 하 는 데 사 용 됩 니 다. 나머지 매개 변 수 는 호출 함수 에 전 달 됩 니 다. 다른 점 은 arguments 즉시 응용 되 고 모든 매개 변 수 는 한 번 에 전 달 됩 니 다.그러나 Function.prototype.call 남 은 매개 변 수 는 호출 함수 에 순서대로 들 어 오고 실행 을 지연 시 킵 니 다. 그래서 Function.prototype.bind 는 코 리 화 된 것 입 니 다. 아, 멀 어 졌 습 니 다. 그러나 어쨌든 arguments 를 두 부분 으로 나 누 면 그들의 코드 는 이렇게 보 입 니 다.
    Function.prototype.call= function (scope,...args) { //   ECMAScript 6   ...         }; Function.prototype.bind= function (scope,...args) { //   ECMAScript 6   ...         }; 

    우선, 우 리 는 call 에서 자신 을 상 향 조정 할 수 있 습 니 다. bind 은 하나의 함수 이기 때문에 원형 함수 bid 를 호출 할 수 있 습 니 다. 이것 은 우리 가 bind 의 두 번 째 Function.prototype.bind 에 무엇 을 전달 하 든 첫 번 째 Function.prototype.bind 함수 의 첫 번 째 매개 변수 Function.prototype.bind.bind() 라 고 부 르 는 것 을 의미 합 니 다.
    var uncurrying=Function.prototype.bind.bind(Function.prototype.call);

    다음으로 전환:
    var uncurrying= function(){ return Function.prototype.bind.apply(Function.prototype.call) }

    ... 과 같다
    var uncurrying= function (fn) { return Function.prototype.call.bind(fn); };

    여기 서 bind 인상 용 bind, 우 리 는 bid 가 바 인 딩 되 고 새로운 함수 로 돌아 갈 것 이라는 것 을 알 고 있 습 니 다.,
    이것 은 다음 과 같다.
    var uncurrying= function (fn) { return function(scope,...args){ return fn.call(scope,...args); } };

    ECMAScript 6 에서 scope 나머지 인 자 를 가 져 오 겠 다 고 표 시 했 습 니 다. 이제 ES6 에 의존 하지 않도록 다시 쓰 겠 습 니 다.
    var uncurrying= function (fn) { return function(){ var args=[].slice.call(arguments,1); return fn.apply(arguments[0],args); } };

    아하, 우 리 는 지금 돌 아 왔 습 니 다. 위의 함 수 는 이미 앞의 '통용 반 코 리 화 함수' 와 같 습 니 다.
    그리고 우 리 는 지금 앞으로 나 아 간다.
    var bind = Function.prototype.bind; uncurryThis = bind.bind(bind.call); call = uncurryThis(bind.call);

    상기 코드 의 작용 은 call 에 대해 반 코 리 화 를 하 는 것 으로 알 수 있 듯 이 이것 은 바로 앞의 고 B 격 서법 의 변형 이다.
    마지막 으로 코드 를 한 소절 더 보 겠 습 니 다.
    var bind = Function.prototype.call.bind(Function.prototype.bind);

    아아, 이 코드 도 뼈 가 놀 라 워 보이 고 용모 가 비범 해 보이 는데..
    우 리 는 그것 을 계속 읽 을 수 있 는 버 전 으로 바 꾸 었 다.
    var bind = Function.prototype.call.bind(Function.prototype.bind); //       var bind= function (scope) { return function () { return scope.call(arguments); } }; //      ,   scope      Function.prototype.bind    var bind= function () { return Function.prototype.bind.call(arguments); }; //      , bind       bind(func, scope),          ,      var bind= function (func,scope) { return Function.prototype.bind.call(func,scope); }; //       var bind= function (func,scope) { return func.bind(scope); };

    테스트 코드:
    var bind = Function.prototype.call.bind(Function.prototype.bind); var context={foo:"bar"}; function returnFoo(){ return this.foo; } var amazing=bind(returnFoo,context); console.log(amazing()); // bar //                var bind2= function (func,scope) { return func.bind(scope); }; var amazing2=bind2(returnFoo,context); console.log(amazing2()); // bar

    위의 테스트 코드 는 원래 bind 와 우리 가 바 꾼 코드 를 호출 하고 테스트 결 과 는 모두 같은 bar 로 되 돌려 줍 니 다.
    이 글 은 여기까지 쓴 지 이미 오래 되 었 습 니 다. 친구 가 여 기 를 볼 수 있 을 지 모 르 겠 습 니 다.) 다음 에 마지막 으로 하나 더 보충 하 겠 습 니 다. 그 뜻 은?
    var slice = Function.prototype.call.bind(Array.prototype.slice);

    이것 은 말 그대로 ...Function.prototype.call 에 연결 시 키 고 전환 과정 을 알 수 있다.
    var slice2= function(){ return Function.prototype.call.apply(Array.prototype.slice); }; var slice2=function(fn) { return Array.prototype.slice.call(fn); }; var slice2=function() { return Array.prototype.slice.call(arguments[0],arguments[1],arguments[2]); };

    테스트 코드:
    var slice = Function.prototype.call.bind(Array.prototype.slice); console.log(slice([1,2,3],0,1)); // [ 1 ] console.log(slice2([1,2,3],0,1)); // [ 1 ] console.log(Array.prototype.slice.call([1,2,3],0,1)); // [ 1 ] 

    이것 도 var bind = Function.prototype.call.bind(Function.prototype.bind);, call, Array.prototype.slice 세 가지 방법 에 대해 많은 연습 을 한 셈 이다. 이 세 가지 방법 은 자 바스 크 립 트 함수 식 스타일 의 중요 한 기초 이다. 어린이 신발 들 이 상기 고 B 격 문 구 를 포장 하고 바 꿀 때 함수 변환 수학 문 제 를 풀 수 있 는 방법 이 있다.
     원문:http://www.cnblogs.com/zztt/p/4152147.html
     
    참고 자료: 자 바스 크 립 트 의 함수 currying 코 리 화 분석 자 바스 크 립 트 의 Function. prototype. bind () 방법 분석 원형 대상 중 this 에 대한 어 리 석 은 잘못된 인식 자 바스 크 립 트 의 재 미 있 는 반 코 리 화 기술

    좋은 웹페이지 즐겨찾기