function createStore(reducer){ let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined let cbs = [] //массив подписчиков const getState = () => state //функция, возвращающая переменную из замыкания const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка const dispatch = action => { const newState = reducer(state, action) //пробуем запустить редьюсер if (newState !== state){ //проверяем, смог ли редьюсер обработать action state = newState //если смог, то обновляем state for (let cb of cbs) cb() //и запускаем подписчиков } } return { getState, //добавление функции getState в результирующий объект dispatch, subscribe //добавление subscribe в объект } } function reducer(state, {type, ШО, СКОКА, БАБЛО}){ //объект action деструктуризируется на три переменных if (!state){ //начальная уборка в ларьке: return { пиво: {count : 100, price: 25}, чипсы: {count : 100, price: 20}, сиги: {count: 100, price: 10}, касса: 0 } } if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то: if(СКОКА <= state[ШО].count && БАБЛО >= state[ШО].price * СКОКА){ return { ...state, //берем все что было из ассортимента [ШО]: {...state[ШО], count: state[ШО].count - СКОКА}, //и уменьшаем то, что покупается на количество касса: state.касса + state[ШО].price * СКОКА } } } return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть } function createTable (obj){ table.innerText = '' for(let [key, value] of Object.entries(obj)){ let tr = document.createElement('tr'); let td = document.createElement('td'); td.innerText = key tr.append(td); table.append(tr); if(typeof value === 'object'){ for(let [key1,value1] of Object.entries(value)){ let td = document.createElement('td'); td.innerText = key1 + ' : ' + value1; tr.append(td); } } else { let td = document.createElement('td'); td.innerText = value; tr.append(td); } } } const store = createStore(reducer); createTable(store.getState()) for(let [key] of Object.entries(store.getState())){ if (key !== 'касса'){ let option = document.createElement('option'); option.innerText = key shop.append(option) } } store.subscribe(()=>createTable(store.getState())); store.subscribe(() => console.log(store.getState())); btnBuy.onclick = (() => store.dispatch({type: 'КУПИТЬ', ШО : shop.value, СКОКА: inputValue.value, БАБЛО: inputMoney.value }))