手写JS-实现new关键字

5,060 阅读2分钟

前言

和其他高级语言一样javascript中也有new关键字,我们以前认知的new是用来创建一个类的实例对象,但在js中万物皆是对象,为何还要new关键字呢,其实js中

new

运算符用来创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。 接下来,本文将带你一起来实现一个new关键字...

原始的new

首先我们先手写 new 一个对象看看:

function Person(name, age) {
    this.name = name
    this.age = age
}
let p = new Person('布兰', 12)
console.log(p)  // Person { name: '布兰', age: 12 }

打印结果:

从打印结果中可以看到:

用new关键字实例化对象时,首先创建了一个空对象p,并且这个空对象包含两个属性name和age,分别对应构造函数中的两个属性,其次我们也可以知道实例化出来的这个对象p是继承自Person.prototype,那么现在我们就可以总结出new关键字在实例化对象时内部都干了什么。

  1. 其实,new关键字内部干了如下三件事(已知构造函数为constructor):.创建一个空对象,并使该空对象继承constructor.prototype;
  2. 执行构造函数,并将this指向刚刚创建的新对象;
  3. 返回新对象;

封装一个函数实现new关键字

当我们知道new关键字的内部原理后,我们就可以封装一个objectFactory函数,使其用于实现new关键字。

objectFactory函数需要传入以下几个参数:

第一个参数:构造函数名Constructor;

第二个参数及后面的参数:构造函数的参数;

实现要点:

  • new 会产生一个新对象;
  • 新对象需要能够访问到构造函数的属性,所以需要重新指定它的原型;
  • 构造函数可能会显示返回;

手撕代码:

function objectFactory() {
    var obj = new Object(); 
    Constructor = [].shift.call(arguments);// arguments 一个用于被 constructor 调用的参数列表。
    obj.__proto__ = Constructor.prototype;
    var ret = Constructor.apply(obj, arguments);
    
    // ret || obj 这里这么写考虑了构造函数显示返回 null 的情况
    return typeof ret === 'object' ? ret || obj : obj;
};
  1. new产生一个新对象;

  2. 拿到传入的参数中的第一个参数,即构造函数Constructor;

  3. 执行构造函数,并将this指向创建的空对象obj;

  4.  将传入构造函数的参数,在obj上下文中执行一遍;

  5. 如果构造函数返回一个对象,则直接返回这个对象;

使用:

function Person(name, age) {
    this.name = name
    this.age = age
}
let p = objectFactory(person, '布兰', 12)
console.log(p)  // { name: '布兰', age: 12 }

打印结果:

最后返回的打印结果显然是相同的,也实现了new关键字。

总结

以上所述是我要介绍的关于实现new关键字的内容,希望对大家有所帮助。