JavaScript 中的高阶函数
视频锁定
{$ currentTime | date:'mm:ss' $}
{$ timeLeft | date:'mm:ss' $}
Lisp 中,对列表有一个 map 操作,map 接受一个函数作为参数,map 对列表中的所有元素应用该函数,最后返回处理后的列表(有的实现则会修改原列表),我们在这一小节中分别用 JavaScript/C/Java 来对 map 操作进行实现,并对这些实现方式进行对比:
Array.prototype.map = function(func /*, obj */){
var len = this.length;
//check the argument
if(typeof func != "function"){
throw new Error("argument should be a function!");
}
var res = [];
var obj = arguments[1];
for(var i = 0; i < len; i++){
//func.call(), apply the func to this[i]
res[i] = func.call(obj, this[i], i, this);
}
return res;
}
我们对 JavaScript 的原生对象 Array 的原型进行扩展,函数 map 接受一个函数作为参数, 然后对数组的每一个元素都应用该函数,最后返回一个新的数组,而不影响原数组。由于 map 函数接受的是一个函数作为参数,因此 map 是一个高阶函数。我们进行测试如下:
function double(x){
return x * 2;
}
[1, 2, 3, 4, 5].map(double);
//return [2, 4, 6, 8, 10]
应该注意的是 double 是一个函数。根据上一节中提到的匿名函数,我们可以为 map 传递 一个匿名函数:
var mapped = [1, 2, 3, 4, 5].map(function(x){return x * 2});
print(mapped);
这个示例的代码与上例的作用是一样的,不过我们不需要显式的定义一个 double 函数,只需要为 map 函数传递一个“可以将传入参数乘 2 并返回”的代码块即可。再来看一个例子:
[
{id : "item1"},
{id : "item2"},
{id : "item3"}
].map(function(current){
print(current.id);
});
将会打印:
item1
item2
item3
也就是说,这个 map 的作用是将传入的参数(处理器)应用在数组中的每个元素上,而不关 注数组元素的数据类型,数组的长度,以及处理函数的具体内容。
在线练习
{$ activeFileHint $}