JS编程建议——74:使用高阶函数

建议74:使用高阶函数
高阶函数作为函数式编程众多风格中的一项显著特征,经常被使用。实际上,高阶函数即对函数的进一步抽象。高阶函数至少满足下列条件之一:
接受函数作为输入。
输出一个函数。
在函数式语言中,函数不但是一种特殊的对象,还是一种类型,因此函数本身是一个可以传来传去的值。也就是说,某个函数在刚开始执行的时候,总可以送入一个函数的参数。传入的参数本身就是一个函数。当然,这个输入的函数相当于某个函数的另外一个函数。当函数执行完毕之后,又可以返回另外一个新的函数,这个返回函数取决于return fn(){...}。上述过程出现3个不同的函数,分别有不同的角色。要达到这样的应用目的,需要把函数作为一个值来看待。
JavaScript不但是一门灵活的语言,而且是一门精巧的函数式语言。下面看一个函数作为参数的示例。
document.write([2,3,1,4].sort()); //"1,2,3,4"
这是最简单的数组排序语句。实际上Array.prototype.sort()还能够支持一个可选的参数“比较函数”,其形式如sort(fn)。fn是一个函数类型的值,说明这里应用到高阶函数。再如,下面这个对日期类型排序的sort()。
// 声明3个对象,每个对象都有属性id和date
var a = new Object();
var b = new Object();
var c = new Object();
a.id = 1;
b.id = 2;
c.id = 3;
a.date = new Date(2012,3,12);
b.date = new Date(2012,1,15);
c.date = new Date(2012,2,10);
// 存放在arr数组中
var arr = [a, b, c];
//开始调试,留意id的排列是按1、2、3这样的顺序的
arr.sort(
function (x,y) {

return x.date-y.date; 

}
);
//已经对arr排序了,发现元素顺序发生变化,id也发生变化。排序是按照日期进行的
在数组排序的时候就会执行“function (x,y) {return x.date-y.date; }”这个传入的函数。当没有传入任何排序参数时,默认当x大于y时返回1,当x等于y时返回0,当x小于y时返回–1。
除了了解函数作为参数使用外,下面再看看函数返回值作为函数的情况。定义一个wrap函数,该函数的主要用途是产生一个包裹函数。
function wrap(tag) {

var stag = '<' + tag + '>';
var etag = '</' + tag.replace(/s.*/, '') + '>';
return function(x) {
    return stag + x + etag;
}

}
var B = wrap('B');
document.write(B('粗体字'));
document.write('
');
document.write(wrap('B')('粗体字'));
“var B = wrap('B');”这一语句已经决定了这是一个“加粗体”的特别函数,执行该B()函数就会产生 …内容…的效果。若是wrap('div'),就会产生

…内容…
的效果,若是wrap('li'),就会产生…内容……的效果,依此类推。wrap('B')返回到变量B的是一个函数。若不使用变量,wrap('B')也是合法的JavaScript语句,只要最后一个括号()前面的是函数类型的值即可。为什么stag + x + etag中的stag/etag没有输入也会在wrap()内部定义?因为warp作用域中就有stag、etag两个变量。如果从理论上描述这一特性,应该属于闭包方面的内容。
实际上,map()函数即为一种高阶函数,在很多的函数式编程语言中均有此函数。map(array, func)的表达式已经表明,将func函数作用于array中的每一个元素,最终返回一个新的array。应该注意的是,map对array和func的实现是没有任何预先的假设的,因此称为“高阶”函数。
function map(array, func) {

var res = [];
for(var i = 0, len = array.length; i < len; i++) {
    res.push(func(array[i]));
}
return res;

}
var mapped = map([1, 3, 5, 7, 8], function(n) {

return n = n + 1;

});
print(mapped); //2,4,6,8,9
var mapped2 = map(["one", "two", "three", "four"], function(item) {

return "(" + item + ")";

});
print(mapped2);(one), //(two),(three),(four),为数组中的每个字符串加上括号
mapped和mapped2均调用了map,但得到了截然不同的结果。因为map的参数本身已经进行了一次抽象,map函数做的是第二次抽象,所以高阶的“阶”可以理解为抽象的层次。

时间: 2024-09-20 12:10:30

JS编程建议——74:使用高阶函数的相关文章

JS编程建议——22:少用函数迭代

建议22:少用函数迭代ECMA-262v4为本地数组对象新增加了一个forEach方法.此方法遍历一个数组的所有成员,并且在每个成员上执行一个函数.在每个元素上执行的函数作为forEach()的参数传进去,并在调用函数时接收3个参数:数组项的值.数组项的索引.数组自身.例如: items.forEach(function(value, index, array){ process(value); }); forEach在Firefox.Chrome和Safari等浏览器中为原生函数.另外,for

JS编程建议——72:惰性载入函数

建议72:惰性载入函数惰性载入函数主要解决的问题也是兼容性,原理跟分支函数类似,下面是简单的示例.var addEvent = function(el, type, handle) { addEvent = el.addEventListener ? function(el, type, handle) { el.addEventListener(type, handle, false); } : function(el, type, handle) { el.attachEvent("on&q

JS编程建议——71:推荐分支函数

建议71:推荐分支函数分支函数解决的一个问题是浏览器之间兼容性的重复判断.解决浏览器之间的兼容性的一般方式是使用if逻辑来进行特性检测或能力检测,根据浏览器不同的实现来实现功能上的兼容,这样做的问题是,每执行一次代码,可能都需要进行一次浏览器兼容性方面的检测,这是没有必要的.能否在代码初始化执行的时候就检测浏览器的兼容性,在之后的代码执行过程中,就无须再进行检测了呢?答案是:能.分支技术就可以解决这个问题,下面以声明一个XMLHttpRequest实例对象为例进行介绍.var XHR = fun

JS编程建议——76:要重视函数节流

建议76:要重视函数节流比起非DOM交互,DOM操作需要更多内存和CPU时间.连续尝试进行过多的DOM相关操作可能会导致浏览器变慢甚至崩溃.函数节流的设计思想就是让某些代码可以在间断情况下连续重复执行,实现的方法是使用定时器对函数进行节流.例如,在第一次调用函数时,创建一个定时器,在指定的时间间隔后执行代码.当第二次调用时,清除前一次的定时器并设置另一个,实际上就是前一个定时器演示执行,将其替换成一个新的定时器.var processor = { timeoutId : null, //实际进行

Javascript 高阶函数使用介绍

  高阶函数(higher-order function)-如果一个函数接收的参数为或返回的值为函数,那么我们可以将这个函数称为高阶函数.众所周知,JavaScript是一种弱类型的语言:JavaScript的函数既不对输入的参数,也不对函数的输出值作强定义和类型检查,那么函数可以成为参数,也可以成为输出值,这就体现了JavaScript对高阶函数的原生支持. 一.参数为函数的高阶函数: ? 1 2 3 4 5 6 function funcTest(f){ //简易判断一下实参是否为函数 if

Javascript 高阶函数使用介绍_javascript技巧

高阶函数(higher-order function)-如果一个函数接收的参数为或返回的值为函数,那么我们可以将这个函数称为高阶函数.众所周知,JavaScript是一种弱类型的语言:JavaScript的函数既不对输入的参数,也不对函数的输出值作强定义和类型检查,那么函数可以成为参数,也可以成为输出值,这就体现了JavaScript对高阶函数的原生支持. 一.参数为函数的高阶函数: function funcTest(f){ //简易判断一下实参是否为函数 if((typeof f)=="fu

函数式接口、默认方法、纯函数、函数的副作用、高阶函数、可变的和不可变的、函数式编程和 Lambda 表达式 - 响应式编程 [Android RxJava2](这到底是什么)第三部分

本文讲的是函数式接口.默认方法.纯函数.函数的副作用.高阶函数.可变的和不可变的.函数式编程和 Lambda 表达式 - 响应式编程 [Android RxJava2](这到底是什么)第三部分, 太棒了,我们又来到新的一天.这一次,我们要学一些新的东西让今天变得有意思起来. 大家好,希望你们都过得不错.这是我们的 RxJava2 Android 系列的第三篇文章. 第一部分 第二部分 在这篇文章中,我们将讨论函数式的接口,函数式编程,Lambda 表达式以及与 Java 8 的相关的其它内容.这

Javascript中的高阶函数介绍_javascript技巧

这是一个有趣的东西,这或许也在说明Javascript对象的强大.我们要做的就是在上一篇说到的那样,输出一个Hello,World,而输入的东西是print('Hello')('World'),而这就是所谓的高阶函数. 高阶函数 高阶看上去就像是一种先进的编程技术的一个深奥术语,一开始我看到的时候我也这样认为的. Javascript的高阶函数 然而,高阶函数只是将函数作为参数或返回值的函数.以上面的Hello,World作为一个简单的例子. 复制代码 代码如下: var Moqi = func

JavaScript高阶函数的学习笔记

在Javascript中,有高阶函数的概念,因而很适合函数式编程.那神马是高阶函数呢?没有神马具体的定义,但高阶函数有两个显著的特征:.用函数做参数或返回一个函数. 函数作为参数 众所周知,函数是Javascript中的一等公民,不仅能被赋值,也能和普通变量一样,作为函数的参数. 如果你有Javascript的Web编程经验或者是一个前端开发者,就会经常碰到回调函数.在某个操作完成之后会被执行的函数就被称为回调函数.通常,回调函数都是匿名的,并作为最后一个函数传递给调用者. 由于Javascri