>웹 프론트엔드 >JS 튜토리얼 >면접질문 속 자바스크립트 커링에 대한 자세한 이해

면접질문 속 자바스크립트 커링에 대한 자세한 이해

不言
不言앞으로
2019-01-24 09:51:302282검색

이 기사는 면접 질문에 대한 자세한 이해를 제공합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

인터뷰 질문: add(1)(2)(3) 구현 //결과 = 6. 질문의 핵심은 js의 커링에 관한 것입니다

먼저 커링이 무엇인지 이야기해 보겠습니다. currying 아직 변형에 대한 기사가 확실하지 않습니다. 예: Currying은 여러 매개변수를 허용하는 함수를 단일 매개변수(원래 함수의 첫 번째 매개변수)를 허용하는 함수로 변환하고 나머지 매개변수를 반환하는 것입니다. 그리고 결과를 반환하는 새로운 함수의 기술. 대부분의 블로그에서는 이렇게 말하고 있는데, 솔직히 말해서 저는 혼란스럽습니다.
카레는 매개변수를 수집하는 방식인 것으로 알고 있습니다.

구현 전 핵심 사항을 나열해 보겠습니다
1. 클로저를 사용하여 (여러 매개 변수를 여러 번 실행하는 인터뷰 질문과 마찬가지로) add(1)(2 ,3과 같이 매번 실행되는 매개 변수 수는 몇 개입니까? )(4)
3. 매개변수가 충분한지 알아야 합니다

        //如题
        //add(1)(2)(3)
        //逻辑应该是这样add(1)执行收集参数1继续执行收集参数2依次类推直到收集完毕。
       function curry(fn) {
            let arg = []; //用于收集参数
            //做一个闭包https://segmentfault.com/a/1190000017824877
            return function() {
                //每执行一次收集一次参数,为什么用concat是因为有时候后是多个参数(2,3)
                arg = arg.concat([...arguments]);
                //直到参数收集完成执行fn
                // 我们需要知道什么时候收集完了,条件就是curry参数fn的参数个数 fn.length
                //如果收集的参数个数大于等于fn的参数个数执行fn,如果没有递归执行
                if (arg.length >= fn.length) {
                    return fn(...arg)
                }
                // 参数没有收集完我们需要继续收集,递归
                return arguments.callee
            }
        }

        // 测试一下
        let testAdd = curry(add1)
        // console.log(testAdd(1)(2)(3))
        // console.log(testAdd(1, 2)(3))
        //console.log(testAdd(1)(2, 3))
실수로 작성이 완료되었습니다!

하지만 헤드라인을 장식하지 마세요. 약속대로 자세한 설명을 하도록 하겠습니다. 다음으로 인터넷에 있는 대부분의 커링 구현 코드를 분석해 보겠습니다.

function curry(fn) {
  function _c(restNum, argsList) {
    return restNum === 0 ?
      fn.apply(null, argsList) :
      function(x) {
        return _c(restNum - 1, argsList.concat(x));
      };
  }
  return _c(fn.length, []);
}
한 눈에 이해하지 못해도 괜찮습니다. 좀 더 살펴보세요.

분석:
1. Curry는 또한 매개변수(fn)를 받습니다. 2. 함수를 반환하고 fn.length와 빈 배열을 받습니다. 이것은 제가 작성한 단순화된 버전이기도 합니다. 그 후 fn.length를 사용하여 매개변수가 충분히 수집되었는지 확인합니다. 빈 배열을 매개변수로 전달하는 것은 실제로 매개변수를 수집하는 데 사용되는 클로저의 구현입니다.
3. 내부에 삼안 판정이 있습니다. 화려해 보이지만 그렇게 복잡하지는 않습니다. 판정 매개변수 개수가 0이면 이를 수집하여 fn을 직접 실행할 필요가 없습니다. argList), 아주 잘 이해합니다. 큰 소리로 말하면 어디에서나 사용할 수 있나요? 제 생각에는 쓸모가 없습니다. argList가 배열이고 Apply가 두 번째 매개 변수가 배열이라는 것을 지원하기 때문에 사용됩니다.
4. fn 매개변수 개수가 0이 아닙니다. fn 함수 매개변수 개수가 수집될 때마다 0이 될 때까지 1씩 줄여서 fn을 실행합니다. 한 번에 두 마리가 죽었습니다.

또 다른 예: 바인드 메소드 구현

Function.prototype.bind = function(context) {
            //返回一个绑定this的函数,我们需要在此保存this
            let self = this
                // 可以支持柯里化传参,保存参数
            let arg = [...arguments].slice(1)
                // 返回一个函数
            return function() {
                //同样因为支持柯里化形式传参我们需要再次获取存储参数
                let newArg = [...arguments]
                console.log(newArg)
                    // 返回函数绑定this,传入两次保存的参数
                    //考虑返回函数有返回值做了return
                return self.apply(context, arg.concat(newArg))
            }
        }

        // 搞定测试
        let fn = Person.say.bind(Person1)
        fn()
        fn(18)

예, 바인드 메소드는 커링을 사용합니다.

위 내용은 면접질문 속 자바스크립트 커링에 대한 자세한 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제