JavaScript 手写系列(1)

95 阅读1分钟

1、使用 setTimeout 实现 setInterval

    function mySettimeout(fn: Function, t: number) {
          let timer: any = null;
          // 递归函数,函数内调用自身
          function inter() {
            fn();
            timer = setTimeout(inter, t);
          }
          inter();

          // 返回取消延时器的 方法
          return {
            cancel: () => {
              clearTimeout(timer);
            },
          };
        }

    const cancel = mySettimeout(() => {
      console.log(111);
    }, 1000);

    cancel.cancel();

2、反过来 setInterval 实现  setTimeout

    function myTime(fn: Function, t: number) {
      let timer: any = null;
      timer = setInterval(() => {
        clearInterval(timer);
        fn();
      }, t);
    }

    myTime(() => {
      console.log(111);
    }, 1000);

3、数组扁平化

ES6 方法

    const arr = [1, ['a', ['b', ['c']]]];
    console.log(arr.flat(Infinity)); // es6 方法 flat

    // flat(depth) 方法中的参数depth,代表展开嵌套数组的深度,默认是1
    // 不知道数组维度,depth的值设置为Infinity。

递归实现

    var arr1 = [1, 2, 3, [1, 2, 3, 4, [2, 3, 4]]];

    const newArr: any[] = [];

    function getAllArr(arr: Array<any>) {
      arr.forEach((item: any) => {
        if (Array.isArray(item)) {
          getAllArr(item);
        } else {
          newArr.push(item);
        }
      });
    }
    getAllArr(arr1);

    function flatten(arr) {
      return arr.reduce((res, next) => {
        return res.concat(Array.isArray(next) ? flatten(next) : next);
      }, []);
    }
    flatten(arr1)

while 循环

      if (!arr.length) return;
      while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr);
      }
      return arr;
    }
    // console.log(flatter([1, 2, [1, [2, 3, [4, 5, [6]]]]]));

4、new 操作符

new 的过程

  • 创建一个 u = {} 空对象
  • 绑定原型 u.proto = User.prototype
  • 将构造函数中 this 绑定到 新对象上
  • 根据构造函数返回类型作判断,如果是原始值则被忽略,如果是返回对象,需要正常处理
    function User(name) {
      this.name = name;
    }

    let u = new User('leo');
    
    // 手动实现
    function mynew(Func, ...args) {
      // 1.创建一个新对象
      const obj = {};

      // 2.新对象原型指向构造函数原型对象
      obj.__proto__ = Func.prototype;

      // 3.将构建函数的this指向新对象
      let result = Func.apply(obj, args);

      // 4.根据返回值判断
      return result instanceof Object ? result : obj;
    }