【前端面试题】彻底搞懂函数柯里化、函数防抖、函数节流

函数柯里化

在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。

柯里化(Currying),又称部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。核心思想是把多参数传入的函数拆成单参数(或部分)函数,内部再返回调用下一个单参数(或部分)函数,依次处理剩余的参数。

经典面试题

function add(a, b) {
  return a + b;
}
function curry(fn) {
}
curry(add)(1)(2)  => 3

答案:

const currying = function (fn, ...args) {
  const len = fn.length //函数参数长度
  args = args || [];
  const returnFn = (...rests) => {
    args = args.concat(rests)
    return args.length >= len ? fn.apply(null, args) : returnFn
  }
  return returnFn
};


const sum = (a, b, c) => a + b + c;

const newSum = currying(sum);
console.log(newSum(1)(2)(3));

函数节流

函数节流:规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。简单来说,触发后立即执行,但如果要执行下一次,需要在离上次执行时间间隔设定时间后再出发才能执行。

题目:

function sayHi(name, action){
    console.log(`${name}_${action}`);
}
document.addEventListener('input', throttle(sayHi, 2000, 'rock', 'hello'));

答案:

// 多次连续触发 在一段时间内仅仅一次出发。
function throttle(fn, timeout, ...rest){
    let timer = null;
    return ()=>{
        if(timer){
            return;
        }
        timer = setTimeout( ()=>{
            fn.apply(this, rest);
            clearTimeout(timer);
            timer = null;
        }, timeout)
    }
}

函数防抖

函数防抖:在频繁触发的情况下,只有足够的空闲时间,才执行代码一次,如果没有执行完就清除掉,重新执行逻辑。简单来说,当触发后再次触发,会取消上一次触发的执行,直到最后一次触发后过去设定时间后才执行。

函数防抖规定函数再次执行需要满足两个条件:

  • 当调用事件触发一段时间后,才会执行该事件
  • 在条件一等待的这段时间间隔内再次调用此动作则将重新计算时间间隔
// 多次连续触发仅仅最后一次执行
function debounce(fn, timeout, ...rest){
    let timer = null;
    return ()=>{
        timer && clearTimeout(timer);
        timer = setTimeout( ()=>{
            fn.apply(this, rest);
            clearTimeout(timer);
            timer = null;
        }, timeout)
    }
}
function sayHi(name, action){
    console.log(`${name}_${action}`);
}
document.getElementById('input').addEventListener('input', debounce(sayHi,2000, 'rock', 'hello'));

函数等待

题目:手写红绿灯, 红灯:3s, 绿灯: 2s, 黄灯:1s

function light(color, timeout) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(color, new Date().toString());
      resolve();
    }, timeout)
  })
}

async function caller() {
  await light("red", 3000);
  await light("green", 2000);
  await light("yellow", 1000);
  caller();
}
caller();

偏函数

偏函数(英文:Partial Application),也叫部分应用。是指在计算机科学中,固定多元函数的部分参数,并返回一个可以接受剩余部分参数的函数的转换过程。

偏函数与柯里化十分相像:

柯里化: 将多参数函数转换成多个单参数函数,也就是将一个 n 元函数转换成 n 个一元函数
偏函数: 则是固定一个函数的一个或多个参数,也就是将一个 n 元函数转换成一个 n - x 元函数

偏函数其实函数柯里化的一部分,也就是中间部分的函数返回。
🌰 示例:

function add(a, b) {
  return a + b;
}

// 执行 add 函数,一次传入两个参数即可
add(1, 2); // 3

// 假设有一个 partial 函数可以做到局部应用
var addOne = partial(add, 1);

addOne(2); // 3

这里就不多讲了。

关于我
loading