Maison  >  Article  >  interface Web  >  Compréhension détaillée du curry Javascript dans les questions d'entretien

Compréhension détaillée du curry Javascript dans les questions d'entretien

不言
不言avant
2019-01-24 09:51:302243parcourir

Cet article vous apporte une compréhension détaillée du curry Javascript dans les questions d'entretien. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il vous sera utile.

Question d'entretien : Implémenter add(1)(2)(3) //Résultat = 6, le cœur de la question concerne le currying de js

Parlons d'abord de ce qu'est le currying Currying, j'ai lu de nombreux articles sur le currying, mais je n'arrive toujours pas à comprendre. Par exemple : Currying transforme une fonction qui accepte plusieurs paramètres en une fonction qui accepte un seul paramètre (le premier paramètre de la fonction d'origine et). renvoie une nouvelle fonction qui accepte les paramètres restants et renvoie un résultat. La plupart des blogs disent cela et, pour être honnête, je suis confus.
Je crois comprendre que le curry est une méthode de collecte de paramètres. Si suffisamment de paramètres sont collectés, la fonction sera exécutée.

Listons les points clés avant la mise en œuvre
1. Collectez les paramètres (tout comme les questions d'entretien qui exécutent plusieurs paramètres plusieurs fois Oui, utilisez des fermetures
2. ou moins, par exemple, add(1)(2,3)(4)
3 Nous avons besoin de savoir quand les paramètres sont suffisants

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

Ecriture terminée accidentellement !

Mais je ne peux pas faire la une des journaux. J'ai promis une explication détaillée. Ensuite, analysons la plupart des codes d'implémentation du curry sur Internet

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

Ce n'est pas grave si vous le pouvez. Je ne comprends pas à première vue.
Analyse :
1. Curry reçoit également un paramètre (fn) C'est inévitable
2 Il renvoie une fonction et reçoit deux paramètres, fn.length et un tableau vide. .
Explication, comme je l'ai dit dans la version simplifiée que j'ai écrite, fn.length est utilisé pour déterminer si les paramètres ont été suffisamment collectés
Passer un tableau vide en tant que paramètre est en fait une implémentation de fermeture, utilisée pour. collecter des paramètres.
3. Il y a un jugement trinoculaire à l'intérieur. Cela a l'air sophistiqué mais pas si compliqué si le nombre de paramètres de jugement fn est 0, il n'est pas nécessaire de les collecter et d'exécuter fn directement. ,argList) I Si vous le dites clairement à voix haute, pouvez-vous simplement l'appliquer et l'utiliser partout ? À mon avis, c'est inutile. La raison pour laquelle il est utilisé est parce que argList est un tableau, et apply prend simplement en charge le fait que le deuxième paramètre est un tableau. Cela a l'air très génial.
4. Collectez les paramètres. Le nombre de paramètres fn n'est pas nul. Chaque fois que le nombre de paramètres de la fonction fn est collecté, diminuez-le de un jusqu'à ce qu'il soit égal à 0 et exécutez fn. J'en ai passé deux d'un coup et c'est mort.

Autre exemple : implémentation de la méthode bind

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)

Oui, la méthode bind utilise le curry.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer