Что делает символ подчеркивания (_) перед именем свойства в геттере или сеттере класса ES6?

Я получал ошибки максимального размера стека с исходной версией моего класса (без подчеркивания), и когда я просмотрел его, я увидел несколько примеров, которые включали добавление подчеркивания к свойству класса при ссылке на него в методе получения/установки; прежде чем слишком увлекаться чем-то еще, что было рекомендовано, я просто добавил символы подчеркивания и запустил программу, и это само по себе решило проблему. Как это работает? Что делает подчеркивание в этом контексте? Насколько я понимаю, это предотвращает перегрузку стека от повторного вызова установщика в рекурсивном бесконечном цикле, но как это достигается добавлением подчеркивания?

Для справки: я использую синтаксис ES6 в приложении Node.js.

Оригинал:

    set serialNumber(serialNumber) {
        this.serialNumber = serialNumber;
    }

Исправлено:

    set serialNumber(serialNumber) {
        this._serialNumber = serialNumber;
    }

person scoffin    schedule 10.02.2020    source источник
comment
подчеркивание в качестве префикса имени поля часто используется для обозначения того, что поле является частным. Это синтаксическое соглашение, чтобы пометить его как отличное от связанного свойства.   -  person apomene    schedule 10.02.2020


Ответы (4)


Оно не имеет особого значения, но делает имя свойства различимым.

Сеттер set serialNumber обрабатывает вызовы для установки свойства serialNumber. Если вы попытаетесь установить то же самое свойство внутри установщика, то установщик рекурсивно вызывает сам себя и никогда не завершится.

Это одно из соглашений об именовании «частного» свойства данных, предназначенного для использования в классе, но оно не имеет особого значения для среды выполнения JS.

person Jeremy Roman    schedule 10.02.2020

Подчеркивание само по себе ничего не делает. Особого смысла в этом нет. Все, что он делает, это создает другое имя. Теперь вместо установки значения serialNumber вы устанавливаете его на _serialNumber. Это просто другое имя.

В вашем конкретном случае это означает, что вы не вызываете свой сеттер рекурсивно. this.serialNumber = .. вызывает установщик set serialNumber. Который затем вызывает установщик set serialNumber. Который затем вызывает установщик set serialNumber. Который затем вызывает установщик set serialNumber. До бесконечности…

person deceze♦    schedule 10.02.2020

Присвоения свойств внутри метода установки не обрабатываются иначе, чем снаружи. Поэтому, если сеттер попытается присвоить то же свойство, что и имя сеттера, он снова вызовет сеттер, что приведет к бесконечной рекурсии.

Чтобы обойти это, установщик должен установить другое свойство. Префикс подчеркивания — это просто обычное соглашение об именах, позволяющее отличить внутреннее имя свойства от видимого свойства.

person Barmar    schedule 10.02.2020

Вы очень плохо понимаете :)

Нет никакой связи _ с логикой, это просто обозначение.

Пользователь _ для частных переменных и имени свойства без подчеркивания, например, для возраста, пола

class Person {
  private _age: number;
  private _gender: string;

  get age() { return this._age }
  set age(personAge: number) { this._age = personAge }

  get gender() { return this._gender }
  set age(personGender: string) { this._gender = personGender }
}

Надеюсь, это поможет вам понять концепцию _.

person Ali Adravi    schedule 10.02.2020