AI智能
改变未来

面试官:熟悉JS中的new吗?能手写实现吗?

[toc]

⚠ 预备知识:

  1. 了解原型和原型链
  2. 了解
    this

    绑定

1 new 运算符简介

MDN文档:

new

运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

class Person {constructor(name) {this.name = name;}}// 创建自定义对象类型的实例const person = new Person(\'小明\')// 创建具有构造函数的内置对象的实例const date = new Date()

new

的作用:创建对象的实例

2 new 究竟干了什么事

上面说了

new

的作用是创建对象的实例,那么它究竟是怎么创建实例的,内部干了哪几件事?

new Person()

为例,当它执行时,会发生以下事情:

  1. 创建一个空的简单
    JS

    对象

const obj = {}
  1. 给这个对象添加属性
    __proto__

    ,并将该属性链接到构造函数的原型对象

obj.__proto__ = Person.prototype
  1. 调用构造函数
    Person

    ,并将

    this

    绑定到新创建的对象

    obj
Person.apply(obj)
  1. 如果构造函数没有显式返回一个对象,则返回新创建的对象,即
    obj

3 模拟实现 new 运算符

如上所述,

new

运算符就干了这么

4

件事,下面我们就根据这4个步骤用函数来模拟实现

new

(面试手写代码)

const _new = function(constructor, ...args) {const obj = {}obj.__proto__ = constructor.prototypeconst res = constructor.apply(obj, args)// 这一步在"补充"中会详细解释return res instanceof Object ? res : obj}

代码非常简单,就是按照上面

4

步,一步一步写就可以了

4 补充

  1. ES5

    提供了

    Object.create

    方法,该方法可以创建一个对象,并让新对象的

    __proto__

    属性指向已经存在的对象。

    所以我们可以使用这个方法合并1、2两步

const obj = Object.create(constructor.prototype)// 等价于const obj = {}obj.__proto__ = constructor.prototype
  1. 对于第

    4

    步,再解释一下

      如果构造函数没有显式

      return

      (通常情况)

      那么

      person

      新创建的对象

      obj

    • 如果构造函数返回的不是一个对象,比如

      1

      "abc"

      那么

      person

      新创建的对象

      obj

function Person() {...return 1}
  • 如果构造函数显式返回了一个对象,比如

    {}

    function() {}

    那么

    person

    不是新创建的对象

    obj

    了,而是显式

    return

    的这个对象

function Person() {// 函数也是对象return function() {}}

所以我们在

_new

函数最后一句代码是:

return res instanceof Object ? res : obj
  1. 注意,模拟实现的函数
    _new

    传入的参数只能是构造函数,不能是类

class Animal {  ...}_new(Animal)// 会报错:Class constructor Animal cannot be invoked without \'new\'// 类只能通过new来创建实例
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 面试官:熟悉JS中的new吗?能手写实现吗?