Геттеры и сеттеры
Изучаю основы ООП, классы. Столкнулся с проблемой, ответ на который не могу нагуглить (возможно ищу не по тем ключам, так как тема для меня относительно новая). Написал объект с одним приватным свойством и методом для его получения, когда пользователь кликает по одной из двух кнопок выбора пола. Все работает.
let user = { _sex: '', setSex: function () { document.querySelectorAll('.sex-btn').forEach(btn => { btn.addEventListener('click', () => { this._sex = btn.value; }); }); } }; user.setSex(); Но при попытке создания геттера для класса по аналогии возникли трудности. Не понимаю, как можно сделать установку приватного свойства класса при переборе псевдомассива кнопок или любых других элементов. class User { constructor(sex) { this._sex = sex; } set sex(sex) { // откуда будет браться параметр для сеттера не пойму document.querySelectorAll('.sex-btn').forEach(btn => { btn.addEventListener('click', () => { user.sex = btn.value; }); }); } get sex() { return this._sex; } } let user = new User(); user.sex // что сюда передавать тоже не пойму |
DVV,
<input class="sex-btn" type="button" value="m"> <input class="sex-btn" type="button" value="w"> <script> class User { constructor(sex) { this._sex = sex; document.querySelectorAll('.sex-btn').forEach(btn => { btn.addEventListener('click', () => { console.log('before', this.sex) this.sex = btn.value; console.log('after', this.sex) }); }); } set sex(sex) { this._sex = sex; } get sex() { return this._sex; } } let user = new User('test'); user.sex = 123// что сюда передавать тоже не пойму </script> |
Круто. Все работает. Спасибо огромное. Скажите, пожалуйста, то есть всегда в случае псевдомассива в классе надо геттеры и сеттеры в конструкторе писать?
И еще, а в User('test') что означает test? Просто в качестве временного свойства или его можно пустым оставлять? И зачем тогда set sex(sex) { this._sex = sex; } Код и без него работает С одной стороны все вроде понятно, а с другой - что-то я запутался |
DVV,
придут люди которые в этом разбираются, может ответят на ваши вопросы более досконально. Цитата:
Цитата:
Цитата:
|
Цитата:
Его совершенно спокойно можно читать и изменять. К вашим примерам из первого сообщения... user._sex = "와"; console.log(user._sex); // выводит "와" Конструкции вида... set sex(sex) { this._sex = sex; } get sex() { return this._sex; }могут быть заменены на sex = "";или this.sex = "";в конструкторе... <input class="sex-btn" type="button" value="m"> <input class="sex-btn" type="button" value="w"> <script> class User { constructor(sex) { this.sex = sex; document.querySelectorAll('.sex-btn').forEach(btn => { btn.addEventListener('click', () => { console.log('before', this.sex) this.sex = btn.value; console.log('after', this.sex) }); }); } } let user = new User('test'); user.sex = 123; </script> |
То, как вы используете понятие приватность, не имеет особого смысла. Для лучшего контроля над свойством его делают приватным, а запись значения осуществляется через специальный метод, который называют, если записать при помощи IPA, [ˈsɛɾəɹ] (setter method) и чтение значения осуществляется через специальный метод, который называют [ˈkɛɾəɹ] или [ˈɡɛɾəɹ] (getter method).
При помощи приватного свойства... <input class="sex-btn" type="button" value="m"> <input class="sex-btn" type="button" value="f"> <script> class User { #sex = null; constructor(sex) { this.sex = sex; document.querySelectorAll('.sex-btn').forEach(btn => { btn.addEventListener('click', () => { console.log('before', this.sex) this.sex = btn.value; console.log('after', this.sex) }); }); } set sex(sex) { if(sex !== "m" && sex !== "f") throw new Error(`The provided value '${sex}' is not a valid enum value of type UserSex—use 'm' or 'f'.`); this.#sex = sex; } get sex() { return this.#sex; } } let user = new User('m'); // неправильные значения типа test будут вызывать исключение user.sex = 123; </script> При помощи ассоциативного массива... (подойдет для браузеров, где не поддерживаются приватные свойства) <input class="sex-btn" type="button" value="m"> <input class="sex-btn" type="button" value="f"> <script> const User = (() => { const userSex = new WeakMap(); return class User { constructor(sex) { this.sex = sex; document.querySelectorAll('.sex-btn').forEach(btn => { btn.addEventListener('click', () => { console.log('before', this.sex) this.sex = btn.value; console.log('after', this.sex) }); }); } set sex(sex) { if(sex !== "m" && sex !== "f") throw new Error(`The provided value '${sex}' is not a valid enum value of type UserSex—use 'm' or 'f'.`); userSex.set(this, sex); } get sex() { return userSex.get(this); } } })(); let user = new User('m'); user.sex = 123; </script> Теперь в поле sex хранится всегда правильное значение — либо 'm', либо 'f'. Поскольку класс User похож на модель, то скорей всего вам нужно вынести работу с DOM из его определения. |
Про геттеры и сеттеры я знаю, но гдя я только не читал про них. Везде даны простейшие примеры, которые зачастую с одного ресурса учебного копипастятся другими. Ничего подобного с псевдомассивами я нигде не нашел. Был бы очень благодарен, если подскажите ресурсы, где можно об этом подробно почитать.
А зачем нужна эта строка и именно знак #? #sex = null; Кроме того, попробовал закомментировать геттер и сеттер в первом примере с 19 по 28 строку. Все работает и без них. |
Цитата:
Цитата:
|
Понял. Буду разбираться дальше в ООП. Спасибо)))
|
Часовой пояс GMT +3, время: 06:23. |