手写js

79 阅读1分钟

实现new操作符

function mynew(Fn, ...args) {
 // 1.创建一个新对象
  const obj = {};
  // 2.新对象原型指向构造函数原型对象
  obj.__proto__ = Fn.prototype;
  // 3.将构建函数的this指向新对象
  const result = Fn.apply(obj, args);
  // 4.根据返回值判断
  return result instanceof Object ? result : obj;
}

实现bind

Function.prototype.mybind = function (context) {
  if (typeof this !== "function") {
    throw new TypeError("caller is not a function");
  }
  const args = [...arguments].slice(1);
  const fn = this;
  const noop = function () {};
  const res = function () {
    return fn.apply(this instanceof noop ? this : context || window, [
      ...args,
      ...arguments,
    ]);
  };
  if (this.prototype) {
    noop.prototype = this.prototype;
  }
  res.prototype = new noop();
  return res;
};

科里化

const curry = function (fn) {
  return function curriedFn(...args) {
    if (args.length < fn.length) {
      return function () {
        return curriedFn(...[...args, ...arguments]);
      };
    }
    return fn(...args);
  };
};

组合函数:将多个函数组合成一个函数

组合函数与管道函数的意义在于:可以把很多小函数组合起来完成更复杂的逻辑

组合函数执行是从右到左的。而管道函数,执行顺序是从左到右执行的

const compose = (...fns) => {
  return (val) => {
    return fns.reverse().reduce((acc, fn) => {
      return fn(acc);
    }, val);
  };
};
const pipe = (...fns) => {
  return (val) => {
    return fns.reduce((acc, fn) => {
      return fn(acc);
    }, val);
  };
};

函数缓存

const memoize = function (func, content) {
  const cache = Object.create(null);
  content = content || this;
  return (...key) => {
    if (!cache[key]) {
      cache[key] = func.apply(content, key);
    }
    return cache[key];
  };
};

精度问题

function strip(num, precision = 12) {
  return +parseFloat(num.toPrecision(precision));
}

实现instanceof

const _instanceof = (target, Fn) => {
  const type = typeof target;
  if ((type !== "object" && type !== "function") || target === null) {
    return false;
  }
  let proto = Object.getPrototypeOf(target);
  while (true) {
    if (proto === null) return false;
    if (proto === Fn.prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }
};