DeepDive JS - 10일차 // 34-36,39장

2025. 1. 27. 21:21JS

34장 이터러블 (es6 도입)
이터레이션 프로토콜에는 

이터러블 프로토콜 

이터레이터 프로토콜 

                 itrerable                                                                    iterator

 

                                                                        {   

        [Symbol.itrerator]( ) {   }               =>              next (  ) { 

                                                                                  return {  value : any, done : boolean} 

                                                                                    }

                                                                          }

이터러블 : Symbol.iterator를 프로퍼티 키로 사용한 메서드를 직접 구현하거나 프로토타입 체인을 통해 상속받는 객체
이터레이터: 이터러블의 Symbol.iterator 메서드가 반환한 이터레이터는 next 메서드를 갖는다.

for (변수선어문 in 객체) : 프로퍼티 어트리뷰트가 [[Enumerable]] 값이  true인 프로퍼티를 순회하며 열거, 프로퍼티 키가 심벌 열거 x


for (변수선언문 of 이터러블)  :  내부적으로 이터레이터의 next 메서드를 호출하여 이터러블을 순회하며 next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티 값을 for...of문의 변수에 할당 done : true 되면 중단.

 

모든 유사배열 객체가 이터러블은 아님. es6 이후 Symbol.iterator 메서드를 구현한 것만 이터러블이 됨 
ex) arguments, NodeList, HTMLCollection

이터레이션 프로토콜의 필요성
es6에서는 순회 가능한 데이터 컬렉션을 이터레이션 프로토콜을 준수하는 이터러블로 통일하여 for ...of문, 스프레드 문법, 배열 디스트럭처링 할당의 대상으로 사용할 수 있도록 일원화.

 

 

 

35장 스프레드 문법 (es6 도입)

...은 하나로 뭉쳐 있는 여러 값들의 집합을 펼쳐서 개별적인 값들의 목록을 만든다
ex) console.log(...[1,2,3])//1 2 3 

가능 사용처.
함수 호출의 인수목록
ex) const arr = [1,2,3]
const max = Math.max(...arr) // 3 

function bar (...arr ) { } // 1,2,3 => [1,2,3]  //Rest 파라미터: 함수에 전달된 인수 목록을 배열로 전달받음


배열 리터럴의 요소 목록 

concat, splice, 배열 복사, 이터러블을 배열로 변환 
ex) const arr [...[1,2], ...[3,4] ] // [1,2,3,4]

객체 리터럴의 프로퍼티 목록
ex) const merged = {x :1, y:2, ...{a:3, b:4 } } ; // {x:1, y:2 , a:3, b:4 }

스프레드 프로퍼티는 obj.assign 메서드를 대체할 수 있는 간편한 문법.

 

 

 

 

36장 디스트럭처링 할당 : 구조화된 배열과 같은 이터러블 또는 객체를 구조파괴하여 1개 이상의 변수에 개별 할당
배열 디스트럭처링 할당 : 할당 대상(할당문의 우변)은 이터러블, 할당 기준은 배열의 인덱스

ex) const arr = [1,2,3]  => const [ 1st, 2nd, 3rd] = arr  // 1,2,3

객체 디스트럭처링 할당 : 할당 대상(할당문의 우변)은 객체, 할당 기준은 프로퍼티 키

ex) var user = { fristName : 'Saga' , lastName : 'kim' } =>  const { lastName , firstName } = user;  //Saga kim

 

 

 

 

39장 DOM(Document Obeject Model) : 프로퍼티와 메서드를 제공하는 트리구조.

 

노드

HTML요소와 노드 객체

<div(시작태그) class(어트리뷰트 이름) = "greeting"(어트리뷰트 값)>Hi(콘텐츠)</div(종료태그)>
HTML 요소 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소 노드 객체로 변환
이때, HTML 요소의 어트리뷰트는 어트리뷰트 노드로,  텍스트 콘텐츠는 텍스트 노드로 변환

요소 노드  div - class="greeting" 어트리뷰트 노드

텍스트 노드 "Hi" 

 

트리 자료구조
루트 노드 -> 자식 노드까지.

노드 객체들로 구성된 트리 자료구조를 DOM이라 한다.

 

노드 객체 타입

문서노드 

DOM트리 최상위 존재하는 루트 노드 document 객체를 가리킴 // HTML 문서 전체

요소 노드

HTML 태그를 나타냄

 

어트리뷰트 노드

HTML요소의 속성(ex: class, id, style)을 나타냄

 

텍스트 노드 

태그 내부의 텍스트를 나타냄 

 

노드 객체의 상속구조

 

ex: input 요소를 파싱하여 객체화한 input 요소 노드객체 프로토타입 체인.

input > HTMLInputElement > HTMLElement > Element > Node > EventTarget > Object

 

요소 노드 취득

id 어트리뷰트가 있는 요소 노드를 취득 ; getElementById 메서드 사용

그외의 경우 quertSelector, quertSelectorAll 메서드 사용 권장

 

왜?
속도가  getElementById, getElementBy***  > quertSelector, quertSelectorAll 이라고 함.
CSS선택자 문법 quertSelector, quertSelectorAll을 사용하면 좀 더 구체적인 조건으로 요소 노드를 취득

일관된 방식으로 요소노드를 취득 할 수 있다는 장점.

HTMLCollection과 NodeList
특징

HTMLCollection: 노드 객체 상태 변화를 실시간으로 반영하는 살아있는 객체.(live 객체)

NodeList : non-live 객체로 동작하지만 경우에 따라 live로 동작.

-> 노드 객체의 상태 변경과 상관없이 안전하게 DOM 컬렉션을 사용하려면

HTMLCollection, NodeList 객체를 배열로 반환하여 사용하는 것을 권장.

 

노드탐색

요소 노드 , 텍스트 노드 반환

Node.prototype.childNodes 

Node.prototype.firstChild

Node.prototype.lastChild

요소 노드만 반환

Element.prototype.children

Element.prototype.firstElementChild

Element.prototype.lastElementChild

 

노드 정보 취득

Node.prototype.nodeName 노드 이름 문자열로 반환.

 

요소 노드의 텍스트 조작

textContent : 텍스트 모두 반환. HTML 마크업 무시

innerText 사용 지양

1. css 비표시 (visibility :hidden)로 지정된 요소 노드의 텍스트 반환 않함
2. css를 고려해야하므로 textContent보다 느림.

 

DOM 조작

innerHTML : 요소 노드의 콘텐츠 영역(시작/종료태그 사이) 내에 포함된 모든 HTML마크업을 문자열로 반환
단점,

1.크로스 사이트 스크립팅 공격에 취약함. HTML5에서 방지책이 있긴함, 

HTML 섀니티제이션 : DOMPurify 같은 라이브러리 사용 권장.

2.돔을 새로 그림 : 요소 노드의 모든 자식 노드를 제거하고 할당한 HTML 마크업 문자열을 파싱하여 DOM을 변경
3. 새로운 요소를 삽입할 때 삽입될 위치를 지정할 수 없다.
위의 대안으로 insertAdjacentHTML(position, DOMString) 메서드 
기존 요소를 제거하지 않으면서 위치를 지정해 새로운 요소를 삽입

첫번째 인수 beforebegin, affterbegin, beforeend, afterend

Document.prototype.createElement( tagName)  요소 노드 생성

Document.prototype.createTextNdoe(text) 텍스트 노드 생성

Node.prototype.appendChild(childNode) 매개변수 childNode에게 인수로 전달한 노드를 appendChild 메서드를 호출한 노드의 마지막 자식 노드로 추가

 

복수의 노드 생성 과 추가 시 

3개의 요소 노드를 생성하여 DOM에 3번 추가하면 DOM이 3번 변경된다. 이때 리플로우와 리페인트가 3번 실행됨.
이를 해결할 방법은.

document.prototype.createDocumentFragment( ) 메서드 사용

DocumentFragment( ) 노드 생성 , DOM에 추가할 요소 노드를 생성하여 DocumentFragment 노드에 자식 노드로 추가한 다음 DocumentFragment 노드를 기존 DOM에 추가
이렇게 하는 이유는, 실제 DOM변경이 발생하는 것은 한번, 리플로우와 리페인트도 한번만 실행.

노드삽입 
마지막 노드 추가 appendChild( ) 
지정한 위치 노드 삽입 insertBefore(newNode, childeNode)
노드 복사 cloenNode([deep:true:false]) false 얕은 복사, true 깊은 복사

노드 교체 replaceChilde(newChild,oldChild ) 

어트리뷰트
모든 어트리뷰트 노드의 참조는 유사 배열 객체이자 이터러블인 NameNodeMap 객체 담겨서 요소 노드의 attributes 프로퍼티에 저장

HTML 어트리뷰트 조작 

getAttribute( )/ setAttribute( )

HTML 어트리뷰트 vs DOM 프로퍼티
요소 노드의 초기 상태는 어트리뷰트 노드가 관리,

요소 노드의 최신 상태는 DOM 프로퍼티가 관리.
실행컨텍스트의 렉시컬 환경이랑 v.e 랑 비슷?

클래스 조작 

classList.add/remove/item/contains/replace/toggel  ( )  등


 

'JS' 카테고리의 다른 글

DeepDive JS - 12일차 // 41,43-45장  (0) 2025.01.31
DeepDive JS - 11일차 // 37,40,42장  (1) 2025.01.29
DeepDive JS - 7일차 // 25 - 26장  (0) 2025.01.23
DeepDive JS - 6일차 // 20 - 22,24장  (0) 2025.01.22
DeepDive JS - 5일차 // 18 - 19장  (0) 2025.01.21