예전에는 하이퍼텍스트를 눌러 페이지 이동을 했었음.
그때 생긴것이 html
. 그때는 레이아웃, 폰트크기 등 스타일을 html
이 모두 도맡아 함.
이후 css
생김.
현대의 html은 문서의 구조, 의미다.
각 태그마다 기본스타일이 있다. 다 외우는건 멍청한 짓! 사례들로 파악해보자.
숙제를 내주셨따.
css에서 id와 class의 차이, id가 여러개있으면 어떻게 처리하는지
id
는 유일 class
는 중복가능.
여러개있으면 어떻게 처리되는지? => 제일 처음 만난 값만 id를 가진다.
Css의 선택자 종류
html문서를 모델링해 조작 가능한 객체로 뽑아낸 것.
JS와 같이 등장함. 초창기엔 접근 가능한 태그가 적었지만, 점점 늘어났다.
DOM은 트리구조다.
DOM의 각 요소는 prototype으로 정의되어있다.
예를들어 <body>
는 HTMLBodyElement
에서 위임받아 만들어지는 것이다...
여기서 문제! li
태그를 가져올때, 엔진은 어떤 식으로 순회할까?
<html>
<body>
<div>Div</div>
<strong>우하하</strong>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
</html>
정답은 preorder(전위순회)
다.
=> 사람이 인식하는 순서와 동일하다. html > body > div > strong > ul > li...
여기서자세히 설명했다.
몰랐던 것들만 적겠음
firstElementNode
: 첫번째 자식nextElementSibling
: 다음 형제previousElementSibling
: 이전 형제DOM을수정하면 렌더링과정이 다시 일어난다. 자세한 설명은 위에 링크.
그렇기에 상호작용이 많아져 DOM조작이 자주 일어날때 쯤 Virtual DOM이 개발되었다.
원리 자체는 간단하다. DOM조작을 1대1로 업데이트하지 않고
Virtual DOM이라는 복제본에 수정사항을 반영해서 한번에 업데이트한다.
=> 사실 그냥 DOM보다는 느리다. But. 충분히 빠르고 개발자가 일일히 최적화 할 필요가 없어서 사용함.
브라우저 렌더링만 줄여줄 뿐.
숙제를 내주셨다
일종의 임시 document다. 여기에 저장된 노드들이 변경되어도 렌더링과정에 영향을 끼치지 않는다.
예를들어 appendChild()
를 반복문으로 사용할 경우, 최악의 경우 매번 리플로우가 일어나게 된다.
하지만 DocumentFragment
에 일시적으로 노드를 저장 후, 한번에 추가하면 한 번의 리플로우만 일어난다.
Virtual DOM과 유사하구나!
그런데 또 의문이 들었다. 웹 컴포넌트라는 기술에서도 비슷한 <template>
이라는 기능이 있다.
둘의 차이는 뭘까?
=> <template>
은 반복적으로 사용할 노드를 저장해두고 쓰는 것. documentFragment
는 동적으로 생성하거나, 리플로우를 방지할 목적으로 사용한다.
비슷한 기능인데, 목적이 다르다.
실제로 <template>
의 content
는 읽기 전용 DocumentFragment
라고 나와있다.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLTemplateElement/content
//1번
(function(name){
console.log(`hello ${name}`);
}('tomato'))
//2번
(function(name){
console.log(`hello ${name}`);
})('tomato')
내가 알고있던 즉시실행 함수는 1번.
2번도 즉시실행함수다...주의하자.
새로 문서를 팔까 싶다가도, 나중에 한번 정리할테니 짚고 넘어가자
this
는 무조건 전역객체를 가리킨다. 객체 내부 어쩌고어쩌고...쭈욱 들어간 뒤 콜백함수에서 this
를 사용해도 무조건 window
객체다. (브라우저 한정)this
는 .
마침표 연산자 앞에 기술된 객체에 바인딩(소유가 아닌 호출객체)apply,call, bind
는 this
를 바인딩할 객체를 명시한다. 고 녀석에게 바인딩.this
가 없다. => 상위 스코프의 this
의 참조.(선언된 위치의 상위스코프 참조).조금만 더 자세히 알아보자
const myObject = {
name: "example",
outerFunction: () => {
setTimeout(() => {
setTimeout(() => {
console.log(this); // this는 전역 객체를 가리킴
}, 1000);
}, 1000);
}
};
myObject.outerFunction();
이때는 전역객체를 가리킨다. 왜냐면, outerFunction의 상위 스코프는 전역객체니까.
...
outerFunction: function() {
setTimeout(() => {
setTimeout(() => {
console.log(this); // this === myObject
}, 1000);
}, 1000);
}
이렇게 해야 myObject
를 바인딩한다.
virtualDOM에 대해 자세히 알게되어 좋았다. 리액트가 왜 그런 선택을 했는지도 알게되고, 가상돔이 실제돔보다 느리다는 사실도 알게되었다.
그리고 this에 대해 따로 공부했더니 확실히 더 잘 알게되었다. 헷갈릴때마다 매번 보러와야지!