Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 咖喱_Javascript - Fatal编程技术网

Javascript 咖喱

Javascript 咖喱,javascript,Javascript,我是一名JavaScript新手,试图了解Oreilly JavaScript食谱中关于咖喱的教程 请有人用通俗易懂的语言一步一步地详细解释一下这个程序。请确保解释在程序最后第二行传递的“null”参数。如果您能提供帮助,请提前向您表示感谢 function curry(fn, scope) { scope = scope || window; var args = []; for (var i = 2, len = arguments.length; i < le

我是一名JavaScript新手,试图了解Oreilly JavaScript食谱中关于咖喱的教程

请有人用通俗易懂的语言一步一步地详细解释一下这个程序。请确保解释在程序最后第二行传递的“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
功能咖喱(fn,范围){
范围=范围| |窗口;
var args=[];
for(变量i=2,len=arguments.length;i
函数
curry
允许您将函数
f
(函数
curry
的第一个参数)转换为作用域
c
(第二个参数),并带有可选的附加参数(其余参数)

这意味着此函数调用:

curry(func, scope);
返回一个函数
newFunc
,其调用:

var newFunc = curry(func, scope); // get the new function
newFunc(); // now invoke it
相当于:

scope.func();
所有这些的净效果是关键字在
func
中引用
scope
*


具体示例时间 假设
scope
是一个简单的JS对象,只有一个属性:

var scope = {name: 'Inigo Montoya'};
f
是一个函数,它想在
范围内使用一些值

function f() {
    return 'My name is ' + scope.name;
}
这样称呼它:

f(); // returns 'My name is Inigo Montoya'
var scope = { name: 'Inigo Montoya',
              sayIt: f_new }
sayIt(); // returns 'My name is Inigo Montoya'
嗯,这是一种方法。它起作用了

另一种方法是使用
curry
功能。
f
不必知道引用
scope
对象,
scope
现在是函数的调用上下文。现在该函数可以使用
这个
关键字了

function f_new() {
    return 'My name is ' + this.myName; // see the difference?
}

var sayIt = curry(f, scope);
现在,
sayIt
是一个不关心调用什么
scope
的函数。就像
sayIt
是在
scope
对象上定义的,如下所示:

f(); // returns 'My name is Inigo Montoya'
var scope = { name: 'Inigo Montoya',
              sayIt: f_new }
sayIt(); // returns 'My name is Inigo Montoya'
…除了这不是
范围
的实际定义
sayIt
就是这样。现在,我们可以调用
sayIt
,如下所示:

f(); // returns 'My name is Inigo Montoya'
var scope = { name: 'Inigo Montoya',
              sayIt: f_new }
sayIt(); // returns 'My name is Inigo Montoya'

还和我在一起吗? 呸。所有这些的要点是,在您的示例中,
null
被提供作为运行它的
diffOrigin
的作用域,因为它不关心作用域中的内容。行(在
curry
scope=scope | |窗口中
意味着,如果
范围
是一个伪值(即
null
是),那么新函数(
diffOrigin
在本例中)将在全局范围内执行:
将引用
窗口


这对你有意义吗?
*它被称为“调用上下文”

//定义curry()函数
功能咖喱(fn,范围){
//如果未传入任何范围,请将范围设置为window(默认全局对象)。
范围=范围| |窗口;
//将参数转换为普通数组,因为它不是一个数组。
//args将包含所有额外参数,不包括前2个(fn,作用域)
//循环从索引2开始,以i=2跳过fn和scope
var args=[];
for(变量i=2,len=arguments.length;i

在这种情况下,根本不使用
范围
参数<代码>范围
设置此
对象的内容。您正在使用的函数没有使用此,因此没有实际效果。当调用
fn.apply(scope,args)
时,就会设置作用域,这既可以设置要运行的作用域,也可以提供要传入的参数。

如果您不介意建议,请从Javascript开始:好的部分。接下来是Javascript模式,或者Javascript忍者的秘密,以获得更高级的技术。烹饪书更多的是用来解决问题,而不是学习资源

马特·鲍尔解释得很好。如果你是一个初学者,不管怎样,我都不会费力去弄清楚咖喱的功能。除此之外,在我看来,这种咖喱功能很糟糕。这就是我要改变它的方式

// 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虽然很棒,但却非常冗长。在定义绑定时不必要地重复var只会增加很多噪音。而且,没有必要费力地构建这样一个真正的阵列,sli