전의 내용과 이어서 진행, PaintToDo라는 함수를 만들고 매개변수로 newToDo를 입력한다.
function paintToDo(newTodo) {} // 매개변수로 들어간 newToDo는 상수 newToDo와 관계없다
그리고 handleToDoSubmit()
를 paintToDo()
를 호출하고 newToDo
를 보낸다.
function paintToDo(newTodo) {
console.log("i will", newTodo);
}
function handleToDoSubmit(event) {
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value = "";
paintToDo(newTodo);
}
newToDo
는 input의 value를 비우기 전의 값을 나타내는 변수, 그 입력값을 paintToDo()
에 넣어서 호출한다. 입력값을 넣어서 console.log()로 확인해 보면 input에서 value를 얻어서 paintToDo()
라는 새로운 함수에 그 값을 보낸 것을 확인할 수 있다.
paintToDo()
함수가 하는 일은 todo list를 만드는 일, <li>
를 만들어 그 <li>
를 <ul>
에 추가할 것이다. paintToDo()
함수에 작성해보자.
function paintToDo(newTodo) {
const li = document.createElement("li");
}
그리고 <li>
내부에 <span>
을 만든다. 나중에 ToDo를 삭제하는 <button>
을 만들 것이기 때문이다.
<ul id="todo-list">
<!-- example -->
<li>
<span>Hello</span>
<button></button>
</li>
</ul>
두 가지 element를 만들었다. 그리고 <li>
내부에 appendChild()
를 사용해서 <span>
을 넣어준다. <li>
는 <span>
이라는 자식요소를 갖게되었다. 그 다음 span.innerText = newToDo를 넣었다. 여기서 <span>
의 텍스트는 handleToDoSubmit()
함수에서 온 newToDo 텍스트가 된다. console.log()로 확인해보자
function paintToDo(newToDo) {
const li = document.createElement("li");
const span = document.createElement("span");
li.appendChild(span);
span.innerText = newToDo;
console.log(li);
}
내용을 입력하고 엔터를 하면, <li>
안에<span>
있고 <span>
안에는 작성한 내용이 보인다.
이제 todo list를 추가하는 코드를 작성해 보자, toDoList
내부에 appendChild()
를 사용해서 <li>
넣어준다.
function paintToDo(newToDo) {
const li = document.createElement("li");
const span = document.createElement("span");
li.appendChild(span);
span.innerText = newToDo;
toDoList.appendChild(li);
}
todo list가 추가되는 것을 확인할 수 있다. 아무것도 입력하지 않으면 todo list가 추가되지 않는다. HTML에서 input에 required를 넣었기 때문에 아무것도 입력하지 않는 경우 경고창이 나온다.
todo list는 추가되고 삭제되어야 하는데 지금은 추가만 할 수 있고 제거는 할 수가 없는 상황이다. 새로고침을 하면 작성한 내용이 유지되지 않고 사라져버린다. 다음 강의에서 고쳐보자.
const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");
toDoForm.addEventListener("submit", handleToDoSubmit);
// 매개변수로 들어간 newToDo는 상수 newToDo와 관계없다
// todo list가 추가되는 함수
function paintToDo(newToDo) {
const li = document.createElement("li");
const span = document.createElement("span");
li.appendChild(span);
span.innerText = newToDo;
// span의 텍스트는 handleToDoSubmit() 함수에서 온 newToDo 텍스트가 된다.
toDoList.appendChild(li);
}
// submit 했을 때 실행될 함수
function handleToDoSubmit(event) {
event.preventDefault();
// preventDefault()는 어떤 event의 기본 동작이 발생되지 않도록 막아준다
// ex: submit event는 새로고침을 하는데 그 기능을 막아준다
const newTodo = toDoInput.value;
// toDoInput.value의 값을 저장하는 변수
toDoInput.value = "";
// toDoInput.value에 빈 값(””)을 넣어주고 엔터를 누르면 input 창이 비워진다
paintToDo(newTodo);
// 변수 newTodo의 입력값을 paintToDo() 함수에 넣어 호출
}
🤔❓❓
toDoForm.addEventListener("submit", handleToDoSubmit); function paintToDo(newToDo) { const li = document.createElement("li"); const span = document.createElement("span"); li.appendChild(span); span.innerText = newToDo; toDoList.appendChild(li); } function handleToDoSubmit(event) { event.preventDefault(); const newTodo = toDoInput.value; toDoInput.value = ""; paintToDo(newTodo); }
💡 궁금한 게 생겼다. JavaScript 코드는 순서대로 실행되는 걸로 알고 있는데 강의를 보며 궁금한 건 이벤트 리스너를 실행하면 그 안에 함수가 호출되는데 코드를 보면 호출된 함수가 이벤트 리스너보다 밑에 작성되어 있는데 이 둘의 위치를 바꾸더라도 똑같이 작동했다. 이벤트 리스너가 실행되기 전에 호출될 함수가 먼저 존재해야 하는 것이 아닌가 의문이 들었다. 그래서 검색하다 함수의 선언 방식에 대해 알게 되었다.
📌 함수의 선언 방식
함수를 선언하는 방식은 2가지가 있다. 함수 선언식과 함수 표현식
◎ 함수 선언식(function declartion)
함수명이 정의되어 있고, 별도의 할당 명령이 없는 것
hoisted(); // logs "foo" function hoisted() { console.log("foo"); }
◎ 함수 표현식
정의한 function을 별도의 변수에 할당하는 것
notHoisted(); // TypeError: notHoisted is not a function let notHoisted = function() { console.log("let"); };
📌 함수 선언식과 함수 표현식의 차이점
함수 선언식은 호이스팅에 영향을 받지만, 함수 표현식은 호이스팅에 영향을 받지 않습니다.
함수 선언식은 코드를 구현한 위치와 관계없이 자바스크립트의 특징은 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어 올려진다.
함수 표현식은 별도의 변수에 할당하게 되는데, 변수는 선언부와 할당부를 나누어 호이스팅 하게 됩니다. 선언부만 호이스팅 하게 된다.
sum(50, 50); // 100 minus(100, 50); // Uncaught TypeError: minus is not a function function sum(a, b) { // 함수 선언식 return a + b; } var minus = function (a, b) { // 함수 표현식 return a - b; };
위는 호이스팅이 마치게 되면 다음과 같이 표현할 수 있다.
function sum(a, b) { // 함수 선언식 - 함수 전체 호이스팅 return a + b; }; var minus; // 함수표현식 - 선언부만 호이스팅 sum(50, 50); // 100 minus(100, 50) // Uncaught TypeError: minus is not a function function (a,b) { // 함수 표현식 - 할당부는 그대로 return a - b; }
아래의 코드처럼, 함수 표현식을 코드를 호출하는 부분 위에 작성하면 문제없이 정상적으로 출력된다.
var minus = function (a,b) { // 함수 표현식 return a - b; } sum(50, 50); // 100 minus(100, 50) // 50 function sum(a, b) { // 함수 선언식 return a + b; };
왜 이렇게 동작할까? 의문을 던지고 스스로 답을 찾으며 점점 더 많이 공부 해야겠다.