Новый оператор позволяет разработчикам создавать экземпляр определяемого пользователем типа объекта или одного из встроенных типов объектов.

Прежде чем копаться в подкапотном пространстве нового оператора, было бы неплохо, если бы вы прочитали https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new и имели базовое понимание нового оператора в Javascript.

Давайте сразу к теме. Как работает оператор new? 🤔

👏🏻 Ответить

Он имеет 3 этапа:

  1. Создать: он создает новый объект и устанавливает свойство [[prototype]] этого объекта в качестве свойства prototype функции-конструктора.
  2. Execute: указывает this на вновь созданный объект и выполняет функцию конструктора.
  3. Возврат: в обычном случае возвращается только что созданный объект. Однако, если вы явно возвращаете non-null object or a function , вместо этого возвращается это значение. Следует отметить, что если вы возвращаете ненулевое значение, но это не объект (например, значение символа, неопределенное значение, NaN), это значение игнорируется и возвращается вновь созданный объект.

Напишите, что у вас есть new

Чтобы было понятнее, давайте напишем собственный new. Мы просто назовем его myNew:

function myNew(constructor, ...args) {
  const obj = {}
  Object.setPrototypeOf(obj, constructor.prototype)
  
  const returnedVal = constructor.apply(obj, args)
  
  if (
    typeof returnedVal === 'function' 
    || (typeof returnedVal === 'object' && returnedVal !== null)) {
      return returnedVal
  }
  return obj
}

Тесты

Тест первый: обычный случай 👏🏻

function Boy(name) {
    this.name = name
    console.log('this', this) // Boy { name: 'Quizme Boy' }
}
  
const boy = myNew(Boy, 'Quizme Boy') 
console.log('boy', boy) // Boy { name: 'Quizme Boy' }

Второй тест: возвращаемое значение 🤔

Когда мы явно возвращаем ненулевой объект, он возвращает этот объект.

function Boy(name) {
    this.name = name
    console.log('this', this) // Boy { name: 'Quizme Boy' }
    return {
      hello: '123'
    }
}
  
const boy = myNew(Boy, 'Quizme Boy') 
console.log('boy', boy) // Boy { hello: '123' }

Когда мы явно возвращаем функцию, она возвращает эту функцию.

function Boy(name) {
    this.name = name
    console.log('this', this) // Boy { name: 'Quizme Boy' }
    return () => {
      hello: '123'
    }
}
  
const boy = myNew(Boy, 'Quizme Boy') 
console.log('boy', boy) // Boy { hello: '123' }

Однако, когда мы явно возвращаем значение Symbol, оно игнорируется и возвращается первоначально созданный объект. 🤔

function Boy(name) {
    this.name = name
    console.log('this', this) // Boy { name: 'Quizme Boy' }
    return Symbol('123)
}
  
const boy = myNew(Boy, 'Quizme Boy') 
console.log('boy', boy) // Boy { name: 'Quizme Boy' }

👏🏻 Бинго! Мы сделали свои собственные new! 😄

Это все для этой темы.

Не стесняйтесь обращаться, если у вас есть какие-либо вопросы.