function reducer(state, { type, ШО, СКОКА }) { // объект action деструктуризируется на три переменных if (!state) { // начальная уборка в ларьке: return { пиво: { "number": 100, "price": 10 }, чипсы: { "number": 100, "price": 15 }, сиги: { "number": 100, "price": 5 }, бабло: { "в ларьке": 5, "в кармане": prompt("Введите сколько у вас денег в кармане", 0) } } } if (type === 'КУПИТЬ' && (state[ШО]["number"] - СКОКА) >= 0 && state["бабло"]["в кармане"] - state[ШО]["price"] * СКОКА >= 0) { //если тип action - КУПИТЬ, то: return { ...state, //берем все что было из ассортимента [ШО]: { ["number"]: state[ШО]["number"] - СКОКА, ["price"]: state[ШО]["price"] },// и уменьшаем то, что покупается на количество ["бабло"]: { ["в кармане"]: state["бабло"]["в кармане"] - state[ШО]["price"] * СКОКА, ["в ларьке"]: state["бабло"]["в ларьке"] + state[ШО]["price"] * СКОКА } } } return state // если мы не поняли, что от нас хотят в `action` - оставляем все как есть } 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 в объект } } const store = createStore(reducer); store.subscribe(() => console.log(store.getState())); store.subscribe(() => createTable()); const tovaryEl = document.getElementById("tovary"); const numberEl = document.getElementById("number"); const tableEl = document.getElementById("table"); tableEl.border = 1; for (let key in store.getState()) { if (key === "бабло") continue; let optionEl = document.createElement("option"); optionEl.innerHTML = key; tovaryEl.appendChild(optionEl); } const buttonEl = document.getElementById("button"); buttonEl.onclick = () => { store.dispatch({ type: "КУПИТЬ", ШО: tovaryEl.value, СКОКА: numberEl.value }); } createTable(); function createTable() { tableEl.innerHTML = ""; createTr("Наименование", "Количество", "Цена за единицу"); for (let [key, value] of Object.entries(store.getState())) { if (key === "бабло") continue; createTr(key, value.number, value.price); } createTr("Касса", "в ларьке:", store.getState()["бабло"]["в ларьке"]); createTr("Касса", "в кармане:", store.getState()["бабло"]["в кармане"]); } function createTr(td1, td2, td3) { const trEl = document.createElement("tr"); const td1El = document.createElement("td"); const td2El = document.createElement("td"); const td3El = document.createElement("td"); td1El.innerText = td1; td2El.innerText = td2; td3El.innerText = td3; trEl.append(td1El, td2El, td3El); tableEl.appendChild(trEl); }