Files
notes_estom/JavaScript/4JavaScript高阶函数.md
2020-07-21 09:13:01 +08:00

208 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 1 高阶函数定义
JavaScript的函数其实都指向某个变量。既然变量可以指向函数函数的参数能接收变量那么一个函数就可以接收另一个函数作为参数这种函数就称之为高阶函数。
```
function add(x, y, f) {
return f(x) + f(y);
}
x = -5;
y = 6;
f = Math.abs;
f(x) + f(y) ==> Math.abs(-5) + Math.abs(6) ==> 11;
return 11;
```
## 2 MapReduce
map:对集合分割运算。
reduce对分割运算的结果进行聚合。
### array.map
map()方法本身可以接受一个函数,作用在数组的每一个元素,并拼接成新的数组。是一个高阶函数。
```
function pow(x) {
return x * x;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var results = arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
console.log(results);
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']
```
### array.reduce
再看reduce的用法。Array的reduce()把一个函数作用在这个Array的[x1, x2, x3...]上这个函数必须接收两个参数reduce()把结果继续和序列的下一个元素做累积计算,其效果就是:
```
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
```
```
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
```
## 3 filter
### 过滤元素
把Array的某些元素过滤掉然后返回剩下的元素
Array的filter()也接收一个函数。filter()把传入的函数依次作用于每个元素然后根据返回值是true还是false决定保留还是丢弃该元素。
```
var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var r = arr.filter(function (x) {
return x % 2 !== 0;
});
r; // [1, 5, 9, 15]
```
### 回调函数
filter()接收的回调函数其实可以有多个参数。通常我们仅使用第一个参数表示Array的某个元素。回调函数还可以接收另外两个参数表示元素的位置和数组本身
```
var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
console.log(element); // 依次打印'A', 'B', 'C'
console.log(index); // 依次打印0, 1, 2
console.log(self); // self就是变量arr
return true;
});
```
利用回调函数,除掉重复元素
```
var r,arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
r = arr.filter(function (element, index, self) {
return self.indexOf(element) === index;
});
```
## 4 sort
默认把所有的元素转换为String进行排序。可以接受比较函数进行排序。
```
arr.sort(function (x, y) {
if (x < y) {
return -1;
}
if (x > y) {
return 1;
}
return 0;
});
console.log(arr); // [1, 2, 10, 20]
```
## 5 every
every()方法可以判断数组的所有元素是否满足测试条件。
```
var arr = ['Apple', 'pear', 'orange'];
console.log(arr.every(function (s) {
return s.length > 0;
})); // true, 因为每个元素都满足s.length>0
console.log(arr.every(function (s) {
return s.toLowerCase() === s;
})); // false, 因为不是每个元素都全部是小写
```
## 6 find
find()方法用于查找符合条件的第一个元素如果找到了返回这个元素否则返回undefined
```
var arr = ['Apple', 'pear', 'orange'];
console.log(arr.find(function (s) {
return s.toLowerCase() === s;
})); // 'pear', 因为pear全部是小写
console.log(arr.find(function (s) {
return s.toUpperCase() === s;
})); // undefined, 因为没有全部是大写的元素
```
## 7 findIndex
findIndex()和find()类似也是查找符合条件的第一个元素不同之处在于findIndex()会返回这个元素的索引,如果没有找到,返回-1
```
var arr = ['Apple', 'pear', 'orange'];
console.log(arr.findIndex(function (s) {
return s.toLowerCase() === s;
})); // 1, 因为'pear'的索引是1
console.log(arr.findIndex(function (s) {
return s.toUpperCase() === s;
})); // -1
```
## 8 forEach
forEach()和map()类似它也把每个元素依次作用于传入的函数但不会返回新的数组。forEach()常用于遍历数组,因此,传入的函数不需要返回值:
```
var arr = ['Apple', 'pear', 'orange'];
arr.forEach(console.log); // 依次打印每个元素
```
## 9 闭包
> 闭包的出现,可以获取函数内部的变量且变量一直在内存当中.最简单的理解,一个作用域使用了另一个作用域中的变量。比如外层函数通过传参的方式,把某个变量传递给内层函数,就产生了闭包
>
### 函数可以作为返回值实现惰性求值
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
可以通过函数作为返回值,实现懒求值。
```
function lazy_sum(arr) {
var sum = function () {
return arr.reduce(function (x, y) {
return x + y;
});
}
return sum;
}
//调用函数f时才真正计算求和的结果
f(); // 15
```
### 函数作为返回值实现循环惰性求值
> 感觉与Python的生成器yield惰性求值很像这里介绍了其根本的原理。
```
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push((function (n) {
return function () {
return n * n;
}
})(i));
}
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
f1(); // 1
f2(); // 4
f3(); // 9
```
## 10 回调函数与多线程异步通信
回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。