(arrow function은 callback 함수 사용시 가장 많이 사용한다.)
forEach() 메소드는 주어진 함수를 배열 요소 ‘각각’에 대해 실행한다.
map() 메소드는 배열 내의 모든 요소 ‘각각’에 대해, 주어진 함수를 호출한 결과를 모아 ‘새로운 배열’을 반환한다.
즉, forEach()와 map() 메소드는 주어진 함수를 배열 요소 각각에 실행한다는 점에서 같은 기능을 갖고 있으며,
map() 메소드는 그 결과를 모아 ‘새로운 결과’를 반환한다는 점이 forEach()와 다르다.
forEach() 함수가 return 하는 것은 아무것도 없으며, forEach 함수를 탈출하고 싶을 때 return을 사용하면 된다.
즉, forEach()함수는 for문 대신 사용하는 반복 메소드라고 볼 수 있다.
또한, forEach()의 두 번째 인자에 인덱스값을 지정해서 출력결과를 받을 수 있다.
let idxOfC = -1;
let arr = ['a', 'b', 'c', 'd'];
arr.forEach((el, idx) => {
if (el === 'c') {
idxOfC = idx;
return;
}
});
console.log(idxOfC)
// 2
객체도 순회가 가능하나, 순서가 보장되지 않는다.
(because object does not have order)
객체 반복문 작성 방법
따라서, 아래의 방법으로 key와 value를 순회할 수 있다.
// key 순회
const obj = {
name: 'melon',
weight: 4350,
price: 16500,
isFresh: true
}
Object.keys(obj) // ['name', 'weight', 'price', 'isFresh']
// key를 배열로 저장하고, 그 변수를 통해 value 순회
const keys = Object.keys(obj)
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const value = obj[key]
console.log(value)
}
// value 순회
Object.values(obj) // [‘melon’, 4350, 16500, true]
// key, value 한 번에 순회 (가장 유용하게 사용됌)
Object.entries(obj) // [ [ 'name', 'melon' ],
[ 'weight', 4350 ],
[ 'price', 16500 ],
[ 'isFresh', true ] ]
for 문의 두 가지 사용예. (둘이 똑같이 기능한다.)
for (let i = 0; i < arr.length; i ++)
for (let i in arr)
for in을 object에 사용한 예.
for (let key in obj) {
const value = obj[key]
console.log(key)
console.log(value)
}
// name
melon
weight
4350
price
16500
isFresh
true
DOM이란 웹페이지의 HTML을 계층화시켜 트리구조로 만든 객체 모델이다.
JavaScript는 이 모델로 웹페이지에 접근하고, 페이지 수정 등을 할 수 있다.
DOM은 HTML인 웹페이지와 Javascript인 스크립팅 언어를 서로 잇는 역할을 한다.
사이트의 Devtools > Network > XHR 을 보면, api를 통해 서버에서 객체형식으로 데이터를 전송받는 것을 볼 수 있다.
document 객체는 DOM 트리의 root node에 접근하게 해준다.
그래서 document 객체로 element 및 attribute에 접근할 수 있다.
element의 content는 innerHTML로 접근하고 수정할 수 있다.
따라서 body 태그 내부에 있는 것을 ‘내용 다 바꿈’이라는 텍스트로 수정하고 싶으면, 아래와 같이 입력하면 된다.
document.body.innerHTML = '내용 다 바꿈';
혹은
function updateTitle() {
let title = document.getElementsByClassName('h1-title')[1]; // 대괄호 내 숫자는 인덱스 값으로, 클래스의 중 일부를 지정할 수 있다.
title.innerHTML = '바뀐 제목!!!';
}
updateTitle();
function addClass(name) {
let title = document.getElementsByTagName('h1')[0];
title.innerHTML = "wecode.com/img.png";
}
addClass('title');
특정 element는 css selector로 접근할 수 있다.
주의할 점은, Javascript에서 style을 수정할 때 하이픈 - 은 사용할 수 없기 때문에, 그런 property 명은 CamelCase로 변경해서 입력한다.
let blueElement = document.querySelector('.blue');
blueElement.style.backgroundColor = 'blue';
새로운 element를 생성할 수도 있다.
.createElement(tagName)
함수로 생성이 가능하며, 생성 후 어딘가의 요소에 append 해줘야 한다.
만약, innerHTML로 내용을 모두 할당했다면, appendChild 함수는 요소의 뒤쪽에 붙여준다.
function addElement() {
let listWrap = document.createElement('ul');
let list = document.createElement('li');
let listContent = document.createElement('span');
listContent.innerHTML = "목록이다";
list.appendChild(listContent);
listWrap.appendChild(list);
document.body.appendChild(listWrap);
}
addElement();
DOM 만드는 과정에서 과제는 summitted가 되고 result도 예상한대로 나왔는데,
connsole에 아래의 오류 메세지가 떴다.
HierarchyRequestError: Failed to execute 'appendChild' on 'Node': The new child element contains the parent.
Error: Failed to execute 'appendChild' on 'Node': The new child element contains the parent.
at addP
내가 만든 코드는 아래와 같다.
function addP() {
let h1 = document.createElement('h1')
let addedP = document.createElement('p'); // p 태그를 생성하고
addedP.className = 'dom' //해당 요소에 dom 이라는 class 이름을 주고
// let named = document.getElementsByTagName('p')
addedP.innerHTML = 'DOM' //해당 요소에 "DOM" 이라는 텍스트를 넣어서
// 이것들을 h1요소 내부에 추가
h1.appendChild(addedP)
document.body.appendChild(h1)
addedP.appendChild(h1);
}
addP();
오류 메세지처럼 새로운 자식 요소가 부모 요소를 담고 있어서 실패가 됐다면 result도 예상처럼 출력이 되지 않았어야 하는데,
잘 출력이 됐다.
흠.. 뭐가 문제일까.
좋은 이벤트는 오류가 없고, 이동이 자연스럽고 부드러우며, 클릭했을 때 빠르게 반응해서 사용자의 분노를 일으키지 않는 사이트이다.
특히, 다양한 interaction으로 사용자의 흥미를 불러일으키고 사용자를 편하게 하는 웹사이트가 늘어나고 있는데,
이 interaction은 html, css가 아닌 javascript 코드로 만들 수 있다.
따라서, 프론트엔드 웹 개발자는 interactive한 반응을 만들 수 있는 addEventListener 메소드를 잘 알고 있어야 한다.
addEventListener는 특정 이벤트가 언제 발생하는 지 가만히 듣고 있다가, 발생하면 인자로 받은 함수를 실행시켜 준다.
element.addEventListener(이벤트종류, function() {
// 이벤트 발생 시 실행할 내용
});
위와 같이 함수도 인자로 전달할 수 있는데, 이런 함수를 callback함수라고 부른다.
EventListener에 관한 자세한 내용은 아래 두 개의 사이트에서 확인할 수 있다.
https://www.w3schools.com/js/js_htmldom_eventlistener.asp
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
가장 많이 발생하는 이벤트는 클릭 이벤트다.
프론트엔드 개발자는 버튼, 사진, 글 등의 요소마다 클릭 이벤트를 달아서 각자 클릭이벤트에 맞는 reaction을 프로그래밍한다.
예시)
const thisIsButton = document.getElementsByClassName('login-btn')[0]; // 선택한 요소를 배열에 담아 반환한다.
thisIsButton.addEventListener('click', function() {
const password = document.getElementById('password').value;
const rePassword = document.getElementById('re-password').value;
if (!password) {
alert('비밀번호를 입력해주세요!');
return;
}
if (!rePassword) {
alert('비밀번호 확인을 입력해주세요!');
return;
}
if (password !== rePassword) {
alert('비밀번호가 맞지 않습니다!');
return;
}
alert('로그인 성공!!');
});
그 다음으로 많이 발생하는 이벤트는 키 이벤트다.
사람이 키보드를 누르면 발생하는 이벤트로 예시는 다음과 같다.
// 아래는 keydown 이벤트 addEventListener를 추가한 모습이다.
const thisIsPw = document.getElementById('password'); // id는 요소로 반환된다.
const thisIsCode = document.getElementById('code');
thisIsPw.addEventListener('keydown', function(e) {
thisIsCode.innerHTML = e.keyCode;
});
key code란 각 키보드가 갖고 있는 고유한 code이다.
평소에 다른 웹 사이트에서 로그인 할 때,
어떤 사이트는 엔터를 치면 로그인이 되고, 어떤 사이트는 엔터를 쳐도 로그인이 되지 않는 경우가 있다.
프론트앤드 개발자가 key 이벤트를 추가해서 엔터를 감지하여 로그인이 되도록 프로그래밍을 했느냐, 아니냐의 차이이다.