
자기 전, 간단히 오늘 공부했던 내용들 다시 한번 정리하기!
Javascript Execution Context and Hoisting
브라우저 환경과 다양한 명세서
좌표
코어자바스크립트 책
브라우저 창 사이즈와 스크롤
실행할 코드에 제공할 환경 정보들을 모아놓은 객체로, 자바스크립트의 동적 언어로의 성격을 가장 잘 파악할 수 있는 개념이다.
➡️ 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 '컨텍스트'를 구성하고, 이를 콜 스택에 쌓아 올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련있는 코드들을 실행하는 방식으로 전체 코드의 환경과 순서를 보장한다.
흔히 우리가 실행 컨텍스트를 구성하는 방법은 '함수를 실행'하는 것이다.
예를 들어서 함수A를 하나 가지고 있는 코드를 우리가 실행한다고 해보다. 먼저 코드를 실행하는 순간 전역 컨텍스트가 콜스택에 담긴다. 순차적으로 위에서 밑으로 읽어나가다가 함수A가 실행되면, 전역컨텍스트의 실행을 일시중단하고, 함수A에 관련된 콜 스택이 최상단에 쌓인다. 그리고 최상단에 있는 함수 A의 컨텍스트가 모두 실행되어 제거되면, 다시 전역 컨텍스트가 실행된다.
👉 그럼 실행 컨텍스트가 활성화 될 때, 자바스크립트 엔진이 해당 컨텍스트와 관련된 코드들을 실행하는데 필요한 정보들을 수집해서 실행컨텍스트 객체에 저장한다는데, 대체 어떤 정보들을 수집하는 것인가?🤔
바로 VariableEnvironmet/ LexicalEnvironment / THisBinding이 세가지의 정보들을 담는다.
실행 컨텍스트를 생성할 때는 VariableEnvironment와 LexicalEnvironment가 동일한 내용으로 구성되지만, 후자는 함수실행 도중에 변경되는 사항이 즉시 반영되는 반면, 전자는 초기 상태를 그대로 스냅샷으로 유지한다. LexicalEnvironment는 environmentRecord(매개변수명, 변수의 식별자, 선언한 함수의 함수명 등을 수집)와 outerEnvironmentReference(바로 직전 컨텍스트의 LexicalEnvironment 정보를 참조하는)로 구성돼 있다.
environmentRecord에는 처음부터 끝까지 쭉 읽어나가며 순서대로 정보들을 수집한다. 이런 수집하는 과정을 마쳤더라도, 아직 실행 컨텍스트가 관여할 코드들은 실행되지 않은 상태이다. 그런데, 코드가 실행되기 전이라도 먼저 정보를 수집하였기 때문에 자바스크립트 엔진은 이미 해당 환경에 속한 코드의 변수명들을 모두 알고 있게 된다. 즉, 이미 정보가 먼저 수집되었기 때문에, 이를 끌어올린다는 의미의 hoisting은 이를 추상화 한 단어이다.
⛔️ 변수 선언과 값 할당이 동시에 이루어진 문장은 '선언부'만 끌어올리고 할 당 과정은 원래 자리에 남아있다. 여기서 함수 선언문과 함수 표현식의 차이가 발생한다. ➡️ 다시 한 번 풀어서 써 보면, 함수 선언문은 본문의 내용까지 전부를 호이스팅하지만, 변수에 함수를 대입해 놓은 함수 표현문에서는 변수만 끌어올려진다. 함수 표현문으로 작성해 놓으면 함수 내부의 값이 실행 컨텍스트대로 실행되기 때문에, override될 가능성이 낮아져 상대적으로 안전하다.
스코프는 식별자에 대한 유효범위이다. 어떤 경계 A외부에서 선언한 변수는 A 내부에서도 접근가능하지만, A내부에서 선언한 변수는 A외부에서 접근 불가하다. 스코프체인이란 식별자의 유효범위를 안에서부터 바깥으로 차례대로 검색해 나가는 것을 의미한다.
전역 컨텍스트의 LexicalEnvironment에 담긴 변수를 전역변수라고 하고, 그 밖의 함수에 의해 생성된 실행 컨텍스의 변수들은 모두 지역변수이다.
실행 컨텍스트를 활성화 하는 당시에 지정된 this가 저장된다. 실행 컨텍스트의 활성화 당시에 별도로 지정되어 있지 않다면, this에는 전역객체가 저장되며, 그 외에는 함수를 호출하는 방법에 따라 저장되는 대상이 다르다.
브라우저 창의 너비와 높이를 알고 싶을 때,
window객체가 아닌document.documentElement를 쓰는 이유는, 스크롤바를 제외한 공간을 구해야 하기 때문이다.
스크롤바가 생기면 스크롤바도 공간을 차지하는데,window.innerWidth는 스크롤바가 차지하는 영역을 포함해서 값을 계산하기 때문이다.
element.getBooundingclientRect를 사용하면 정보를 얻을 수 있다.pageX,Y vs clientX,Y : page X,Y는 문서를 기준으로 한 좌표인 반면, clientX,Y는 사용자가 보고있는 창을 기준으로 한 좌표이다.window.scrollTo(x,y) - 절대 좌표로 데려다준다.
window.scrollBy(x,y) – 입력한 값만큼 스크롤 된다.
elem.scrollIntoView(top) – elem 위치로 스크롤 된다.
💡scrollBy mdn을 참고하면, 늘 새로운 걸 얻을 수 있다.
scrollby({top: 100, left: 100, behavior: 'smooth'})처럼 객체를 안에 넣어 옵션을 지정할 수가 있는데, 스무스하게 움직이는 느낌이 참 맘에 든다❤️