调用 new 的过程发生了什么?手写 new 的实现过程

336 阅读1分钟

前言

面试题常见问题:new的原理是什么?调用new的过程发生了什么?
new关键词的主要作用就是执行一个构造函数、返回一个实例对象,在new的过程中,根据构造函数的情况,来确定是否可以接受参数的传递。

New动作做了什么

new操作符可以帮助我们构建出一个实例,并且绑定上 this,内部执行步骤可大概分为以下几步:

  1. 创建一个新对象
  2. 对象连接到构造函数原型上,并绑定 this(this 指向新对象)
  3. 执行构造函数代码(为这个新对象添加属性)
  4. 返回新对象

手写 new 的实现过程

function create(fn, ...args) {
    if(typeof fn !== 'function') {
        throw 'fn must be a function';
    }
    // 1、用new Object() 的方式新建了一个对象obj
    // var obj = new Object()
    // 2、给该对象的__proto__赋值为fn.prototype,即设置原型链
    // obj.__proto__ = fn.prototype

    // 1、2步骤合并
    // 创建一个空对象,且这个空对象继承构造函数的 prototype 属性
    // 即实现 obj.__proto__ === constructor.prototype
    var obj = Object.create(fn.prototype);

    // 3、执行fn,并将obj作为内部this。使用 apply,改变构造函数 this 的指向到新建的对象,这样 obj 就可以访问到构造函数中的属性
    var res = fn.apply(obj, args);
    // 4、如果fn有返回值,则将其作为new操作返回内容,否则返回obj
    return res instanceof Object ? res : obj;
};
  • 使用 Object.create 将 obj 的proto指向为构造函数的原型
  • 使用 apply 方法,将构造函数内的 this 指向为 obj
  • 在 create 返回时,使用三目运算符决定返回结果。
//使用create代替new
function Person() {...}
// 使用手写的new,即create
var person = create(Person)

来源声明:用于记录学习心得整理总结,内容非原创。