자바스크립트(Javascript)는 본래 웹 브라우저에서 사용하려고 만든 언어이다. 넷스케이프에서 브랜든 아이크가 처음 만든 이후 진화를 거쳐 다양한 사용처와 플랫폼을 지원하는 언어로 변모하였다.
자바스크립트가 돌아가는 플랫폼들은 호스트(Host)
라고 불리는데 이는 브라우저 혹은 웹 서버, 또는 커피머신에서 자바스크립트가 돌아가기만 한다면 호스트라고 불릴 수 있다. 각 플랫폼들은 해당 플랫폼에 특정되는 기능을 제공하는데, 이를 자바스크립트 명세서에선 호스트 환경(Host Environment)
라고 부른다.
자바스크립트의 호스트 환경에서는 랭귀지 코어(ECMAScript)에 더하여 플랫폼에 특정되는 객체와 함수를 제공한다. 웹 브라우저일 경우 웹페이지를 제어하기 위한 수단을 제공하고, Node.js는 서버 사이드 기능을 제공해준다.
웹 브라우저일 때의 호스트 환경의 기능들을 보여주는 이미지
웹 브라우저의 호스트환경에서 window
라는 루트 객체가 존재한다. window는 자바스크립트 전역객체로써 browser window를 대변하고 이를 제어할 수 있는 메서드(method)를 제공한다.
브라우저의 개발자 도구에서 window를 입력한 모습
위와 같이 window는 전역객체이자 루트객체로써 alert ,blur, devicePixelRatio, event, 등등 수많은 내장객체와 함수들을 제공함으로써 브라우저를 컨트롤 할 수 있게 도와준다.저 수많은 객체, 함수들은 크게 3가지 역활로 나눌 수 있다.
DOM(Document Object Model)
은 문서 객체 모델이란 뜻으로 웹 페이지 내의 모든 콘텐츠를 객체로 나타내준다. 이를 통해 객체에 접근하여 수정을 가능케 해준다. DOM의 가장 대표적이자 페이지의 가장 기본 진입점 역활을 하는 객체는 document
이다.
개발자도구에 document를 입력하지 페이지 전체를 가리키는 모습
document
를 통하여 직접적으로 HTML Element
의 값을 추가, 변경 할 수 있다
document의 내부객체들을 통하여 새로운 div element를 생성해 추가한 모습
이 외에도 다양한 기능들을 제공한다. 관련 프로퍼티와 메서드에 대한 정보는 WHATWG의 DOM Living Standard 에서 확인할 수 있다.DOM은 브라우저만을 위한 모델이 아니다. DOM은 문서의 구조와 이를 조작할 수 있는 객체에 대한 설명이 담겨져 있기 대문에 브라우저가 아닌곳, 서버와같은곳에서 페이지를 그려 브라우저로 보내는 방식(서버사이드렌더링)등으로 사용하기도 한다.
BOM(Browser Object Model)
은 브라우저 객체 모델로 문서 이외의 모든것을 제어하기 위해 호스트환경(브라우저)에서 제공하는 객체들을 나타낸다.
앱의 이름이나 앱의 코드네임, 언어 등 브라우저의 정보들과 운영체제의 정보들이 나타나는 모습
HTML을 지탱하는것은 태그(tag)
이다. DOM에 따르면, 모든 HTML 태그는 객체
이다. 태그 하나가 감싸고 있는 자식(child)태그는 중첩 태그(nested tag)라고 부른다. 위 DOM 에서 사용한 객체 역시 body의 자식 객체를 추가하기에 appendChild라는 메서드로 newDiv를 추가한 모습을 볼 수 있다.
html의 노드와 자식노드를 확인하는 모습
HTML
은 HTML이라는 가장 큰 tag 안에 자식태그 Head tag가 있고 Head tag는 또 Title tag라는 자식 태그가 존재하게되고 이는 거대한 태그 트리 구조를 이루게 된다. 또한 title태그 안에 적게 될 "타이틀" 이라는 텍스트 역시 하나의 텍스트 노드
로써 title tag의 자식 노드가 된다.
위에 글을 확인해보면 텍스트는 텍스트 노드 라고 부르고 태그라 불렀는데 텍스트 노드는 DOM의 Node Type들 중 하나로써 Node Type은 크게 12가지로 나뉜다. 그중 가장 자주 쓰이는 타입과 비교적 덜 쓰이는 타입을 구분해보았다.
개발자 도구에서 nodeType이라는 메서드로 다양한 노드타입들을 확인할 수 있다.
앞서 DOM은 객체에 접근하여 값을 수정할 수 있다고 하였다. 그럼 DOM은 객체에 어떻게 접근하는것일까?
앞의 예시를 보면 document
를 통해 객체에 접근하거나 객체의 속성, 노드타입 등을 확인하는 모습을 볼 수 있다. document
가 DOM에 접근하기 위한 가장 기본적인 진입점이기 때문에 가능했던 일이다.
Document 관계 이미지 참조(출처 - 모던자바스크립트 - 문서)
하나씩 글로써 풀어보자면 document
는 DOM에 접근하기위한 가장 기본적인 진입점으로써 최상위에 위치해있다. document
안에서 documentElement
는 페이지 내 html의 루트객체인 html
태그를 가리킨다. 그리고 html 노드의 자식노드인 body
가 다음에 위치하게된다. 또 body
의 자식노드 에 div, main, section등의 자식노드가 오게 되고, 해당 노드의 형제노드(sibling)
혹은 또 다른 자식노드(childNodes)
가 오게된다. 이런식으로 document의 DOM tree 형식을 이용하여 DOM을 탐색할 수 있다.
위와 같은 방식으로 하나하나 자식,형제 노드를 탐색하지 않고 특정한 값을 찾고 싶을때는 getElement*, querySelector*
메서드로 탐색할 수 있다.
getElement*
에는 다음과 같은 메서드 들이 있다.
getElementById()
- 태그의 속성 중 id의 값을 이용해 DOM을 탐색한다. id는 중복될 수 없는 값이기에 1개의 노드만을 리턴하게된다.getElementsByTagName()
- 태그의 이름을 통해 DOM을 탐색한다. 태그의 이름은 여러개가 존재할 수 있기에 노드의 배열을 반환한다.getElementsByClassName()
- 태그의 속성 중 className을 이용하여 DOM을 탐색한다. className는 중복될 수 있기에 노드의 배열을 반환한다.getElementsByName()
- 태그의 속성 중 name속성을 이용하여 DOM을 탐색한다. name은 중복될 수 있기에 노드의 배열을 반환한다.getElement*를 이용하여 DOM을 탐색하는 모습
querySelector*
에는 다음과 같은 메서드 들이 있다.
querySelector()
- CSS선택자(ex. #id, .class, a[href$='zip'])을 토대로 탐색하여 가장 첫번째 노드를 리턴한다. 아래 querySelectorAll()
의 0번째 인덱스값과 같다.querySelectorAll()
- CSS선택자(ex. #id, .class, a[href$='zip'])을 토대로 탐색하여 연관된 노드의 배열을 반환한다.DOM의 노드들은 종류에 따라 각기 다른 프로퍼티들을 지원한다. a tag를 대응하는 element node에는 링크와 관련된 프로퍼티를, input tag를 대응하는 element node에는 입력과 관련된 프로퍼티를 제공한다.
대응하는 element node에 관련된 프로퍼티를 제공하는 모습
그런데 DOM 노드는 공통 조상에게서 만들어지기 때문에 노드타입은 다를 수 있지만 결국 모든 DOM 노드는 공통된 프로퍼티와 메서드를 지원한다.
EventTarget
로부터 node
는 EventTarget
을, 자식노드들은 부모 노드의 node class
를 상속받게된다.
상속관계를 그림으로 나타낸 이미지[출처 - modern javascript DOM노드 클래스]
새로 등장한
EventTarget
이란 클래스는 지금까지 언급된적 없는 새로운 친구인데, 이 부분은 브라우저의 이벤트를 알아보면서 더 자세히 알아볼 예정이다.
EventTarget
으로부터 상속받은 Node
라는 클래스가 DOM 노드의 주요 베이스역활을 하게되는 클래스이다. EventTarget
으로부터 상속 받았기에 addEventListener
와 같은 이벤트 메서드를 사용할 수 있게된다. 또한 Node로부터 상속받는 Text
, Element
, Comment
역시 Node
로부터 할당받기 때문에 노드가 가진 메서드들을 사용할 수 있다. 또 이중 Element
로부터 상속받은 HTMLElement
가 있게되고 위와같은 과정을 반복하게된다.
이렇게 꼬리에 꼬리를 물듯이 상속이 되어가는데 instanceof
라는 연산자를 통해 상속 여부를 확인할 수 있다.
instanceof 를 이용해 document와 document.body가 어디서 상속받았는지 추적하는모습