모던 자바스크립트 deep dive 36장 ~ 44장

2025. 4. 23. 16:58·Things I Learned

1. Deep Dive 학습 내용

[deep dive 37장: Set과 Map]

Set 객체

  • 중복되지 않는 유일한 값들의 집합. 배열과 달리 요소 순서에 대한 의미가 없으며, 인덱스로 요소에 접근할 수 없다.
  • 수학에서의 집합을 구현하기 위한 자료구조이다.
  • Set 객체를 생성할 때는 이터러블을 인수로 전달받는데, 이때 이터러블의 중복값은 한 번만 저장된다.
  • forEach() 메서드를 사용해서 Set 객체의 요소를 순회할 수 있다. 그리고 Set 객체는 이터러블이므로 for..of 문으로 순회할 수 있다.
  • 중복값을 제거하거나 유일값만 저장할 때 주로 사용된다.

 

Map 객체

  • 키-값의 쌍으로 이루어진 컬렉션이다. 객체와 달리 키값으로 객체를 포함한 모든 값을 사용할 수 있다.
  • Set 객체와 마찬가지로 Map 객체를 생성할 때는 이터러블을 인수로 전달받는다. 이때 이터러블은 키-값 쌍으로 이루어진 요소로 구성돼야 한다.
  • Map 객체에는 중복된 키를 갖는 요소가 존재할 수 없다.
  • 키에 문자열 외의 타입도 사용하고 싶을 때 사용된다.

 

[deep dive 38장: 브라우저의 렌더링 과정]

✅ body 요소의 가장 아래(닫는 body 태그 바로 위)에 script 요소를 위치하는 것이 바람직한 이유

브라우저는 동기적으로 html, css, javascript를 파싱하고 실행한다. 만약, DOM의 생성이 완료되지 않은 시점에서 DOM을 변경하는 DOM API를 사용하는 경우 문제가 발생할 수도 있기 때문에 이를 방지하기 위해 script 요소를 하단에 위치해야 한다. 

ex) 브라우저가 아직 li 요소를 파싱하지 않은 상태에서 script를 통해 li 요소를 조작하려고 하는 경우, 에러가 발생한다.

 

[deep dive 39장: DOM]

DOM은 HTML 문서를 javascript가 이해할 수 있도록 트리구조의 객체로 만든 것으로, 이를 이용해서 HTML의 내용 및 스타일 등을 동적으로 조작할 수 있다. 하지만, 이를 조작하기 위해서는 먼저 html 요소에 접근해야 한다. DOM은 요소에 접근하는 다양한 메서드를 제공한다.

1) document.getElementById (id로 접근하기)

2) document.getElementsByTagName (태그 이름으로 접근하기)

3) document.getElementsByClassName (클래스 이름으로 접근하기)

4) document.querySelector (CSS 선택자로 접근하기)

=> 검색 속도, 배열 메서드 사용 불가 등과 같은 이유로 인해 id 속성이 있는 요소에 접근하는 경우에는 getElelmentById 메서드를, 그 외의 경우에는 querySelector를 사용하는 것을 권장한다.

 

👀 노드 생성하기

1. createElement: 요소 노드 생성하기

2. 1단계에서 생성한 요소의 속성 또는 텍스트 추가하기

3. appendChild: 부모 요소에 자식 요소 붙이기

 

👀 HTML 어트리뷰트 vs DOM 프로퍼티

  • HTML 어트리뷰트: 초기 상태값. getAttribute() 메서드를 통해 접근하며, 변하지 않고 유지된다. 
  • DOM 프로퍼티: 현재 입력된 값. 가장 최신 상태의 값을 유지한다. value로 접근함.

 

[deep dive 40장: 이벤트]

이벤트 핸들러 등록 방식

1) html 속성 방식

<button onclick="alert('hi')">Click me</button>

오래된 방식이므로 권장하지 않음

 

2) DOM 프로퍼티 방식

const btn = document.getElementById('myBtn');
btn.onclick = function () {
  console.log('Clicked!');
};

하나의 이벤트 핸들러만 등록할 수 있다는 단점이 있으며, 나중에 다른 이벤트가 덮어씌어지면 기존의 이벤트는 사라진다.

 

3) addEventListener 방식

const btn = document.getElementById('myBtn');
btn.addEventListener('click', function () {
  console.log('Clicked!');
});
  • 여러 개의 이벤트 핸들러 등록 가능하며, 제거도 가능하다.
  • 이벤트 캡처링/버블링 옵션 설정이 가능하다.

 

이벤트 전파

이벤트가 발생하면, 그 이벤트는 단순히 그 요소에서만 발생하는 게 아니다. 이벤트는 DOM 트리 구조를 따라 여러 요소들을 거치며 전달되는 과정을 거치는데, 이를 이벤트 전파라고 한다. 그리고 이벤트 전파는 캡쳐링 단계, 타깃 단계, 버블링 단계 총 3개의 단계를 거친다.

1) 캡쳐링 단계 : 상위 요소에서 타깃 요소로 이벤트만 전달된 상태이다. (이때 이벤트는 실행되지 않고 전달 중임)

2) 타깃 단계 : 이벤트가 실제로 발생한 타깃 요소에 도달한 단계

3) 버블링 단계 : 이벤트가 타깃 요소에서 다시 상위 요소로 전파되는 단계이다.

* 이벤트는 한 번만 발생하고, 그 이벤트 객체가 부모 요소로 전파되면서 부모의 이벤트 리스너도 실행되는 것이다.

 

이벤트 위임

여러 개의 자식 요소에 이벤트 리스너를 각각 다는 대신, 부모 요소 하나에만 이벤트 리스너를 등록해서 이벤트를 처리하는 방법. 이벤트 버블링 덕분에 가능하다.

<ul id="menu">
  <li>🍔 햄버거</li>
  <li>🍕 피자</li>
  <li>🥤 콜라</li>
</ul>

위의 리스트의 각 아이템들을 클릭했을 때 콘솔에 출력하고 싶으면?

 

// 비효율적인 예시

const items = document.querySelectorAll("#menu li");

items.forEach((item) => {
  item.addEventListener("click", () => {
    console.log("아이템 클릭됨:", item.textContent);
  });
});

문제점

  • 리스트 아이템이 100개라고 가정하면? 이벤트 리스너도 100개 등록될 것이다.
  • 리스트에 새로운 li가 추가되면, 새로 추가된 요소에는 이벤트 리스너가 등록되지 않을 것이다.
    => 위와 같은 문제점들을 해결하기 위해 이벤트 위임을 사용해보자.

 

const menu = document.getElementById("menu");

menu.addEventListener("click", (e) => {
  if (e.target.tagName === "LI") {
    console.log("아이템 클릭됨:", e.target.textContent);
  }
});

li의 부모 요소인 ul 요소에 이벤트 리스너를 1개만 등록한다. 이렇게 하면 나중에 li 요소가 추가되어도 작동한다.

 

[deep dive 41장: 타이머]

  • 디바운스: 이벤트가 연속해서 발생할 때, 일정 시간 동안 아무 입력이 없으면 딱 한번 실행됨
    ex) 검색창에 사용자가 검색어를 입력할 때마다 서버에 api 요청을 보내면 서버는 과부하될 것이다. 따라서 사용자가 입력을 멈춘 후 일정 시간 뒤에만 요청을 보내도록 설정한다.

 

  • 쓰로틀: 이벤트가 너무 자주 발생할 때, 일정 시간 간격마다 한 번씩만 실행됨.
    ex) 유저가 스크롤할 때 헤더를 상단에 고정시키는 기능을 만들어보자. 헤더를 고정하려면 스크롤 위치를 체크해야 하는데, 스크롤 이벤트는 자주 발생할텐데 그 이벤트가 발생할 때마다 스크롤 위치를 체크하는 함수를 실행시키면 비효율적이다. 따라서 일정 시간 간격으로만 체크하는 게 더 효율적이다.

 

[deep dive 43장: Ajax]

- Ajax: 웹페이지를 새로 고치지 않아도 서버와 "필요한 데이터만" 주고 받을 수 있게 해주는 비동기 통신 기술

- JSON: 클라이언트-서버 간의 HTTP 통신을 위한, 키와 값으로 구성된 텍스트 데이터 포맷

 

[deep dive 44장: REST API]

- REST: 주소(uri)와 요청 방식(get, delete 메서드 등)을 조합해서 서버한테 "무엇을 해줘!"라고 말하는 규칙

- RESTful API: REST 원칙을 잘 지켜서 만든 구체적인 API를 말한다. 

* URI는 리소스를 표현하는 데 중점을 두어야 하는데, 리소스를 식별할 수 있는 이름은 동사보다는 명사를 사용한다. GET /getTodos/1 보다는 



2. 궁금점 및 추가 학습

이벤트 버블링을 알아야 하는 이유. 어떤 상황에서 주의해서 써야 할까?

1) 부모 요소까지 이벤트가 전달되면서 의도하지 않은 일이 생기는 경우를 방지하기 위해

ex) 화면에 모달창이 떠 있다. 사용자가 모달 외부 배경을 클릭하면 모달이 닫혀야 한다. 이때 사용자가 모달 안쪽 버튼을 클릭하면 모달은 닫히면 안된다.

<div id="modalOverlay"> <!-- 회색 배경 -->
  <div id="modalContent"> <!-- 흰색 모달 박스 -->
    <button id="confirmBtn">확인</button>
  </div>
</div>
// 잘못된 예제

// 배경 클릭 시 모달 닫기
document.getElementById("modalOverlay").addEventListener("click", () => {
  console.log("모달 닫기 실행");
});

// 모달 안 버튼 클릭
document.getElementById("confirmBtn").addEventListener("click", () => {
  console.log("확인 버튼 클릭");
});

실행결과: 사용자가 모달 안의 버튼을 클릭했을 때 "확인 버튼 클릭"과 "모달 닫기 실행"이 모두 출력됨. 왜냐하면 confirmBtn 버튼을 클릭하면, confirmBtn -> modalContent -> modalOverlay로 이벤트가 버블링되어 modalOverlay의 이벤트 리스너도 실행되기 때문이다.

// 올바른 예제

// 배경 클릭 시 모달 닫기
document.getElementById("modalOverlay").addEventListener("click", () => {
  console.log("모달 닫기 실행");
});

document.getElementById("confirmBtn").addEventListener("click", (e) => {
  e.stopPropagation(); // 💥 버블링 방지
  console.log("확인 버튼 클릭");
});

의도치 않은 버블링 문제를 방지하기위해 자식 요소의 이벤트 리스너에 stopPropagation 메소드를 추가해준다. 그럼 부모 요소로 이벤트가 전파되는 것을 막을 수 있기 때문에 확인 버튼을 클릭해도 "모달 닫기 실행"이 출력되지 않는다.

저작자표시 비영리 변경금지 (새창열림)
'Things I Learned' 카테고리의 다른 글
  • React 자습서: 틱택토 게임 (1) - 상태 끌어올리기, 불변성
  • React란 무엇이며, 왜 써야 할까?
  • 모던 자바스크립트 deep dive 27장 ~ 35장, 자바스크립트 객체에 특정 속성 존재 여부 확인하기
  • 모던 자바스크립트 deep dive 19장 ~ 26장, 프로토타입
킵고양
킵고양
궁금한 게 넘모 많아요 그래도 keep goyang
  • 킵고양
    개발할고양
    킵고양
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 프로젝트
      • 갱발자 레벨업
        • 갱스타그램
        • 코테
      • 뿌시기 시리즈
      • Things I Learned
  • 인기 글

  • 태그

    자바스크립트
    리액트
    useRef
    프로그래머스
    useCallback
    Promise
    프론트엔드
    MUI
    GitHub
    프로토타입
    코딩테스트
    무한스크롤
    접근성
    react
    Zustand
    프로젝트회고
    V8엔진
    javascript
    실행컨텍스트
    배열
    비동기
    개발자
    gitflow
    props
  • hELLO· Designed By정상우.v4.10.3
킵고양
모던 자바스크립트 deep dive 36장 ~ 44장
상단으로

티스토리툴바