面试官:new一个新对象的过程,发生了什么?

102 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

在平时工作和面试经常会被问道,“new一个新对象的过程,发生了什么?”关于这个问题,我们先从构造函数讲起,再具体详细讲解new一个对象的具体流程,最后再通过代码简单手写一个new函数。

构造函数

在ES6之前,js并没有类的概念,对象并不是基于类去创建的,而是用构造函数的来定义的。如:

function Person(name,age){
   this.name = name;
   this.age = age;
}
let pr = new Person('vivi',23);

由此可见,构造函数是一种特殊的函数,可以用来定义对象和它们的特征,通常和new一起使用。 需要注意的是:当构造函数用于创建对象时,其首字母要大写。

new一个新对象

回到最初的问题,我们来对new一个对象做一下的简单分解动作:首先需要分配对象的内存空间,然后初始化对象,最后设置引用指向分配的内存地址。

具体的,我们来看调用new时,主要做了哪些事情:

  1. 在内存中创建一个新的空对象
  2. 将空对象的_proto_指向构造函数的prototype,并将构造函数的this指向这个新创建的空对象
  3. 执行构造函数,为这个对象添加属性和方法。
  4. 最后,查看构造函数本身的返回结果:如果有return 对象,则直接返回这个对象,如果没有返回值或者返回的是一个原始值,则浏览器默认会将新创建的对象实例返回。

根据以上的步骤,我们可以手写一个简单的new函数,如下:

function createNew(fn,..args){
   const obj={}; //创建一个空对象
   obj.__proto__ = fn.prototype;  //空对象的_propto_指向构造函数的prototype
   const res = fn.apply(obj,args);//构造函数的this指向这个新创建的空对象
   return typeof res === 'object'?res:obj;//有返回值则返回返回值,没有则返回新对象
}
const pr = createNew(Person,'vivi',23);