1、简述
高阶函数似乎是一种先进编程的的技术。然而,并不是。
高阶函数其实就是将函数作为参数或者返回值的函数。其中作为参数的函数一般是回调函数。
2、例子
(1)最简单的例子
大家都熟悉数组的sort方法。
高阶函数
sort方法的参数就是一个函数(回调函数),这个回调函数决定了如何比较数组中的任意两个元素。
Array的sort方法源码实现(使用了插入排序和快速排序):
function ArraySort(comparefn) { // 使用款速排序算法 // 对于长度小于22的数组,使用插入排序算法 //判断comparefn是不是一个函数 var custom_compare = IS_FUNCTION(comparefn); function Compare(x, y) { // 假设comparefn(若存在的话)是一致的比较函数。 // 如果不是,则假设假设comparefn函数是任意的(通过ECMA 15.4.4.11) if(x === y) return 0; if(custom_compare) { // 不要直接调用comparefn以避免暴露内置的全局对象。. return comparefn.call(null, x, y); } x = ToString(x); y = ToString(y); if(x == y) return 0; else return x < y ? -1 : 1; }; //插入排序 function InsertionSort(a, from, to) { for(var i = from + 1; i < to; i++) { var element = a[i]; // Pre-convert the element to a string for comparison if we know // it will happen on each compare anyway. var key = (custom_compare || % _IsSmi(element)) ? element : ToString(element); // place element in a[from..i[ // binary search var min = from; var max = i; // The search interval is a[min..max[ while(min < max) { var mid = min + ((max - min) >> 1); var order = Compare(a[mid], key); if(order == 0) { min = max = mid; break; } if(order < 0) { min = mid + 1; } else { max = mid; } } // place element at position min==max. for(var j = i; j > min; j--) { a[j] = a[j - 1]; } a[min] = element; } } //快速排序 function QuickSort(a, from, to) { // 若数组长度小于22的话,使用插入排序。 if(to - from <= 22) { InsertionSort(a, from, to); return; } var pivot_index = $floor($random() * (to - from)) + from; var pivot = a[pivot_index]; // Pre-convert the element to a string for comparison if we know // it will happen on each compare anyway. var pivot_key = (custom_compare || % _IsSmi(pivot)) ? pivot : ToString(pivot); // Issue 95: Keep the pivot element out of the comparisons to avoid // infinite recursion if comparefn(pivot, pivot) != 0. a[pivot_index] = a[from]; a[from] = pivot; var low_end = from; // Upper bound of the elements lower than pivot. var high_start = to; // Lower bound of the elements greater than pivot. // From low_end to i are elements equal to pivot. // From i to high_start are elements that haven't been compared yet. for(var i = from + 1; i < high_start;) { var element = a[i]; var order = Compare(element, pivot_key); if(order < 0) { a[i] = a[low_end]; a[low_end] = element; i++; low_end++; } else if(order > 0) { high_start--; a[i] = a[high_start]; a[high_start] = element; } else { // order == 0 i++; } } QuickSort(a, from, low_end); QuickSort(a, high_start, to); } var old_length = ToUint32(this.length); if(old_length < 2) return this; % RemoveArrayHoles(this); var length = ToUint32(this.length); // 将未定义的元素移动到数组的末尾. for(var i = 0; i < length;) { if(IS_UNDEFINED(this[i])) { length--; this[i] = this[length]; this[length] = void 0; } else { i++; } } QuickSort(this, 0, length); //如果this是一个数组,我们只改变了这个数组的长度。 如果this不是数组,则不允许设置此对象的长度,因为这可能会引入新的length属性。 if(IS_ARRAY(this)) { this.length = old_length; } return this; }
(2)字符换大写
实现一:
高阶函数
实现二:
高阶函数
(3)高阶函数实现
若代码中出现重复或者类似的代码,就可以使用高阶函数。如产生一个包含数字的字符串:
高阶函数
使用高阶函数实现:
高阶函数