前端 - JS补充知识
函数柯里化
柯里化也称为部分求值,分步给函数传递参数
- 每次传递参数进行处理,并返回一个更具体的函数接收剩下的参数
- 中间可嵌套多层这样的接收部分参数的函数,直至返回最后的结果
function add(x, y) {
return x + y;
}
add(1, 2); // 3
// 柯里化之后
function cAdd(x) {
return function(y) {
return x + y;
}
}
cAdd(1)(2); // 3
定义一个求和的柯里化函数:
// 求和函数
function sum(...args) {
return args.reduce((prev, curr) => prev + curr, 0);
}
// 柯里化函数
function currying(fn) {
const args = []; // 收集过程中所有的参数
return function result(...rest) {
if (rest.length === 0) {
return fn(...args);
}
args.push(...rest);
return result;
};
}
currying(sum)(1)(2, 3, 4)(); // 10
currying(sum)(1, 2, 3)(4)(5)(6)(); // 21
currying(sum)(1)(2)(); // 3
异步相关
Generator
Generator
函数和普通函数的区别:
function
关键字与函数名之间有一个*
,Generator
最大的特点就是可以交出函数的执行权,即暂停执行- 内部使用
yield
语句,可以定义不同的内部状态- 状态,其实就是数据
- 函数内部的状态,就是函数内部的值,在不同的时候是不一样的
总的来说:
- 本质上,
Generator
就是一个封装的异步任务,也可以说是异步任务的容器 yield
命令是异步不同阶段的分界线,所以有时会把yield
当作是return
,但是二者有本质区别
next()简介
一个最简单的Generator
函数:
function* fn() {
yield 'a';
yield 'b';
return 'c';
}
let _fn = fn();
调用next()
方法来启动Generator
函数,每次调用会返回一个对象表示当前阶段的信息:
value
属性:done
属性:true
表示函数已经执行完了
_fn.next(); // { value: 'a', done: false }
_fn.next(); // { value: 'b', done: false }
_fn.next(); // { value: 'c', done: true }
_fn.next(); // { value: undefined, done: true }
迭代器对象相互独立:
let xx = fn();
let yy = fn();
console.log(xx.next()); // { value: 'a', done: false }
console.log(xx.next()); // { value: 'b', done: false }
console.log(yy.next()); // { value: 'a', done: false }
console.log(yy.next()); // { value: 'b', done: false }
- 每当调用了
next()
方法,Generator
函数的内部指针会从上一次停下来的地方继续运行,直到遇到了下一个yield
语句
next()传参
Generator
函数的next()
方法可以接收参数:
- 传入的参数,其实是把上一个yield语句返回的值覆盖了
- 第一个
next()
方法其实是启动器- 由于在它之前没有
yield
语句,所以给第一个next()
方法传参没有意义
- 由于在它之前没有
function* fn() {
let n = 1;
let val = yield n + 100;
console.log(val); // abc
yield ++n;
yield ++n;
}
let _fn = fn();
// 第1个next(), 在 yield n + 100 处暂停, 但是还没有进行到let val = 101 的赋值阶段
_fn.next(); // { value: 101, done: false }
// 第2个next(), 将上一次yield语句的值101覆盖为'abc', 遇到下一个yield语句暂停
_fn.next('abc'); // { value: 2, done: false }
_fn.next(); // { value: 3, done: false }
这个例子说明Generator
函数的一个应用场景,即通过next()
方法,分阶段注入数据,让函数分阶段给出不同的值。
for of循环
Generator
函数支持for of
循环。
function* fn() {
yield 'a';
yield 'b';
return 'c';
}
let _fn = fn();
for (let i of _fn) {
console.log(i);
}
// a
// b
_fn.next(); // { value: undefined, done: true }