我们在初始化一个构造函数实例时,需要用new操作符去初始化实例,那么我们在new 一个构造函数的时候new到底为我们做了什么呢?

function Person(name){
    this.name = name
}
Person.prototype.sayHi = function(){
    console.log(this.name)
}
const jayken = new Person('Jayken');

// Person {name: "Jayken"}
//   name: "Jayken"
//   __proto__:
//     sayHi: ƒ ()
//     constructor: ƒ Person(name)
//     __proto__: Object

从上面的例子可以看出 new 为我们做了以下事情:

  1. 创建一个新的对象;
  2. 将新对象的__proto__ 指向构造函数的prototype;
  3. 用指定的参数通过call/apply调用构造函数,改变构造函数的this指向新创建的对象;
  4. 返回新创建的对象;

知道new做了什么后,我们来动手实现一个

/**
 * 
 * @param Fn 传入的构造函数
 * @param args 需要传给构造函数的参数
 */
function creater(Fn, ...args){
  // Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (MDN)
  const obj = Object.create(Fn.prototype);
  // 使用apply调用Fn构造函数,将Fn的this指向obj
  Fn.apply(obj, args);
  return obj;
}

实现完成后我们用Person函数来验证一下:

const jayken = creater(Person, 'Jayken');

// Person {name: "Jayken"}
//   name: "Jayken"
//   __proto__:
//     sayHi: ƒ ()
//     constructor: ƒ Person(name)
//     __proto__: Object

OK 结果完全一样!

标签: js

评论