Node-JS专精05高阶函数

高阶函数

把函数作为参数或者返回值的函数

JS内置高阶函数

  • Function.prototype.bind
  • Function.prototype.apply
  • Function.prototype.call
  • Array.prototype.sort
  • Array.prototype.map
  • Array.prototype.filter
  • Array.prototype.reduce

bind

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
var bind = Function.prototype.bind

const fn = function(){
console.log(this)
console.log(arguments)
}

var f1 = fn.bind({name:'hjx'},1,2,3)

fn()
// window
// Arguments[]

f1()
// {name:'hjx'}
// Arguments伪数组[1,2,3]


// 首先我们认同这句话
// obj.method(a,b,c,d)
// 等价于
// obj.method.call(obj,a,b,c,d)


// 代入值
// 设 obj = f1
// 设 method = bind

// 得到
// f1.bind(a,b,c,d)
// 等价于
// f1.bind.call(f1,a,b,c,d)

// 继续代入
// 设 a = {name:'hjx'}
// 设 b,c,d = 1,2,3
// f1.bind({name:'hjx'},1,2,3)
// 等价于
// f1.bind.call(f1,{name:'hjx'},1,2,3)

// f1.bind = Function.prototype.bind
// var bind = Function.prototype.bind
// 所以 f1.bind 就是 bind

// 继续代入 f1.bind.call(f1,{name:'hjx'},1,2,3)
bind.call(f1,{name:'hjx'},1,2,3) 这个式子就是结论


// 得到结论
bind.call 接受 一个函数fn,this,其他参数
返回一个新的函数,会调用 fn,并传入 this,和其他参数

apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var apply = Function.prototype.apply

const f1 = function(){
console.log(this)
console.log(arguments)
}

f1.apply({name:'hjx'},[1,2,3]) // 直接调用
// {name:'hjx'}
// Arguments伪数组[1,2,3]


// 首先我们认同这句话
// obj.method(a,b,c,d)
// 等价于
// obj.method.call(obj,a,b,c,d)

// 设 obj = f1
// 设 method = apply

// 代入
// f1.apply({name:'hjx'},[1,2,3])
// 等价于
// f1.apply.call(f1,{name:'hjx'},[1,2,3])

// 继续代入
// 设 a = {name:'hjx'}
// 设 b,c,d = 1,2,3
// f1.apply({name:'hjx'},[1,2,3])
// 等价于
// f1.apply.call(f1,{name:'hjx'},[1,2,3])

// f1.apply = Function.prototype.apply
// f1.apply = apply

// 注意这里是直接调用,不会像 bind一样重新返回函数
apply.call(f1,{name:'hjx'},[1,2,3])

call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var call = Function.prototype.call

const f1 = function(){
console.log(this)
console.log(arguments)
}

f1.call({name:'hjx'},1,2,3) // 直接调用
// {name:'hjx'}
// Arguments伪数组[1,2,3]

// 设 obj = f1
// 设 method = call

// 代入
// f1.call({name:'hjx'},1,2,3)
// 等价于
// f1.call.call(f1,{name:'hjx'},1,2,3)

// 继续代入
// 设 a = {name:'hjx'}
// 设 b,c,d = 1,2,3
// f1.call({name:'hjx'},[1,2,3])
// 等价于
// f1.call.call(f1,{name:'hjx'},[1,2,3])

// f1.call = Function.prototype.call
// f1.call = call


// call的含义 也是直接调用 f1
call.call(f1,{name:'hjx'},1,2,3)

sort

map ,filter , reduce同理

1
2
3
4
5
var array = [1,5,2,3,4]
var sort = Array.property.sort

array.sort((a,b)=> b - a)
array.sort.call(array,(a,b=> b - a))

注意

理解JS的 call 用法才能真正掌握JS

adrian Mejia twitter

1
2
3
4
5
6
7
8
9
10
Reduce illustrated with Emojis:

map([🌽, 🐮, 🥚,🐓, 🥔], cook)
//=> [🍿, 🍔, 🍳,🍗, 🍟]

filter([🍿, 🍔, 🍳,🍗, 🍟], isVegetarian)
//=> [🍿, 🍳, 🍟]

reduce([🍿, 🍔, 🍳,🍗, 🍟], digest)
//=> 💩

函数的组合(用的比较少的)

1
2
3
4
5
6
7
8
9
10
11
12
function doubleSay (str) {
return str + ", " + str;
}
function capitalize (str) {
return str[0].toUpperCase() + str.substring(1);
}
function exclaim (str) {
return str + '!';
}

let result = exclaim(capitalize(doubleSay("hello")));
result //=> "Hello, hello!"

使用Pipe操作

1
2
3
4
5
6
let result = "hello"
|> doubleSay
|> capitalize
|> exclaim;

result //=> "Hello, hello!"

在不久的将来,这个语法就能用了。
如果你现在就想用,可以使用Ramda.js

1
2
3
// 组合方法,除了第一个函数,后面的函数必须接受一个参数
const say = R.compose(doubleSay, capitalize, exclaim);
let result = say("hello");

React高阶组件

特点

  • children是个函数
  • children返回React个数
  • 把需要暴露的API传给 children
  • 其实就是个回调

总结

  • 搞清函数所有特点
  • 理解递归
  • 理解迭代
  • 理解记忆化 memorize
  • 理解柯里化 curry
  • 组合函数