不理解函数以及如何从函数式Javascript调用它
Not understanding function and how it is called from Functional Javascript
我刚开始阅读函数式JavaScript,并立即被介绍给一个我不理解的函数:
function splat(fun) {
return function(array) {
return fun.apply(null, array);
};
}
var addArrayElements = splat(function(x, y) { return x + y });
addArrayElements([1, 2]);
//=> 3
splat(function(x, y) { return x + y })
如何工作。它是用数组[1,2]
调用的,但似乎调用splat
中的匿名函数需要两个参数,而不是一个数组。
将console.log(fun)
放在此代码的第 2 行表明fun
是整个匿名function(x, y) { return x + y }
。 console.log(array)
后return function(array) {
显示数组[1, 2]
。那么array
从何而来呢?
多谢。
在不使用 .apply
方法的情况下,查看此函数的编写方式可能更简单:
function splat(fun) {
return function(array) {
return fun(array[0], array[1]);
};
}
首先,你调用 splat,给它传递一个函数:
var add = function(x,y){ return x + 1 };
var ff = splat(add);
在这一点上,ff 指的是 function(array)
函数,这意味着它是一个单参数函数。私有变量fun
是指add
函数。
现在,您调用 ff 传递其一个参数
ff([1,2]);
它使用数组中的值来调用带有两个参数的fun
return fun(array[0], array[1]);
这与真实示例之间的唯一区别是,apply
方法允许您使用任何参数数组长度,而不是像我那样硬编码特定长度 (2(。
//Every time we call this function, we get another one back
function splat(fun) {
return function(array) { // <-- this one will be returned in splat();
return fun.apply(null, array);
};
}
//Step one, call splat, pass a function as parameter
var addArrayElements = splat(function(x, y) { return x + y });
/*
Get back a function that accepts an array, and will execute the function we just passed in on it
*/
// This will call the newly created function, func will be available because it's in a closure
addArrayElements([1, 2]);
最后一件事是,即使匿名函数接受两个参数,我们也调用 apply,以便它将绑定array[0] ==> x
和array[1] ==> y
这是一个高阶函数的示例。这是一个将函数作为参数并返回函数而不仅仅是常规值的函数(尽管函数在 Javascript 中">只是常规值"(。在这种情况下:
function splat(fun) {
splat
将函数作为其参数...
return function(array) {
。并返回一个接受数组的新函数...
return fun.apply(null, array);
。调用时调用第一个fun
函数,数组.applied
作为其参数。
因此,splat
采用一个需要多个参数的函数,并将其包装在一个接受参数数组的函数中。"splat"这个名字来自Ruby等语言,其中函数参数列表中的*
("splat"或"被压扁的错误"(将任意数量的参数累积到数组中。
var addArrayElements = splat(function(x, y) { return x + y });
addArrayElements
现在基本上是:
function (array) {
// closed over variable:
// var fun = function(x, y) { return x + y }
return fun.apply(null, array);
}
在这里,这是通过闭包实现的,闭包关闭并"保留"在新返回函数中传递给splat
的原始fun
。
addArrayElements = function(array) { fun.apply(null, array); };
但
它有一个闭包,其中其包含范围的变量上下文(创建匿名函数的splat
函数的上下文(仍然可见且可访问。
在 JavaScript 中,函数是一等对象,可以作为参数引用和传递,或者像本例中一样,通过闭包机制传递。
编辑:关于JavaScript和范围
在大多数语言中,默认情况下,变量是定义它们的范围的局部变量(通常是函数的本地符号表(。相比之下,在 JavaScript 中,只有当变量使用 var
关键字定义时才是局部变量;否则,该符号将在包含范围的链中回溯,直到隐式根对象(在 Web 浏览器的情况下为 window
. 即
function foo() { someVar = "bar"; }
foo();
alert(someVar); // shows "bar"
该符号不限于本地范围,已(有意或无意(泄漏到根范围。
更进一步:
function foo() {
var baz = function() {
someVar = "bar";
};
baz();
}
foo();
alert(someVar); // shows "bar"
但是,如果您在 foo 中声明一些 Var:
function foo() {
var someVar;
var baz = function() {
someVar = "bar";
};
baz();
alert("someVar in foo=" + someVar); // shows "bar"
}
foo();
alert("someVar in root=" + window.someVar); // shows "undefined"
请注意,在最后一个版本中,我需要使用 window.someVar 而不仅仅是 someVar,因为 someVar 从未被定义为根范围内的变量或根对象的属性,这导致了错误。
一种更实用的方法使用bind((,它足够短,你不再需要splat了,消除闭包总是很好的:
var addArrayElements = Function.apply.bind( function(x, y) { return x + y } , null );
addArrayElements([1, 2]); // === 3
- 从函数JavaScript返回不可变数组/对象
- 将对象传递给函数.JavaScript
- 如何定义const函数javascript(语法糖)
- 新的日期函数javascript
- TypeError:this.getAttribute不是一个函数-javascript
- 从函数javascript发送变量
- 扩展自容器函数Javascript
- 从内部函数javascript内部分配外部函数的对象
- 使用函数JavaScript中的函数
- 在这里使用回调函数(JavaScript)有什么好处吗
- 来自函数 Javascript 的 NaN 返回值 ||函数执行顺序
- 将“e”传递给一个新函数 - javascript
- 调用函数中的一个函数——Javascript
- 传递的变量不适用于我的函数-Javascript
- 如何将类方法设置为等于多个函数?-Javascript
- 显示php中的函数javascript
- 如何使用php代码创建函数Javascript弹出框
- 未调用的外部函数-javascript
- 如何在类中运行函数.Javascript
- 关闭mouseover上的一个函数——Javascript,jQuery