Skip to content

手写题

用函数实现 new 操作

javascript
function create() {
  // 获得构造函数
  let Con = [].shift.call(arguments);
  // 链接到原型
  //obj.__proto__ = Con.prototype
  //采用Object.creact()方法创建原型链
  const obj = Object.create(Con.prototype);
  // 绑定 this,执⾏构造函数
  let result = Con.apply(obj, arguments);
  // 确保 new 出来的是个对象 如果构造函数返回对象就是生成这个对象,否则返回obj
  return typeof result === "object" ? result : obj;
}

手写 call、bind、apply

javascript
Function.prototype.myCall = function (...arg) {
  // 调用myCall的函数
  const fn = this;
  // 需要绑定的this对象
  const targetThis = arg[0];
  // 不可枚举,这样外面就看不到对象被设置的值
  Object.defineProperty(targetThis, "fn", {
    value: fn,
    configurable: true,
  });
  const res = targetThis.fn(arg.slice(1));
  // 调用完了立马删除
  delete targetThis.fn;
  return res;
};
javascript
Function.prototype.myBind = function (context) {
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }
  var _this = this;
  var args = [...arguments].slice(1);
  // 返回⼀个函数
  return function F() {
    // 因为返回了⼀个函数,我们可以 new F(),所以需要判断
    if (this instanceof F) {
      return new _this(...args, ...arguments);
    }
    return _this.apply(context, args.concat(...arguments));
  };
};

深拷贝

javascript
function deepClone(obj, tempMap = new Map()) {
  if (obj && typeof obj === "object") {
    // 第一步确定是一个引用数据类型(除了function)

    if (obj instanceof Date) {
      return new Date(obj);
    }
    if (obj instanceof RegExp) {
      return new RegExp(obj);
    }

    if (tempMap.get(obj)) {
      // 防止对象内循环引用
      return tempMap.get(obj);
    }
    let cloneObj = new obj.constructor();

    //缓存已经拷贝过的对象
    tempMap.set(obj, cloneObj);

    // 遍历对象
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        cloneObj[key] = deepClone(obj[key], tempMap);
      }
    }
    return cloneObj;
  } else {
    // 基本数据类型或者函数(lodash的cloneDeep也是引用的同一函数)
    return obj;
  }
}

数组去重

ES5

javascript
function uniqArr(arr) {
  return arr.filter(function (item, index) {
    return arr.indexOf(item) === index;
  });
}

ES6

javascript
function uniqArr(arr) {
  return [...new Set(arr)];
}

数组拍平

javascript
Array.prototype.myFlat = function (depth = 1) {
  return this.reduce((acc, val) => {
    return acc.concat(Array.isArray(val) && depth > 1 ? val.myFlat(depth - 1) : val);
  }, []);
};