#javascript #oop
#javascript #рекурсия #getter-сеттер
Вопрос:
Может кто-нибудь, пожалуйста, помочь мне понять значение символа ‘_’ в установщиках и геттерах javascript. Например, у меня есть следующий код, который работает нормально.
var user = {
get name() {
return this._name;
},
set name(value) {
this._name = value;
}
};
var me = user;
me.name = "Rob";
alert(me.name);
Но если я уберу подчеркивание, чтобы мой код выглядел следующим образом, тогда мой код не будет работать, и я получаю сообщение об ошибке в консоли браузера с указанием «Ошибка диапазона: превышен максимальный размер стека вызовов».
var user = {
get name() {
return this.name;
},
set name(value) {
this.name = value;
}
};
var me = user;
me.name = "Rob";
alert(me.name);
</script>
Может кто-нибудь, пожалуйста, объяснить мне, что «_» делает в этой ситуации?
Комментарии:
1.
_name
( с подчеркиванием) является закрытым для вашегоuser
объекта, ноname
( без подчеркивания) является общедоступным и изменяемым из внешней области. итак, по сути, вы вызываетеname
извне, который затем снова вызывает себя и, следовательно, становится рекурсивным.2. в js нет частных / общедоступных свойств, это просто конфликт имен. вам нужен параметр состояния отдельно от вашего свойства access для геттеров.
Ответ №1:
Это довольно просто. В вашем втором примере, get
, вызывает себя.
Поскольку вы ссылаетесь на свойство me.name
, JavaScript нуждается в get
этом свойстве. Когда это происходит, запускается геттер. Используя ваш второй пример, JavaScript вызывает средство получения, но затем ему предлагается сделать то же самое: получить свойство, для обработки которого оно предназначено. Функция всегда вызывает саму себя, что делает ее бесконечно рекурсивной.
Однако в первом примере свойство, которое извлекается в получателе, не совпадает с тем, которое первоначально запустило получатель. Значение, получаемое получателем, является своего рода компонентом хранилища, чтобы избежать проблемы рекурсии, упомянутой выше. Два свойства не имеют фактической связи между ними, даже если они имеют похожие имена.
Та же идея применима и к сеттеру.
Комментарии:
1. Вопрос — является ли это соглашением в js, что любое свойство, управляемое с помощью getter / setter, должно быть добавлено с подчеркиванием?
2. @AnkurMarwaha Иногда используется для частных полей, которые таковыми и являются. Ответ Анибе Агамы говорит об этом подробнее.
3. Допустим, у меня есть свойство
this.name
, и я пытаюсь получить к нему доступ сget name
помощьюthis.name
, тогда происходит рекурсия, это понятно. Но, сделав только одно изменение внутриget name
, т.е. Используяthis._name
его, все работает нормально. Итак, похоже, что js добавил что-то внутренне для идентификации свойства_
с помощью обычного имени свойства. Это то, в чем я все еще не уверен.4. @AnkurMarwaha Используя
_name
вместоname
, вы используете совершенно другую переменную. Вы можете использовать любое другое имя переменной, кромеname
. При использованииname
JavaScript необходимо вызвать его getter , который является текущей функцией, что вызывает бесконечную рекурсию. Это то же самое, что и это:function getname() {return getname()}
. Если вы используете_name
which не имеет getter , вы просто получаете значение.5. Спасибо за ваше терпение, чувак, ты потрясающий. Я понял, что совершаю какую-то глупую ошибку.
Ответ №2:
Это соглашение об именовании, используемое для идентификации частных переменных или свойств. Это _
не имеет особого значения для JS.
Из руководства по стилю JavaScript Airbnb:
Используйте начальный символ подчеркивания _ при именовании частных свойств.