如何实现一个new

240 阅读1分钟

首先,我们需要先了解下原型链的知识(详解JS原型与原型链(长文详解) - 掘金 (juejin.cn))

new操作符的原理

  • 创建一个空对象,将它的引用赋给this,继承函数的原型
  • 通过this将属性和方法添加至这个对象
  • 最后返回this指向的新对象,也就是实例

大概是这样的:

function _new (name, age) { 
    // 1. 创建一个新对象,赋予this,这一步是隐形的 
    let this = {}; 
    // 2. 给this指向的对象赋予构造属性 
    this.name = name; 
    this.age = age; 
    // 3. 如果没有手动返回对象,则默认返回this指向的这个对象,也是隐形的 
    return this; 
}

我们在写的详细一些:

function myNew() {
  // 创建一个空的对象
  let obj = Object.create();
  // 将arguments转换成数组,再调用shift方法返回第一个参数,也就是构造函数
  let Con = [].shift.call(arguments);
  // 链接到原型
  obj.__proto__ = Con.prototype;
  // 绑定this,执行构造函数(因为apply会自动执行函数,注意现在的argument里面只有传递进来的属性值)
  let result = Con.apply(obj, arguments);
  // 这里进行判断,如果构造函数最后有return操作,那就返回构造函数里面的值,判断是否是其他类型的值,否则则返回obj
  return typeof result === "object" ? result : obj;
}

测试一下:

function Person (name, age) { 
    this.name = name
    this.age = age
    return this 
} 
let a = myNew(Person, '诺安人', 24) 
// {name = '诺安人', age = 24}