JavaScript 常用核心手写实现

加载中... 浏览

本篇文章汇总了 JavaScript 开发中最为频繁遇到的核心手写题目,包括函数增强、常用工具函数、原型链模拟以及异步处理等。

1. 函数柯里化 (Currying)

柯里化是一种将多参数函数转换为一系列单参数函数的技术。

javascript
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function (...args2) {
        return curried.apply(this, args.concat(args2));
      };
    }
  };
}

2. 深拷贝 (Deep Clone)

递归实现对象的深拷贝,处理基本类型与引用类型。

javascript
function deepClone(obj) {
  if (typeof obj !== 'object' || obj === null) return obj;

  let newObj = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepClone(obj[key]);
    }
  }
  return newObj;
}

3. 防抖 (Debounce)

在事件被触发 n 秒后再执行回调,如果在这 n 秒内又被触发,则重新计时。

javascript
function debounced(fn, time) {
  let timer;
  return function (...args) {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, time);
  };
}

4. 节流 (Throttle)

规定在一个单位时间内,只能触发一次函数。

javascript
function throttle(fn, time) {
  let lastTime = 0;
  return function (...args) {
    let now = Date.now();

    if (now - lastTime > time) {
      fn.apply(this, args);
      lastTime = now;
    }
  };
}

5. Function.prototype.bind

javascript
Function.prototype.myBind = function (obj, ...args) {
  const context = (obj !== null && typeof obj === 'object') ? obj : window;

  return (...args2) => {
    this.call(context, ...args, ...args2);
  };
}

6. Function.prototype.call

javascript
Function.prototype.myCall = function (obj, ...args) {
  const context = (obj !== null && typeof obj === 'object') ? obj : window;

  const key = Symbol();
  context[key] = this;
  const result = context[key](...args);
  delete context[key];

  return result;
}

7. Function.prototype.apply

javascript
Function.prototype.myApply = function (obj, argArray) {
  const context = (obj !== null && typeof obj === 'object') ? obj : window;

  const key = Symbol();
  context[key] = this;
  let result;
  if (!argArray) {
    result = context[key]();
  } else {
    result = context[key](...argArray);
  }
  delete context[key];

  return result;
}

8. 实现数组 reduce 方法

javascript
Array.prototype.myReduce = function (fn, init) {
  let total;
  let list = this;
  let startIndex;

  if (list.length === 0 && arguments.length < 2) {
    throw new TypeError('error');
  }

  if (arguments.length > 1) {
    total = init;
    startIndex = 0;
  } else {
    total = list[0];
    startIndex = 1;
  }

  for (let i = startIndex; i < list.length; i++) {
    total = fn(total, list[i], i, list);
  }

  return total;
};

9. 数组拍平 (Flat)

javascript
function myFlat(arr, depth = 1) {
  const result = [];

  arr.forEach((item) => {
    if (Array.isArray(item) && depth > 0) {
      result.push(...myFlat(item, depth - 1));
    } else {
      result.push(item);
    }
  });

  return result;
}

10. 实现 new 操作符

javascript
function myNew(fn, ...args) {
  const obj = Object.create(fn.prototype);
  fn.apply(obj, args);
  return obj;
}

11. 实现 instanceof

javascript
function myInstanceof(left, right) {
  let proto = Object.getPrototypeOf(left);
  const prototype = right.prototype;

  while (proto) {
    if (proto === prototype) {
      return true;
    }
    proto = Object.getPrototypeOf(proto);
  }

  return false;
}

12. 实现 Promise.all

javascript
Promise.myAll = function (list) {
  let finishNums = 0;
  const result = [];

  return new Promise((resolve, reject) => {
    if (list.length === 0) return resolve([]);

    list.forEach((item, index) => {
      Promise.resolve(item).then(
        (res) => {
          finishNums++;
          result[index] = res;
          if (finishNums === list.length) {
            resolve(result);
          }
        },
        (err) => {
          reject(err);
        }
      );
    });
  });
};

留言板

加载评论中...
Vue 3 开发者的 React 入门笔记
Valaxy v0.28.0-beta.1 驱动|主题-Yunv0.28.0-beta.1