前端 - JS补充知识

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函数和普通函数的区别:

  1. function关键字与函数名之间有一个*
  2. Generator最大的特点就是可以交出函数的执行权,即暂停执行
  3. 内部使用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 }
posted @ 2022-04-30 19:33  lv6laserlotus  阅读(34)  评论(0)    收藏  举报