Heim  >  Artikel  >  Web-Frontend  >  Detailliertes Verständnis des Javascript-Currying in Interviewfragen

Detailliertes Verständnis des Javascript-Currying in Interviewfragen

不言
不言nach vorne
2019-01-24 09:51:302231Durchsuche

Dieser Artikel vermittelt Ihnen ein detailliertes Verständnis des Javascript-Currys in Interviewfragen. Ich hoffe, dass er Ihnen als Referenz dienen wird.

Interviewfrage: Implementiere add(1)(2)(3) //Ergebnis = 6, der Kern der Frage dreht sich um das Currying von js

Lassen Sie uns zunächst darüber sprechen, was Currying ist Currying, ich habe viele Artikel über Currying gelesen, aber ich kann es immer noch nicht herausfinden. Zum Beispiel: Currying wandelt eine Funktion, die mehrere Parameter akzeptiert, in eine Funktion um, die einen einzelnen Parameter akzeptiert (den ersten Parameter der ursprünglichen Funktion). gibt eine neue Funktion zurück, die die verbleibenden Parameter akzeptiert und ein Ergebnis zurückgibt. Die meisten Blogs sagen das, und um ehrlich zu sein, bin ich verwirrt.
Mein Verständnis ist, dass Curry eine Methode zum Sammeln von Parametern ist. Wenn genug gesammelt werden, wird die Funktion ausgeführt.

Lassen Sie uns die wichtigsten Punkte vor der Implementierung auflisten
1. Sammeln Sie Parameter (genau wie Interviewfragen, die mehrere Parameter mehrmals ausführen)
2 oder weniger, zum Beispiel add(1)(2,3)(4)
3 Wir müssen wissen, wann die Parameter ausreichen

        //如题
        //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))

Versehentlich mit dem Schreiben fertig sein!

Aber ich kann keine Schlagzeilen machen, da ich Ihnen eine ausführliche Erklärung versprochen habe. Lassen Sie uns die meisten Curry-Implementierungscodes im Internet analysieren

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, []);
}

Es ist in Ordnung, wenn Sie es nicht verstehen können Schauen wir uns den ersten Blick genauer an.
Analyse:
1. Curry erhält auch einen Parameter (fn)
2. Es gibt zwei Parameter zurück, fn.length und ein leeres Array .
Erklärung: Wie ich in der vereinfachten Version, die ich geschrieben habe, sagte, wird fn.length verwendet, um festzustellen, ob die Parameter ausreichend erfasst wurden.
Die Übergabe eines leeren Arrays als Parameter ist eigentlich eine Implementierung des Abschlusses Parameter sammeln.
3. Es sieht schick aus, ist aber nicht so kompliziert. Wenn die Anzahl der Parameter zur Beurteilung von fn 0 ist, besteht keine Notwendigkeit, sie zu sammeln und fn direkt auszuführen ,argList) I Wenn Sie es klar und deutlich sagen, können Sie es dann einfach anwenden und überall verwenden? Meiner Meinung nach ist es nutzlos, weil argList ein Array ist und apply nur unterstützt, dass der zweite Parameter ein Array ist.
4. Die Anzahl der Fn-Parameter ist nicht Null. Verringern Sie sie jedes Mal um eins, bis sie gleich 0 ist. Dies ist nicht so vielseitig wie das, was ich geschrieben habe. Ich habe zwei auf einmal passiert und es ist gestorben.

Ein weiteres Beispiel: Implementierung der Bind-Methode

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)

Ja, die Bind-Methode verwendet Currying.

Das obige ist der detaillierte Inhalt vonDetailliertes Verständnis des Javascript-Currying in Interviewfragen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen