일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- icmp
- 컴퓨터네트워크
- 이것이 취업을 위한 코딩 테스트다
- 리스트
- data type
- 파이썬 자료형
- IT5분잡학사전
- 이것이 취업을 위한 코딩테스트다
- 이코테
- ARP
- 노마드코더
- DP
- 라우팅
- 쿠키
- 데이터 통신과 컴퓨터 네트워크
- 시스템 소프트웨어
- sort()
- GIT
- 자료형
- 데이터통신
- 기억장치
- 컴퓨터 동작방식
- 파이썬 정렬
- 북클럽
- 파이썬 연산자
- CS
- RARP
- 노개북
- OSI7계층모델
- 쉽게 배우는 데이터 통신과 컴퓨터 네트워크
Archives
- Today
- Total
뚝딱햄 탈출기
[기술면접대비][JS] 호이스팅의 발생 원인 : 선언자, 스코프 본문
선언자
📌 let, var는 ES6에서 도입된 선언자!
const, let, var
const는 재선언, 재할당 금지. 따라서 변하지 않는 상수를 선언할 때 사용.
let은 재선언 금지, 재할당 가능.
var는 재선언 가능, 재할당 가능.
let a = b;
a = c; // 재할당. let으로 선언한 a에 사용 가능.
let a = e; // 재선언. let으로 선언한 a에 사용 불가.
2023.08.07 - [Programming language/JavaScript] - [JavaScript] 자바스크립트 변수 : const, let, var
스코프
스코프란 변수에 접근할 수 있는 범위를 뜻한다.
💡 const와 let은 블록 스코프, var는 함수 스코프이다.
함수 스코프
- 원래 JS에서는 함수 스코프를 따른다.
- 함수가 선언되면 무조건 스코프가 생성된다.
- 함수 내에서 선언된 변수는 해당 함수 내에서만 접근 가능하다.
예시 1
if (5 > 4) {
var secret = '12345';
}
secret // '12345'
- 어디에서나 변수 secret에 접근할 수 있는 이유는, 함수가 선언되어 있지 않기 때문.
- 함수가 선언되어야 스코프가 생성된다.
- 새로운 스코프가 형성되지 않아 변수는 동일한 실행 컨텍스트 내에 존재한다.
예시 2
function a() {
var secret = '12345';
}
secret; // ReferenceError
- 함수 a의 생성과 동시에 새로운 실행 컨텍스트가 생성되어 이 실행 컨텍스트 내부에 존재하는 변수 환경에 변수 secret가 저장된다.
- 부모 스코프는 자식 스코프에 간섭할 수 없다. (= 접근 불가)
- 따라서 함수 외부(global scope)에서는 함수 a 내부의 변수에 접근할 수 없다.
블록 스코프
- {}이 생성될 때마다 새로운 스코프가 형성된다.
- 블록 내에서 선언된 변수는 해당 블록 내에서만 접근할 수 있다.
- 선언 이전에 접근하면 참조 오류를 발생시킨다. (코드 명확성, 안정성 측면에서 더 좋음)
예시 1
function loop() {
for(var i = 0; i < 5; i++) {
console.log(i);
}
console.log('final',i);
}
loop(); // 잘 출력됨.
- for문에서 변수 i를 var로 선언 ⇒ 함수 스코프를 따름 ⇒ for문 내부와 외부에서 모두 변수 i에 접근해 console.log 실행
- loop이라는 함수 스코프 안에 존재 ⇒ for문 안과 밖에서 i에 접근 가능
예시 2
function loop() {
// let i; // 이렇게 하면 가능
for (let i = 0; i < 5; i++) {
console.log(i);
}
console.log('final', i); // for 루프 종료되면 변수 i 참조 불가
}
loop(); /* ReferenceError: i is not defined */
- for문 내에서 변수 i를 let으로 선언 ⇒ 변수 i는 for문 내에서만 종속되어 for문 외부에서 i에 접근할 수 없음.
예시 3
function test() {
console.log(x); // ReferenceError: x is not defined (선언 전에 써서)
let x = 10;
}
test();
📌 let 키워드는 선언 이전에 변수에 접근하면 참조 에러가 발생하는 이유? “아직 초기화되지 않아서”
📌 var 키워드는 선언 이전에 변수에 접근하면 undefined가 뜨는 이유는? “호이스팅”
호이스팅이란?
- 변수 선언과 초기화가 분리되어 선언이 가장 위로 끌어올려지는 현상
- JS의 모든 선언에는 호이스팅이 일어난다.
- JS의 변수 선언은 선언 → 초기화 단계.
- 선언 단계
- 변수명 등록해 JS 엔진에 변수의 존재를 알림.
- JS 엔진 구동시 선언문을 가장 최우선으로 해석
- 초기화 단계
- 값을 저장하기 위한 메모리 공간 확보, 암묵적으로 undefined를 할당해 초기화.
- 런타임 과정에 이루어짐.
- 선언 단계
- var a = 2
- var a;와 a = 2;로 분리됨.
- JS의 변수 선언은 선언 → 초기화 단계.
- 자바스크립트 엔진은 런타임 이전에 실행 컨텍스트를 생성하는데, 이 때 실행 할 코드를 읽어서 코드를 실행하는데 필요한 변수나 함수를 메모리에 등록한다.
- JS 엔진은 코드 실행 전 실행 가능한 코드를 형상화하고 구분하는 과정을 거치는데, 이 때 모든 선언(변수, 함수, 클래스)을 스코프에 등록한다.
- 따라서 선언의 위치에 상관없이 함수/변수를 참조할 수 있는 것이다.
- 변수가 함수 내에서 정의되었을 경우 선언이 함수의 최상위로 변경되고, 함수 바깥에서 정의되었을 경우 전역 컨텍스트의 최상위로 변경된다.
var의 호이스팅
💡 결론 - 초기화 전에도 참조 가능하나, 초기화 이전이므로 undefined이다.
- var 키워드로 선언 및 초기화를 한 변수는 호이스팅이 발생하면 선언과 거의 동시에 undefined로 초기화된다.
- 실행 시점의 스코프 최상단에서 해당 변수에 대한 메모리가 살아있기 때문에 선언부 위치에 상관없이 참조, 할당이 가능하다.
- JS 엔진 구동시 선언문을 가장 최우선으로 해석
function test() {
console.log(x); // undefined (선언 이전에도 함수 스코프에 존재하는 것으로 인식됨.)
var x = 10;
}
test();
let, const의 호이스팅
💡 결론 - 호이스팅 후 초기화 전까지 TDZ에 있으므로 ReferenceError가 발생한다.
- 호이스팅이 되지 않는 것처럼 동작한다.
- JS의 모든 선언에는 호이스팅이 일어난다.
- let, const 키워드로 선언 및 초기화를 한 변수는 호이스팅이 발생하면 선언만 이루어지고, 실행 시점에서 실질적인 선언부를 만날 때까지 초기화는 이루어지지 않는다.
- 선언과 초기화 단계가 분리되어 진행된다.
- 초기화는 런타임에 실행
- 초기화 단계에 메모리가 할당된다
- 따라서 초기화 이전에 참조하면 참조 에러(ReferenceError)가 발생한다.
- 선언 이후~초기화 이전의 간극을 TDZ(Temporal Dead Zone, 일시적 사각지대)라고 한다. (변수 존재, 초기화 X)
- 이 간극만큼 해당 변수에 대한 메모리가 존재하지 않아 선언부 상단에서 참조 할당이 불가능하다.
- 선언 이후~초기화 이전의 간극을 TDZ(Temporal Dead Zone, 일시적 사각지대)라고 한다. (변수 존재, 초기화 X)
함수 호이스팅 주의사항
- 함수 표현식은 호이스팅되지 않는다.
func(); var func = function() {} // 변수 func의 호이스팅 발생 -> reference error 안일어남 // 함수가 undefined이므로 TypeError 발생
- 변수 선언문보다 함수 선언문이 먼저다.
- 동일한 이름으로 함수 선언문과 변수 선언문(= 함수표현식)이 있다면 함수 선언문의 호이스팅이 먼저 이루어진다.
func();
var func = function(){ console.log('변수 호이스팅') }
function func() {
console.log('함수 호이스팅');
}
// 함수 호이스팅
var의 단점은? 전역변수가 좋지 않은 이유는?
var 단점
- 함수 스코프를 가지나 호이스팅 현상으로 인해 함수 밖에서도 접근 가능
- 선언부 이전에 참조 가능
- 따라서 var 키워드로 선언된 변수를 전역 변수라고 볼 수 있음.
- 블록 스코프 미지원
- strict mode를 사용하면 var 키워드로 선언된 변수도 블록 스코프를 가진다.
- 재선언 가능
전역 변수의 단점
- 암묵적 결합
- 모든 코드가 전역 변수 참조 및 변경 가능
- 어떤 함수가 어떤 전역변수를 사용하는지 파악하기 어렵다.
- ⇒ 명확성 저하
- 긴 생명주기
- 메모리 리소스를 오랜 기간 소비
- 스코프 체인 상의 종점에 존재
- 전역 변수의 검색 속도가 가장 느리다
- 네임 스페이스 오염
- 여러 파일에서 같은 이름의 전역 변수 사용시 이름 충돌 발생 가능
'Programming language > JavaScript' 카테고리의 다른 글
[JavaScript] for 반복문 (2) | 2023.10.08 |
---|---|
[JavaScript] event (0) | 2023.08.16 |
[JavaScript] sort(), ASCII(아스키) 코드 : 배열 객체 정렬 오름차순 내림차순, 문자열 정렬, 문자 비교 (0) | 2023.08.08 |
[JavaScript] 템플릿 리터럴 : 문자열 내에 변수 삽입, 백틱(`) (0) | 2023.08.08 |
[JavaScript] 산술 연산자, 비교 연산자 : 몫과 나머지, '==='와 '=='의 차이 (0) | 2023.08.07 |
Comments