草庐IT

JavaScript curry

coder 2024-05-12 原文

我是 JavaScript 的新手,试图理解 Oreilly JavaScript Cookbook 中有关柯里化(Currying)的教程。

谁能用通俗易懂的语言逐步详细解释这个程序。请务必解释在程序的倒数第二行中传递的“null”参数。如果您能提供帮助,请提前致谢。

function curry(fn, scope) {
    scope = scope || window;
    var args = [];
    for (var i = 2, len = arguments.length; i < len; ++i) {
        args.push(arguments[i]);
    }
    return function() {
        var args2 = [];
        for (var i = 0; i < arguments.length; i++) {
            args2.push(arguments[i]);
        }
        var argstotal = args.concat(args2);
        return fn.apply(scope, argstotal);
    };
}

function diffPoint(x1, y1, x2, y2) {
    return [Math.abs(x2 - x1), Math.abs(y2 - y1)];
}

var diffOrigin = curry(diffPoint, null, 3.0, 4.0);
var newPt = diffOrigin(6.42, 8.0); //produces array with 3

最佳答案

如果您不介意某个建议,请从 Javascript:好的部分开始。随后阅读 Javascript Patterns 或 Secrets of the Javascript Ninja 以获得更高级的技术。食谱更多地是针对问题的固定解决方案,而不是一种学习资源。

Matt Ball 很好地解释了发生的事情。如果您是初学者,无论如何我都不会费心去弄清楚 curry 函数。除此之外,IMO 这个 curry 函数很糟糕。这就是我要改变的方式

// this is doing binding and partial function application, 
// so I thought bind was a more appropriate name
// The goal is that when you execute the returned wrapped version of fn, its this will be scope
function bind(fn, scope) {
  // arguments is an implicit variable in every function that contains a full list
  // of what was passed in. It is important to note that javascript doesn't enforce arity.
  // since arguments is not a true array, we need to make it one.
  // a handy trick for this is to use the slice function from array,
  // since it will take arguments, and return a real array.
  // we are storing it in a variable, because we will need to use it again.
  var slice =  Array.prototype.slice,
      // use slice to get an array of all additional arguments after the first two
      // that have been passed to this function.
      args = slice.call(arguments, 2);

  // we are returning a function mostly as a way to delay the execution.
  // as an aside, that this is possible in a mainstream language is a minor miracle
  // and a big part of why i love javascript.
  return function() {
    // since functions are objects in javascript, they can actually have methods.
    // this is one of the built in ones, that lets you execute a function in a different
    // context, meaning that the this variable inside the 
    // function will actually refer to the first argument we pass in.

    // the second argument we are jamming together the arguments from the first function
    // with the arguments passed in to this wrapper function, and passing it on to fn.
    // this lets us partially apply some arguments to fn when we call bind.
    return fn.apply(scope, args.concat(slice.call(arguments)));
  }
}

JavaScript 虽然很棒,但非常冗长。在定义绑定(bind)时不必要地重复 var 只会增加很多噪音。此外,没有必要像那样痛苦地构建一个真正的数组,slice 会接受参数并给你一个真正的数组。尤其是在我们使用它两次的情况下,我们实际上还是想切掉前两个参数。最后,当您申请并且您的第一个参数为 null 时,JavaScript 将为您申请全局对象。没有必要明确地这样做。

在我看来,我的 5 行函数主体从 o'reillys 的 11 行中剔除了废话,而且在我看来,它的可读性要高得多。

关于JavaScript curry ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5176313/

有关JavaScript curry的更多相关文章

随机推荐