<script>
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");
const TODOS_KEY = "todos"
let toDos = [];
function saveToDos() {
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}
function deleteToDo(event) {
const li = event.target.parentElement;
li.remove();
toDos = toDos.filter(toDo => toDo.id !== parseInt(li.id));
saveToDos();
}
function paintToDo(newTodoObj) {
const li = document.createElement("li");
li.id = newTodoObj.id;
const span = document.createElement("span");
span.innerText = newTodoObj.text;
const button = document.createElement("button");
button.innerText = "❌";
button.addEventListener("click", deleteToDo);
li.appendChild(span);
li.appendChild(button);
toDoList.appendChild(li);
}
function handleToDoSubmit(event) {
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value = "";
const newTodoObj = {
text: newTodo,
id: Date.now()
};
toDos.push(newTodoObj);
paintToDo(newTodoObj);
saveToDos();
}
toDoForm.addEventListener("submit", handleToDoSubmit);
const savedToDos = localStorage.getItem(TODOS_KEY);
if(savedToDos !== null) {
const parsedToDos = JSON.parse(savedToDos);
toDos = parsedToDos;
parseToDos.forEach(paintToDo);
}
</script>
❗️ function paintToDo(newTodoObj)에서 파라미터의 이름을 다르게 해도 handleToDoSubmit에서 넘겨준 인수 값이 newTodoObj이므로 코드의 실행에는 문제가 없다.
: 인수로 주어진 callback 함수의 테스트를 통과하는 모든 요소를 모아서 새로운 배열로 만들어 반환한다.
✓ callback 함수의 결과가 true일 때 해당 요소를 유지하고, false이면 제외한다.
↳ filter()는 배열 내 각 요소에 대해 callback 함수를 호출해서 요소가 callback 함수에서 true를 반환할 때만 새로운 배열에 "추가"되고, 아니면 건너뛰어 버리는 방식으로 새로운 배열을 만든다.
예제1)
<script>
function coolFilter(item) {
return !== 3
}
[1, 2, 3, 4, 5, 6].filter(coolFilter);
</script>
↳ [1, 2, 4, 5, 6]을 새로운 배열로 만든다.
예제2)
<script>
const arr = ["avocado", "potato", "chocolate"];
function foodFilter(favFood) {
return food !== "potato";
}
arr.filter(foodFilter);
const foodFilter = arr.filter(favFood => favFood !== "potato");
</script>
↳ [”avocado”, “chocolate”]을 새로운 배열로 만든다.
💡 JSON의 일반적인 용도는 웹 서버와 데이터를 교환하는 것이다. 웹 서버에서 데이터를 보낼 때는 타입이 문자열이어야 한다.
stringify()는 JavaScript의 object를 String으로 변환한다.<script> function saveToDos() { localStorage.setItem(TODOS_KEY, JSON.stringify(toDos)); } </script>
↳ localStorage에 배열 toDos의 요소를 문자열로 변환해서 "todos"라는 key의 값으로 저장했다.
💡 웹 서버에서 데이터를 수신할 때 데이터의 타입은 항상 문자열이다.
parse()는 JSON 문자열의 구문을 분석하고, 그 결과에서 JavaScript 값이나 object를 생성한다.<script> const savedToDos = localStorage.getItem(TODOS_KEY); if(savedToDos !== null) { const parsedToDos = JSON.parse(savedToDos); toDos = parsedToDos; parseToDos.forEach(paintToDo); } </script>
↳ localStorage에 이전에 저장된 To-do 리스트가 있다면, 파싱해서 객체로 만든 다음에, forEach 함수로 각 요소마다 paintToDo 함수를 실행해서 화면에 보여준다.
An arrow function expression is a compact alternative to a traditional function expression.
<script> parseToDos.forEach((item) => console.log("This is the turn of ", item)); </script>