Почему значение 'this' не определено в функции внутри конструктора? - PullRequest
0 голосов
/ 23 апреля 2020

Я пытаюсь реализовать свою собственную версию обещаний в Node.js для практических целей. Я получаю результаты, которые я не понимаю. Я создал следующий код, чтобы показать, в чем заключается моя проблема.

class Person {
  constructor(name) {
    this.name = name

    // console.log(this)

    function sayName() {
      console.log(this.name)
    }

    sayName()
  }
}

const joe = new Person('Joe')

Я получаю сообщение об ошибке 'TypeError: Невозможно прочитать свойство' name 'из undefined' . Когда я вызываю конструктор, значением this является вновь созданный объект, поэтому, если я раскомментирую закомментированную строку, я выйду из этой строки из-за объекта, который создается.

Когда я вызываю Функция sayName, я ожидаю, что значение this будет глобальным объектом. В большинстве случаев, которые я видел, можно предположить, что когда вы начинаете определять новую функцию, значением this является глобальный объект. Но здесь это 'undefined', поэтому я получаю сообщение об ошибке.

Если я делаю то же самое без использования ключевого слова class, и я помещаю функцию sayName в конструктор, она ведет себя так, как ожидается, и регистрирует ' undefined ', так как для глобального объекта не определено свойство name.

function Person(name) {
  this.name = name

  function sayName() {
    console.log(this.name)
  }

  sayName()
}

const joe = new Person('Joe')

Я знаю, что есть некоторые механизмы безопасности, которые вы запускаете при использовании ключевого слова class. Мое лучшее предположение, что разница между двумя примерами в том, что один из них срабатывает без моего ведома.

Скажите, пожалуйста, в чем причина различия, почему значение 'this' не определено в первом примере! Спасибо

1 Ответ

0 голосов
/ 23 апреля 2020

Похоже, объявления функций function() {} теряют this контекст при определении внутри конструктора. Я предполагаю, что это как-то связано с тем, как constructor реализовано за кулисами. Вы можете добавить его обратно с помощью

sayName = sayName.bind(this);
sayName();

или, возможно, лучше просто не определять функции в конструкторе и определять его как метод класса:

sayName() {
  return this.name;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...