//1. Store Class // Переделайте задание Store на синтаксис ES6-классов: // { // // }class Store { // #reducer; // #state; // #cbs = [] // // constructor(reducer) { // this.#reducer = reducer // this.#state = (undefined, {} ) // } // getState () { // return this.#state // } // // subscribe (cb) { // this.#cbs.push(cb) // return (cb) => { // this.#cbs = this.#cbs.filter(c => c !== cb) // } // } // // dispatch (action) { // const newState = this.#reducer(this.#state, action) // if (newState !== this.#state) { // this.#state = newState // for (let cb of this.#cbs) // cb() // } // } // // get state () { // return this.#state // } // } //2. Password Class // По аналогии, переделайте код задания Password в синтаксис классов ES6. Спрячьте все что можно в #приватные свойства // объектов класса. Проверьте на форме логина - ведь она использует Password // { // class Password { // #parent // #open // #inputPassword = document.createElement('input') // #btnSee = document.createElement('input') // #onChange // #onOpenChange // // onchange = () => this.setOpen(this.#btnSee.checked) // // constructor(parent, open) { // this.#parent = parent // this.#open = open // // // this.#parent.append(this.#inputPassword) // this.#btnSee.type = 'checkbox' // this.#parent.append(this.#btnSee) // this.#btnSee.onchange = this.onchange // } // // set onChange(value) { // this.#onChange = value // } // // set onOpenChange(value) { // this.#onOpenChange = value // } // // setValue(value) { // this.#inputPassword.value = value // } // // setOpen(open) { // this.#open = open // this.#inputPassword.type = this.#open ? 'text' : 'password' // } // // getValue() { // return this.#inputPassword.value // } // // getOpen() { // return this.#inputPassword.type // } // } // // const p = new Password(document.body, true) // p.onChange = data => console.log(data) // p.onOpenChange = open => console.log(open) // // p.setValue('qwerty') // console.log(p.getValue()) // // p.setOpen(false) // console.log(p.getOpen()) // } // StoreThunk Class // Унаследуйте класс Store в новом классе StoreThunk. Новый класс должен перекрывать метод dispatch, проверять тип // переданного экшона и если это функция, запускать её, передав у неё this.dispatch и this.getState. Данное условие // написано тут. Учтите, что в thunk передаются функции dispatch и getState без объекта до точечки, а эти методы в // классе Store являются обычными функциями, склонными к потере this. Для прибития this намертво к функции используйте // метод bind. Посмотреть можно тут и тут Проверьте на модульном проекте { class Store { #reducer; #state; #cbs = [] constructor(reducer){ this.#reducer = reducer this.#state = reducer(undefined, {}) } getState(){ return this.#state } subscribe(cb){ (this.#cbs.push(cb), () => this.#cbs = this.#cbs.filter(c => c !== cb)) } dispatch(action){ let newState = this.#reducer (this.#state,action) if (newState !== this.#state) { this.#state = newState for ( let cb of this.#cbs) { cb () } } } get state () { return this.#state } } class StoreThunk extends Store { dispatch(action) { //если это функция, if (typeof action === 'function') { //запускать её, передав у неё this.dispatch и this.getState; используйте метод bind return action(this.dispatch.bind(this), this.getState.bind(this)) } else { super.dispatch(action) } } } } //RGB Class // Напишите класс RGB, приватными свойствами которого являются три числа #r, #g, #b. Класс должен обладать следующими // геттерами и сеттерами: class RGB { #r; #g; #b; set r (newR) { if (typeof newR !="number" || !(newR>= 0 && newR<=255)) { throw new RangeError('Неправильный формат или диапазон') } else { this.#r = newR } } set g (newG) { if (typeof newG !="number" || !(newG>= 0 && newG<=255)) { throw new RangeError('Ошибка в типе значений') } else { this.#g = newG } } set b (newB) { if (typeof newB != 'number' || !(newB>= 0 && newB<=255)) { throw new RangeError('Ошибка в типе значений') } else { this.#b = newB } } }