В последнее время я изучал некоторое функциональное программирование на JavaScript и хотел проверить свои знания, написав простое приложение ToDo с простым функциональным программированием. Тем не менее, я не уверен, как можно хранить состояние списка чисто функциональным способом, поскольку функции не имеют побочных эффектов. Позвольте мне объяснить на примере.
Допустим, у меня есть конструктор с именем "Item", у которого просто есть задача, которую нужно выполнить, и UUID для идентификации этого элемента. У меня также есть массив items, который содержит все текущие элементы, а также функции «add» и «delete», например:
function Item(name){
this.name = name;
this.uuid = uuid(); //uuid is a function that returns a new uuid
}
const items = [];
function addItem(name){
const newItem = new Item(name);
items.push(newItem);
}
function deleteItem(uuid){
const filteredItems = items.filter(item => item.uuid !== uuid);
items = filteredItems
}
Теперь это работает отлично, но, как вы видите, функции не являются чистыми: они имеют побочные эффекты и ничего не возвращают. Имея это в виду, я пытаюсь сделать его таким:
function Item(name){
this.name = name;
this.uuid = uuid(); //uuid is a function that returns a new uuid
}
const items = [];
function addItem(array, constructor, name){
const newItem = new constructor(name);
return array.concat(newItem);
}
function removeItem(array, uuid){
return array.filter(item => item.uuid !== uuid);
}
Теперь функции чистые (или, как мне кажется, поправьте меня, если я ошибаюсь), но для сохранения списка элементов мне нужно создавать новый массив каждый раз, когда я добавляю или удаляю элемент. Мало того, что это кажется невероятно неэффективным, но я также не уверен, как правильно это реализовать. Допустим, я хочу добавлять новый элемент в список при каждом нажатии кнопки в DOM:
const button = document.querySelector("#button") //button selector
button.addEventListener("click", buttonClicked)
function buttonClicked(){
const name = document.querySelector("#name").value
const newListOfItems = addItem(items, Item, name);
}
Это опять не чисто функционально, но есть еще одна проблема: это не будет работать должным образом, потому что каждый раз, когда функция вызывается, она будет создавать новый массив, используя существующий массив "items", который сам по себе не является меняется (всегда пустой массив). Чтобы исправить это, я могу думать только о двух решениях: изменить исходный массив «items» или сохранить ссылку на текущий массив items, оба из которых включают функции, имеющие некоторые побочные эффекты.
Я пытался найти способы реализовать это, но безуспешно. Есть ли способ исправить это с помощью чистых функций?
Заранее спасибо.