高阶函数简述 js
1、简述
高阶函数似乎是一种先进编程的的技术。然而,并不是。
高阶函数其实就是将函数作为参数或者返回值的函数。其中作为参数的函数一般是回调函数。
2、例子
(1)最简单的例子
大家都熟悉数组的sort方法。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>高阶函数</title>
</head>
<body>
<script type="text/javascript">
let arr = [1,2,4,3];
arr.sort((a,b)=>{return a-b})
console.log(arr)
</script>
</body>
</html>
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)字符换大写
实现一:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>高阶函数</title>
</head>
<body>
<script type="text/javascript">
let arr = ['abc', 'def'],
arrNew = [];
for(let i = 0; i < arr.length; i++) {
arrNew[i] = arr[i].toUpperCase()
}
console.log(arrNew)
</script>
</body>
</html>
实现二:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>高阶函数</title>
</head>
<body>
<script type="text/javascript">
let arr = ['abc', 'def'],
arrNew = [];
arrNew = arr.map(val => {
return val.toUpperCase()
})
console.log(arrNew)
</script>
</body>
</html>
(3)高阶函数实现
若代码中出现重复或者类似的代码,就可以使用高阶函数。如产生一个包含数字的字符串:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>高阶函数</title>
</head>
<body>
<script type="text/javascript">
let digits = ''
for (let i=0;i<10;i++) {
digits += i
}
console.log(digits)
</script>
</body>
</html>
使用高阶函数实现:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>高阶函数</title>
</head>
<body>
<script type="text/javascript">
let digits = ''
function buildString(n, callback) {
let val = '';
for(let i = 0; i < n; i++) {
val += callback(i)
}
return val
}
digits = buildString(10, i => {
return i
})
console.log(digits)
</script>
</body>
</html>
作者:孟繁贵 Email:meng010387@126.com 期待共同进步!