2021. 2. 20. 18:00ㆍ공부내용 공유하기
문득 여태껏 자바스크립트를 사용하면서 window객체와 document객체의 차이에 대해 잘 알지 못했다는 점이 생각나서 공부 후 포스팅한다.
내가 window / document 객체를 참조하는 흔한 작업들은 다음과 같았다.
1. 이벤트 리스너 등록
window.addEventListener("scroll", function () {});
document.addEventListener("click", function() {});
2. dom에 접근
document.body.style.backgroundColor = "#fafafc";
document.getElementById("nextForm").focus();
3. 스크롤 위치 이동
window.scrollTo(pos);
4. 창 닫기 / 열기
window.close();
window.open(url);
나열해놓고 보니 window객체와 document객체에서 하는 일이 뭔가 미묘하게 다른 건 알겠다.
하지만 여전히 명확한 차이가 무엇인지, 두 객체의 addEventListener가 어떤 차이인지 모르겠다.
다행히 이러한 궁금증을 나만 가진것이 아니었기 때문에 다른 분들이 stackoverflow에 작성하신 질문들이 있었고, 거기엔 좋은 답변들이 준비되어 있었다.
결론만 요약하자면 다음과 같다.
- window 객체는 브라우저 탭에 존재하는 자바스크립트 전역 최상위 객체이다. 따라서 window로 어디서든 접근이 가능하다.(서버사이드 렌더링 시엔 브라우저 렌더링이 아니기 때문에 window 객체가 없다)
- window 객체 안에는 document 객체가 존재하고, document에는 잠재적으로 보여질 수 있는 dom에 대한 정보가 저장되어 있다. document객체는 window.document 혹은 document로 접근이 가능하다. (그 이유는 바로 다음 줄에)
- window 객체는 전역으로 선언되어 있기 때문에 window객체 안에 있는 요소는 "window."와 같이 window객체를 참조하지 않고도 property 이름으로 바로 접근이 가능하다. 예컨대 window.innerHeight는 그냥 innerHeight로 접근이 가능하다. ( 오... 신기... 하지만 혼동이나 scope 등의 문제로 window.innerHeight 이런 식으로 사용하는 게 좋을 것 같다. )
- document객체와 window객체에서 수용 가능한 eventList가 다르기 때문에, 같은 addEventListener이 있다고 하더라도, 각 용도에 맞게 호출해야 한다.
좋은 답변들을 다 열람했고 두 객체의 차이가 뭔지 이젠 좀 명확히 알게 되었다고 해도, 글로만 익힌 지식은 실전으로 사포질을 해줘야 가슴으로 와닿는 법이다.
브라우저가 곧 런타임인 자바스크립트의 장점을 살려 바로 console.log(window)를 찍어보자.
윈도우 객체가 나왔다. 두근두근.
접힌 부분을 열어서 내용물을 까 보도록 하자.
window 객체 안에 document 객체가 들어있는 부분을 확인할 수 있다.
저 document객체를 열어보면 알겠지만, 저 안에 dom 정보가 가지런히 정리되어 있다.
window객체를 까보면서 굉장히 많은 걸 배웠다.
일상적으로 자주 쓰던 console, alret, confirm 등의 fucntion이 window객체에 정의되어 있다는 것도 처음 알았고, window객체가 없는 서버사이드 렌더링 시에 어떤 부분을 더 주의해야 하는지 어떤 식으로 오버 라이딩 해야 하는지 와 닿게 알게 된 것 같다.
이 글이 seo가 잘 되어서 그런지 2023년 2월 기준으로도 조회수가 높은 글에 속한다.
2년 전에 잘 모르던 초짜가 쓴 글이라 AS가 좀 필요할 것 같아 첨언하자면...
window 객체는 브라우저라는 host 환경에서 동작하는 최상위 객체로, 브라우저 환경에서 동작하는 여러 API들의 가교 역할을 한다. document, history, location, setTimout, cookieStore 등 다른 브라우저 api에 접근을 제공한다.
뿐만 아니라 브라우저 탭에 대한 접근 권한이 있기 때문에 window.open, window.close, window.location 등을 통해 브라우저 탭 레벨의 여러 제어가 가능하다.
JSDom등의 환경에서는 표준 window 객체의 인터페이스를 바탕으로 구현한 더미 window 객체(더미라고 해도 몇몇 기능들은 동작한다)를 사용하게 되는데 이 경우에는 실제 브라우저의 인터페이스와 다를 수 있으니 주의해야 한다.
document 객체는 window에 로드되는 HTML 문서 그 자체를 나타내며, 해당 문서 내부의 HTML Element, Css 등을 제어할 수 있는 여러 메서드를 제공한다. 보편적으로 window 객체의 프로퍼티로 제공된다.
일반적으로 querySelector 등의 메서드로 css selector 기반의 element 쿼리를 많이 하게 된다.
getByElementById의 경우 찾고자 하는 요소가 Shadow DOM 내부에 있다면 Shadow Root에 접근해서 쿼리해야 한다.