23.09.20 프론트엔드 데브코스 첫 날 강의 공부 기록!
강의는 첫날이지만 커리큘럼상 어제의 오티에 이어 DAY2라 되어있어서 통일한다
📚 오늘 공부한 것
- 변수와 상수 자료형
- 메모리
- 표현식과 연산자
- 흐름 제어
- 배열과 객체 기본 문법
- 스코프와 클로저
이 중 중요하게 느낀 부분, 한번 더 정리할 부분만 기록하려고 한다.
HTML을 파싱하여 DOM트리를 생성합니다.
→ CSSOM 생성합니다.
→ DOM트리와 CSSOM트리를 결합하여 Render 트리 생성합니다. 화면에 표시되는 노드만 렌더 트리에 포함됩니다. (< script >등은 제외란 얘기)
→ 뷰포트 내에서 노드의 정확한 위치와 크기를 계산하여 Render Tree를 배치한다.
→ Render Tree의 노드를 화면에 그린다
var | let | const | |
---|---|---|---|
Scope | 함수 (키워드 없다면 전역) | 블록 | 블록 |
호이스팅 | 발생 | 선언만,정의 전 X | 선언만,정의 전 X |
재선언 | O | X | X |
업데이트(재할당) | O | O | X, 단 객체 내 속성값엔 가능 |
호이스팅 : 변수/함수의 선언이 해당 스코프의 최상단으로 끌어 올려져 메모리 공간에 할당되는 것
함수형 프로그래밍 방식으로 구현 가능
Stateless, Recursion, Pipe등
유효범위. 변수가 어느 범위까지 참조되는 지를 뜻한다.
var : 함수 레벨 스코프. var로 선언된 변수는 호이스팅 되어 변수 선언이 함수 상단으로 이동한다. 그래서 함수 내부에서 변경하는 것에 대해 전역으로 반영이 된다.
const, let : 블록 레벨 스코프
자신이 생성됐을 때의 환경을 기억하는 함수
설명
함수가 선언될 때 자동으로 생성되는 렉시컬 환경에 대한 설명입니다. 이러한 렉시컬 환경은 스코프 체인(scope chain)을 형성하게 되는데, 스코프 체인은 함수가 선언될 때의 모든 변수와 함수를 포함하는 렉시컬 스코프(lexical scope)를 형성합니다. 외부 함수가 실행 되고 반환된 후에도 외부 함수의 범위 내의 함수에 체이닝을 할 수 있는 함수 입니다. 정보를 은닉하기 위해서 주로 사용 합니다.
-> outer는 inner를 return 했습니다.innerExecute에는 outer에서 반환한 inner함수가 할당되게 됩니다. innerExecute를 호출할 때마다, outer에서 정의한 outerVal을 출력하게 됩니다. 이때 inner 함수는 outer 함수의 스코프 체인을 유지하게 되는데, 이러한 특성을 이용하여 클로저를 구현한 것입니다.
```jsx
var box = document.querySelector('.box');
var toggleBtn = document.querySelector('.toggle');
var toggle = (function () {
var isShow = false;
// ① 클로저를 반환
return function () {
box.style.display = isShow ? 'block' : 'none';
// ③ 상태 변경
isShow = !isShow;
};
})();
// ② 이벤트 프로퍼티에 클로저를 할당
toggleBtn.onclick = toggle;
```
① 즉시실행함수는 함수를 반환하고 즉시 소멸한다. 즉시실행함수가 반환한 함수는 자신이 생성됐을 때의 렉시컬 환경(Lexical environment)에 속한 변수 isShow를 기억하는 클로저다. 클로저가 기억하는 변수 isShow는 box 요소의 표시 상태를 나타낸다.
② 클로저를 이벤트 핸들러로서 이벤트 프로퍼티에 할당했다. 이벤트 프로퍼티에서 이벤트 핸들러인 클로저를 제거하지 않는 한 클로저가 기억하는 렉시컬 환경의 변수 isShow는 소멸하지 않는다. 다시 말해 현재 상태를 기억한다.
③ 버튼을 클릭하면 이벤트 프로퍼티에 할당한 이벤트 핸들러인 클로저가 호출된다. 이때 .box 요소의 표시 상태를 나타내는 변수 isShow의 값이 변경된다. 변수 isShow는 클로저에 의해 참조되고 있기 때문에 유효하며 자신의 변경된 최신 상태를 게속해서 유지한다.
이처럼 클로저는 현재 상태(위 예제의 경우 .box 요소의 표시 상태를 나타내는 isShow 변수)를 기억하고 이 상태가 변경되어도 최신 상태를 유지해야 하는 상황에 매우 유용하다. 만약 자바스크립트에 클로저라는 기능이 없다면 상태를 유지하기 위해 전역 변수를 사용할 수 밖에 없다. 전역 변수는 언제든지 누구나 접근할 수 있고 변경할 수 있기 때문에 많은 부작용을 유발해 오류의 원인이 되므로 사용을 억제해야 한다.
var incleaseBtn = document.getElementById('inclease');
var count = document.getElementById('count');
var increase = (function () {
// 카운트 상태를 유지하기 위한 자유 변수
var counter = 0;
// 클로저를 반환
return function () {
return ++counter;
};
}());
incleaseBtn.onclick = function () {
count.innerHTML = increase();
};
스크립트가 실행되면 즉시실행함수 (increase에 할당된 function) 가 호출되고 변수 increase에는 함수 function () { return ++counter; }
가 할당된다. 이 함수는 자신이 생성됐을 때의 렉시컬 환경(Lexical environment)을 기억하는 클로저다. 즉시실행함수는 호출된 이후 소멸되지만 즉시실행함수가 반환한 함수는 변수 increase에 할당되어 inclease 버튼을 클릭하면 클릭 이벤트 핸들러 내부에서 호출된다. 이때 클로저인 이 함수는 자신이 선언됐을 때의 렉시컬 환경인 즉시실행함수의 스코프에 속한 지역변수 counter를 기억한다. 따라서 즉시실행함수의 변수 counter에 접근할 수 있고 변수 counter는 자신을 참조하는 함수가 소멸될 때가지 유지된다. 즉시실행함수는 한번만 실행되므로 increase가 호출될 때마다 변수 counter가 재차 초기화될 일은 없을 것이다. 변수 counter는 외부에서 직접 접근할 수 없는 private
변수이므로 전역 변수를 사용했을 때와 같이 의도되지 않은 변경을 걱정할 필요도 없기 때문이 보다 안정적인 프로그래밍이 가능하다.function Counter(){
let privateCounter = 0;
function changeBy(val){
privateCounter += val
}
return {
increment : function () {
changeBy(1);
},
decrement : function () {
changeBy(-1);
},
value : function () {
return privateCounter;
},
};
}
const counter = Counter();
// 0
counter.increment();
//1
counter.decrement();
//0
var arr = [];
for (var i = 0; i < 5; i++){
arr[i] = (function (id) { // ②
return function () {
return id; // ③
};
}(i)); // ①
}
혹은 let을 사용해서 전역변수의 문제를 해결해줘도 된다const arr = [];
for (let i = 0; i < 5; i++) {
arr[i] = function () {
return i;
};
}
추가 공부 내용은 포이마웹 을 참고하였습니다
강의를 들으면서 완벽히 답할 수 없는 부분에 대해 스스로 찾아보고 공부하였다.
절대적으로 공부하는 시간을 늘릴 수 있었다.
강의 중이나 공부하면서 들었던 의문을 바로바로 해결하진 못했다. 기억하지 못해서 일부는 까먹었을지도 모른다.
팀이 있는 만큼 팀 학습이 더 적극적으로 되었으면 했다. 공부 중 궁금한 것을 활발하게 슬랙에 남기고 답하기로 하였고, 중간 타임을 만들어서 실시간으로도 도움을 주고 받아보려고 한다!