实现new函数的功能

148 阅读1分钟

首先回忆一下构造函数的执行过程:

  1. 初始化作用域链
  2. 创建一个默认的对象(此对象就是当前类的实例)
  3. 让上下文中的this指向此对象
  4. 初始化arguments
  5. 形参赋值
  6. 变量提升
  7. 代码执行
  8. 在没有返回值的情况下,默认会把创建的实例对象返回。如果return的是基本类型值,返回的还是实例;如果return的是引用类型的值,那么会替代默认返回的实例。 new的功能就是实现了对象的创建,并且使this指向这个对象
function _new(Func) {
  //1 创建一个实例对象,并且把Func作为当前对象的的原型链, 也就是此对象是Func的实例
  const obj = Object.create(Func.prototype);
  //2 获取其他参数
  const args = [].slice.call(arguments, 1);
  //3 把类当做普通函数执行
  const result = Func.apply(obj, args);
  //4 看一下是否有返回值,不存在或者返回的是值类型,则默认返回实例,如果返回的是引用数据类型则返回的是自己写的
  if (result !== null && /^(object|function)$/.test(typeof result)) {
    return result;
  }
  return obj;
}

有些低版本的浏览器可能不支持 Object.create 我们可以实现一个 Object.create(xxx) 的作用是创建一个空对象,并且把参数作为当前对象的原型链,接下来我们就可以实现这个函数了

// 重写Object.create 创建某个类的空实例
Object.myCreate = function (prototype) {
  //1. 创建了一个类
  function Func() {}
  //2. 改变了该类的原型链
  Func.prototype = prototype;
  //3. 返回实例
  return new Func();
};
function Func(x, y) {
  let num = x + y;
  this.x = x;
  this.y = y;
}
const fn = _new(Func, 1, 2, 3);
const fn2 = new Func(1,2,3)
console.log(fn);
console.log(fn instanceof Func)
console.log(fn2);
console.log(fn2 instanceof Func)

image.png