函数增强
Rio 2023-01-15
js
说明
函数增强概念、arguments、纯函数、柯里化、组合函数笔记总结
# 函数增强
JavaScript中函数也是一个对象,那么对象中就可以有属性和方法。
# 函数对象的属性
function f1(a,b) {}
function ff2(a,b,c=20) {}
function f3(a,b,c,d,...others) {}
f1.msg="f11"
ff2.msg="f22"
f3.msg="f33"
console.log(f1.length); // 2
console.log(ff2.length); // 2
console.log(f3.length); // 4
let fns = [f1,ff2,f3]
for (const i of fns) {
console.log(i.name);
console.log(i.msg);
}
// f1 f11 ff2 f22 f3 f33
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# arguments
arguments 是一个对应于传递给函数的参数的类数组(array-like)对象
- 拥有数组的一些特性,比如说length,比如可以通过index索引来访问
- 没有数组的一些方法,比如filter、map等
function foo(a,b) {
console.log(arguments);
console.log(arguments[2]); // 3
}
foo(1,2,3,4) //Arguments(4) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]
1
2
3
4
5
2
3
4
5
arguments 转数组
Array.from(arguments)
- […arguments]
- 遍历到数组
[].slice.apply(arguments)
Array.prototype.slice.apply(arguments)
箭头函数没有arguments 详见函数的this指向
# 纯函数
- 此函数在相同的输入值时,需产生相同的输出。
- 函数的输出和输入值以外的其他隐藏信息或状态无关:也和由I/O设备产生的外部输出无关。
- 该函数不能有语义上可观察的函数副作用,表示在执行一个函数时,除了返回函数值之外,还对调用函数产生了附加的影响比如修改了全局变量,修改参数或者改变外部的存储;
# 柯里化
只传递给函数一部分参数来调用它,让它返回一个函数去处理剩余的参数;
function f1(a,b,c) {
console.log(a+b+c);
}
f1(1,2,3) // 6
function f2(x) {
return function (y) {
return function (z) {
console.log(x+y+z);
}
}
}
f2(1)(2)(3) // 6
let f3 = x => y => z => console.log(x + y + z);
f3(10)(20)(30) // 60
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 柯里化实现
function f1(a,b,c) {
console.log(a+b+c);
}
function f2(a,b) {
return a-b
}
function f3(a,b,c) {
console.log(`1.${a} 2.${b} 3.${c}`);
}
// 柯里化
function hyCurrying(fn) {
function curryFn(...args) {
if (args.length >= fn.length) {
// return fn(...args)
return fn.apply(this,args)
} else {
return function(...newArgs) {
// return curryFn(...args.concat(newArgs))
return curryFn.apply(this,args.concat(newArgs))
}
}
}
return curryFn
}
let cf1 = hyCurrying(f1)
cf1(10)(20)(30) // 60
let cf2 = hyCurrying(f2)
console.log(cf2(60)(20)); // 40
let cf3 = hyCurrying(f3)
cf3(10)(20)(30) // 1.10 2.20 3.30
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
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
# 组合函数
组合函数是将多个函数按照排序进行执行,前一个函数返回的数据,作为下一个函数的参数,最后返回最终的结果。
function add(a) {
return a + 100
}
function sub(a) {
return a - 50
}
console.log(sub(add(5)));
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 组合函数实现
function add(a) {
return a + 100
}
function sub(a) {
return a - 50
}
function composeFn(...fns) {
var length = fns.length
if (length<=0) return
for(let i = 0;i < length; i++){
var fn = fns[i]
if (typeof fn !== "function") {
throw new Error(`${i} must be a function`)
}
}
return function (...args) {
var res = fns[0].apply(this,args)
for(let i = 1;i< length;i++){
var fn = fns[i]
res = fn.apply(this,[res])
}
return res
}
}
let newFn = composeFn(add,sub,console.log)
newFn(5) // 55
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
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
# 默认参数
function foo(a,b) {
// a = (a === undefined || a === null ) ? '默认': a
a = a ?? '默认'
console.log(a);
}
foo(1,2) // 1
foo(0) // 0
foo() // 默认
-------------------------------
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10