목차
1. JS > 변수 끌어올림(Hoisting)과 변수 중복 선언
프로그램은 작성한 순서에 따라 윗줄부터 차례로 실행됨. 하지만 var를 활용한 변수 선언은 이 원칙을 따르지 않음
console.log(y)
var y;
위처럼 작성한 코드는 에러를 낼 것 같지만, 발생하지 않고 단순 undefined 출력함.
에러가 나야할 것 같은데 나지 않는 이유는 js에서 var로 선언된 변수는 interpreter가 var로 선언된 변수를 위로 끌어올리기(hoisting) 때문임.
Hoisting
→ 함수 내에 있는 변수 선언(declaratiion), function definition 등을 모두 끌어올려서(hoist) 해당 함수 유효 범위의 최상단에 선언하는 것
단, var로 선언과 동시에 대입하는 값이나, let으로 선언하는 변수는 끌어올려지지 않음
- 호이스팅을 변수 및 함수 선언이 물리적으로 작성한 코드의 상단으로 옮겨지는 것으로 가르치지만, 실제로는 그렇지 않습니다. 변수 및 함수 선언은 컴파일 단계에서 메모리에 저장되지만, 코드에서 입력한 위치와 정확히 일치한 곳에 있습니다.
** 09.14 수정 -- let & const도 Hoisting 됨!
변수가 생성되기까지의 3단계
- Declaration Phase(선언 단계)
- 변수를 Variable Object(변수 객체)에 등록
- 변수 객체는 scope가 참조(referencing)하는 대상이 됨
- Initialization Phase(초기화 단계)
- 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보
- 이 단계에서, 변수의 value는 undefined로 초기화 됨
- Assignment Phase(할당 단계)
- undefined로 초기화된 변수에 실제 값을 할당함
💡var / let / const 모두 물리적 위치에 상관 없이 1단계인 모든 선언이 유효 스코프 내에서 최상단으로 끌어올려짐(hoisting)
💡단, var 키워드로 선언된 변수는 1단계(선언) & 2단계(초기화)가 한번에 이루어짐
→ 1, 2단계가 한번에 이루어지기 때문에 변수 선언 이전에 변수에 접근해도 ReferenceError가 아닌, undefined를 반환함
💡 반면, let, const 키워드로 선언된 변수는 1 & 2단계가 분리되어 따로 이루어짐
→ 따라서, 스코프에 변수가 선언되어 있기는 하지만, 2단계인 init 단계는 변수 선언문에 도달해야지만 이루어지므로, 변수 선언문 이전에 변수에 접근하면 ReferenceError가 발생함
💡 function 키워드로 선언된 함수는 1, 2, 3단계가 한번에 이루어진다
호이스팅 우선 순위 function < var
var myName = "hi";
function myName() {
console.log("smart cow");
}
function yourName() {
console.log("hyeonwoo");
}
var yourName = "bye";
console.log(myName); // "hi"
console.log(yourName); // "bye"
Temporal Dead Zone(TDZ)
→ 1. 선언 단계와 2. init 단계 사이의 구역
/* TDZ STARTS */
console.log(name);
/* TDZ ENDS */
const name = "Smart Cow";
- name이라는 변수가 console.log 위에서 먼저 1. declarartion 되기는 하지만, 2. init 되지는 않음
const a = 2
function square(a = a) {
// function square(a = a) -> Access to TDZ
return a * a
}
square() // throws `ReferenceError`
/* 아래 코드는 정상 작동 */
const init = 2
function square(a = init) {
return a * a
}
// Works!
square() // => 4
var keyword 사용을 자제해야 하는 이유
→ hoisting & 넓은 scope로 인한 의도치 않은 작동
- hoisting으로 인한 코드 가독성의 저하
-
var n = 1; function test() { console.log(n); // undefined var n = 2; console.log(n); // 2 } test();
-
- 함수 레벨 scope
- 함수 외부에 작성 시 전역 변수화 되기 쉬움
- for / if 안에서 선언된 var 변수를 block 밖에서도 참조할 수 있게됨
- 전역으로 선언 시, window 전역 객체의 property가 되버림
-
// 가장 바깥 scope var abc = 1; console.log(window.abc); // 1 출력
-
2. 변수의 명명 규칙
- 일반적인 변수는 보통 lower cammel case 사용
- 생성자의 이름은 upper cammel case 사용
- 논리값을 표현하는 변수는 이름 앞에 is를 붙임(e.g., isMouseDown)
- 상수는 upper snake case 사용(e.g., MAX_SIZE)
- loop counter는 j, j, k 등을 사용
** 함수는 동사로 시작하는 단어로 naming할 것
3. 함수의 실행 흐름
- 호출한 코드에 있는 인수가 함수 정의문의 인자에 대입
- 함수 정의문의 중괄호 안에 작성된 프로그램이 순차적으로 실행
- return 문이 실행되면 호출한 코드로 돌아감. return 문의 값은 함수의 반환값이 됨
- return 문이 실행되지 않은 상태로 마지막 문장이 실행되면, 호출한 코드로 돌아간 후에 undefined가 함수의 반환값이 됨
4. 함수 선언문의 끌어올림
- var를 사용한 변수 선언과 마찬가지로, function 키워드를 통한 함수의 선언은 실행 시 끌어올려짐
- 단, const 등을 사용한 arrow function은 hoisting이 안됨
'TIL(Today I Learned) > 2021년' 카테고리의 다른 글
09.17 - Singleton class in JS (0) | 2021.09.17 |
---|---|
09.10 - BOM & DOM / React에서 document VS ref / 함수의 Argument 객체 (0) | 2021.09.10 |
09.06 - 리액트 컴포넌트 구조 (0) | 2021.09.06 |
08.18 수 - RESTful 하지 않은 API (0) | 2021.08.19 |
08.17 화 - git branch 관련 명령어 (0) | 2021.08.18 |