이전 강의에서 문제가 있었는데 toDos가 localStorage에 저장되어 있지만 브라우저를 새로고침 하면 화면에는 나타나지 않고 새로 내용을 작성하면 기존에 localStorage에 저장되어 있던 내용이 지워지고 새로 작성한 내용이 저장되는 문제가 있었다.
JSON 문자열을 JavaScript 객체로 변환할 때는 JSON
객체의 parse()
메서드를 사용한다. parse()
메서드는 JSON 문자열을 인자로 받고 결과값으로 JavaScript 객체를 반환, 예시로 작성한 JSON 문자열을 str
이라는 변수에 저장한다.
const str = `{
"name": "john",
"age": 30,
"married": false,
"hobbies": ["Basketball", "dodge ball"]
}`;
그 다음, JSON.parse()
메서드에 str
을 인자로 넘겨 호출, 결과값을 obj
라는 변수에 저장
const obj = JSON.parse(str);
obj
를 콘솔에 출력해 보면 JSON 문자열의 형태의 데이터가 JavaScript 객체의 형태로 변환되어 출력되는 것을 확인할 수 있다.
console.log(obj);
localStorage에 저장된 key를 불러오는 savedToDos
라는 이름의 변수를 생성
const savedToDos = localStorage.getItem(TODOS_KEY);
// localStorage에 저장된 key를 불러오는 변수
그리고 localStorage에 저장되어 있는 값이 없는 경우 savedToDos
는 null을 반환한다. 확인해 보자
console.log(savedToDos);
자료형 변환 없이 두 피연산자가 엄격히 같은지 판별한다. 두 피연산자가 같지 않거나, 같은 자료형이 아닐 때 true를 반환
// true
3 !== '3' // true (Number) (String) 데이터 타입이 다르다.
4 !== 3 // true (Number) (Number) 데이터 타입은 같지만 값이 다르다.
'4' !== '3' // true (String) (String) 같은 데이터 타입, 다른 값
//false
'3' !== '3' // false (String) (String) 같은 데이터 타입, 값도 일치한다.
4 !== 4 // // false (Number) (Number) 같은 데이터 타입, 값도 일치한다.
if문을 만들어준다.
if (savedToDos !== null) {
const parsedToDos = JSON.parse(savedToDos);
}
savedToDos
와 parsedToDos
를 console.log()로 확인해보자
const savedToDos = localStorage.getItem(TODOS_KEY);
console.log(savedToDos);
if (savedToDos !== null) {
// savedToDos가 localStorage에 존재할 경우
// 두 연산자가 같지 않거나, 데이터 타입이 다를경우 true를 반환
const parsedToDos = JSON.parse(savedToDos);
// localStorage에서 가져온 String을 JavaScript 객체를 반환
console.log(parsedToDos);
}
forEach()
메서드는 배열에 활용이 가능한 메서드로, array에 있는 각각의 item에 대해 함수를 실행할 수 있게 해준다. 배열의 첫 번째부터 마지막까지 반복하면서 item을 꺼낼 수 있다.
forEach()
의 문법은 아래와 같으며, 함수로 value, index, array를 전달할 수 있습니다.
arr.forEach(func(value, index, array))
forEach()
메서드를 사용해 배열을 순회하려면 콜백 함수 또는 익명 함수가 필요합니다.
const food = ['🍕','🍗','🍺','🍜','🍔']
food.forEach(function(ele, index){
console.log(ele, index)
});
// result
// 🍕 0
// 🍗 1
// 🍺 2
// 🍜 3
// 🍔 4
food.forEach(function(ele){
console.log(ele, index)
});
// result
// 🍕
// 🍗
// 🍺
// 🍜
// 🍔
//arrow 함수 표현법
food.forEach((ele, index) => console.log(ele, index))
// result
// 🍕 0
// 🍗 1
// 🍺 2
// 🍜 3
// 🍔 4
function sayHello() {
console.log("Hello");
}
const savedToDos = localStorage.getItem(TODOS_KEY);
// localStorage에 저장된 key를 불러오는 변수
if (savedToDos !== null) {
// savedToDos가 localStorage에 존재할 경우
// 두 연산자가 같지 않거나, 데이터 타입이 다를경우 true를 반환
const parsedToDos = JSON.parse(savedToDos);
// localStorage에서 가져온 String을 JavaScript 객체를 반환
parsedToDos.forEach(sayHello);
}
parsedToDos
는 localStorage에서 가져온 String을 JavaScript 객체를 반환해 주는 변수이다. parsedToDos
는 배열(Array)을 반환해 주기 때문에 forEach()
를 사용할 수 있다. forEach()
의 매개변수로 sayhello()
를 넣어준다. 그러면 parsedToDos
가 가지고 있는 각각의 item에 대해 sayhello()
를 실행한다.
sayhello()
에 의해 Hello가 3번 출력된 것을 볼 수 있다. Array에 item을 추가하면 item과 같은 수의 Hello를 출력하게 된다.
하지만 이건 이 array의 item 들에 대해 한 개의 function만 실행할 수 있게 해준다. 알아둬야 할 것은 내가 지금 어떤 item을 사용하고 있는지 모른다면 무용지물인 것이다. Hello가 5번 실행됐지만, 처리되고 있는 item이 어떤 것인지 알 수 없다. JavaScript에서 기본 제공하고 있는 기능을 사용해 보자. submit eventListener가 event(argument)를 제공하는 것처럼 JavaScript는 처리되고 있는 item 또한 그냥 제공해 준다.
function handleToDoSubmit(event) {
event.preventDefault(); // submit event의 새로고침 기능을 막아준다.
}
sayhello()
를 수정한 뒤 페이지를 새로고침하고 콘솔 창을 확인해 보자
function sayHello(item) {
console.log("this is the turn of", item);
}
parsedToDos
를 console.log로 확인해 보면 작성했던 내용이 배열로 변환되어 출력되었다. 배열로 바뀌었다는 건 forEach()
를 사용할 수 있다는 얘기이다.
forEach()
는 각각의 item에 대해 sayhello()
를 실행시킨다. 그리고 그 각각의 item에 대한 정보를 sayhello()
함수에 전달해 준다. 그리고 forEach()
를 사용하려면 콜백 함수 또는 익명함 수로 작성할 필요가 있는데 작성된 코드를 보면 현재는 콜백 함수의 형태로 forEach()
가 사용되는 걸 볼 수 있다.
function sayHello(item) {
console.log("this is the turn of", item);
}
const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos !== null) {
const parsedToDos = JSON.parse(savedToDos);
console.log(parsedToDos);
parsedToDos.forEach(sayHello);
}
forEach()
를 사용할 때, sayhello()
나 또 다른 function을 만드는 대신 익명 함수 방식으로 작성해서 코드를 짧게 쓰는 방법도 있다.
const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos !== null) {
const parsedToDos = JSON.parse(savedToDos);
console.log(parsedToDos);
parsedToDos.forEach((item) => console.log("this is the turn of", item));
// 화살표 함수로 작성
}
화면에 출력은 잘 되지만, localStroage를 보면, 새로고침 후 기존 값이 없어지는것은 여전하다. 다음강의에서 고쳐보자
const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");
const TODOS_KEY = "todos";
// localStorage key값의 이름
// newToDo를 submit 할 때마다 newToDo를 toDos라는 빈 배열에 계속 push 한다.
const toDos = [];
// toDos의 내용을 localStorage에 넣어주는 함수
function saveToDos() {
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
// JSON.stringify()를 이용해 객체나 배열을 문자열로 변환해준다.
}
// todo list가 제거되는 함수
function deleteToDo(event) {
// 현재 event.target의 부모요소를 찾아준다
const li = event.target.parentNode;
li.remove();
}
// 매개변수로 들어간 newToDo는 상수 newToDo와 관계없다
// todo list가 추가되는 함수
function paintToDo(newToDo) {
const li = document.createElement("li");
const span = document.createElement("span");
span.innerText = newToDo;
// span의 텍스트는 handleToDoSubmit() 함수에서 온 newToDo 텍스트가 된다.
const button = document.createElement("button");
button.innerText = "❌";
button.addEventListener("click", deleteToDo);
toDoList.appendChild(li);
li.appendChild(span);
li.appendChild(button);
}
function handleToDoSubmit(event) {
event.preventDefault();
// preventDefault()는 어떤 event의 기본 동작이 발생되지 않도록 막아준다.
// ex: submit event는 새로고침을 하는데 그 기능을 막아준다.
const newTodo = toDoInput.value;
// toDoInput.value의 값을 저장하는 변수
toDoInput.value = "";
// toDoInput.value에 빈 값(””)을 넣어주고 내용을 작성한 뒤 엔터를 누르면 input 창이 비워진다.
toDos.push(newTodo);
// toDoInput.value의 값을 todos배열에 push 해준다.
paintToDo(newTodo);
// 변수 newTodo의 입력값을 paintToDo() 함수에 넣어 호출
saveToDos();
// toDos의 내용을 localStorage에 넣어주는 함수
}
toDoForm.addEventListener("submit", handleToDoSubmit);
const savedToDos = localStorage.getItem(TODOS_KEY);
// localStorage에 저장된 key를 불러오는 변수
if (savedToDos !== null) {
// savedToDos가 localStorage에 존재할 경우
// 두 연산자가 같지 않거나, 데이터 타입이 다를경우 true를 반환
const parsedToDos = JSON.parse(savedToDos);
// localStorage에서 가져온 String을 JavaScript 객체를 반환
parsedToDos.forEach((item) => console.log("this is the turn of", item));
// 배열에 있는 각각의 item에 대해 함수를 실행
}