TIL 10 | JavaScript hoisting,let,var,const

ym j·2021년 3월 15일
1

사전스터디 

목록 보기
10/23
post-thumbnail

내용에 들어가기 전, use strict에 대해 간단히 알아보자.



use strict in Vanilla JS

  • use strict를 사용하지 않은 첫 번째 사진에서는 선언되지 않은 변수 a에 6을 재할당 했는데도 불구하고 참조 요류가 뜨지 않았다.
  • use strict를 사용한 두 번째 경우에서는 선언되지 않은 변수 a에 대한 참조 오류가 생긴 것을 확인할 수 있다.
  • 위와 괕이 strict 모드자바스크립트의 문법과 런타임 동작을 모두 검사하여 실수를 에러로 변환 및 체크할 수 있다.

  • 여기서 말하는 바닐라 자바스크립트는 라이브러리나 프레임워크 없는, 순수한 자바스크립트를 뜻한다.

  • 사용하고자 할 시, 자바스크립트 최상단에 'use strict'; 라고 추가하면 된다.



hoisting

  • hoisting이란, 선언된 변수가 스코프 내부 최상단에 위치하는 것을 말한다.

    스코프(scope): 범위, 즉 "변수에 접근할 수 있는 범위"를 뜻함, 전역 스코프, 지역 스코프로 나뉜다.
    전역 스코프(global scope): 함수나 특정 블록({})에 속하지 않고 어디든 접근이 가능하며 이때 지정된 변수를 전역변수라 한다. (함수 외부에서 선언된 변수는 무조건 전역변수이다.)
    지역 스코프(local scope): 코드 내 특정 영역에만 활동 및 접근이 가능하며 이때 지정된 변수를 지역변수라 한다. 이러한 지역 스코프는 해당 함수 내에서 자유로운 함수 레벨 스코프, {}블록 안에서만 자유로운 블록 레벨 스코프가 속한다.

  1. var: 선언이 함수 레벨 스코프 내의 최상단에 위치하게 된다. (함수 안에서만 움직일 수 있음, 중괄호 무시)
function init (){
	console.log(sayHi)
  	var sayHi = 'hello' // init의 최상단으로 호이스팅 됨 
}
	init() // undefine
{
    var age = 20;
};
	console.log(age); // 20(블록 스코프를 뚫고 나온다.)
  1. let, const: 선언이 블록 레벨 스코프 내의 최상단에 위치하게 된다. (중괄호 안에서만 접근 가능, 외부에서 참조 X)
{
	let age = 20;
}
console.log(age) // Uncaught ReferenceError: age is not defined


Variable

  • 자바스크립트의 변수는 크게 var, let, const가 존재한다.

  • letconstvar 단점을 보완하기 위해 ES6(2015)에 추가되었다.

  • 스코프에 대해 알고 있어야 이해하는데 좀 더 빠를 수 있다.



1. var, let (mutable)

  • var
  1. 함수 레벨 스코프 지역 변수 (해당 블록을 넘어 속한 함수 내에서 어디든 이동이 가능하다.)

  2. 변수의 중복 선언을 허용한다.(가장 큰 단점)

  3. 변수 선언 전에도 참조가 가능하다.

console.log(a);
var a = 1004; // undefined
console.log(1004)'; // 1004
  • 위 예제의 실제 실행 과정은 다음과도 같다.
var a;	// 변수 선언 부분만 끌어 올려짐 (호이스팅, 선언, `undefined`으로 초기화 동시에 발생)
console.log(a);	// undefined
a = 1004; // 할당 단계, 할당 단계는 호이스팅 되지 않음
console.log(a);	// 1004
  • 이는 변수 지정 과정인 "선언->초기화->할당" 에서 선언초기화가 동시에 일어나기 때문이다. 위와 같이 선언문이 호이스팅 에 의해 최상단으로 이동한다. 그리고 스코프에 변수를 등록(선언)하고 메모리에 변수를 위한 공간을 확보한 후, undefined로 초기화하는 과정이 동시에 일어난다. 따라서 var의 경우 선언문 이전에 변수에 접근하여도 스코프에 초기화된 변수가 존재하기 때문에(undefined) 에러가 발생하지 않는다.

  • let
  1. 블록 레벨 스코프 지역 변수 (해당 블록 안에서만 접근이 가능하다.)

  2. 할당한 값의 변경은 가능하나 let을 통한 변수의 중복 선언을 허용하지 않는다.

  3. var와 다르게 선언문 이전에 참조를 할 경우 오류가 발생한다.

console.log(a);
let a = 1004; // Uncaught ReferenceError: a is not defined
let a; // 선언 단계만 이루어짐, 동시에 초기화 X
console.log(a); // Uncaught ReferenceError: a is not defined
a = 1004; // 
  • var와 다르게 "선언->초기화->할당" 에서 선언초기화가 동시에 일어나지 않는다. 실제로는 let 선언부가 호이스팅 에 의해 최상위로 끌어 올려지지만, 초기화가 되기 전까지 TDZ(Temporal Dead Zone) 에 빠지므로 참조 오류가 발생하게 된다. 즉 초기화할당이 일어나지 않으면 참조를 할 수 없다. (결론적으로 값이 할당되기 직전에 초기화가 되는듯?...)


2. const (immutable)

  • const
  1. 변수값을 지정함과 동시에 추후 변경이 불가능하다.

  2. 블록 레벨 스코프 지역 변수(해당 블록 안에서만 접근이 가능하다.)

  3. 변수의 값들을 대부분 const로 지정하는 데는 다음과 같은 이유가 있다.
    1. 보안상의 이유: 해커나 악성 코드들에 의해 삽입된 코드로 변수들이 변경되는 것을 방지한다.
    2. 실수 최소화: 값이 변경되는 것을 막아 추후 생기는 버그를 최소화 시킬 수 있다.

  4. 웬만한 변수 값들은 const로 작성하는 것이 바람직한 습관이다. (반복문에서의 iterable값 같은 필수적인 경우는 예외)

  5. let과 같이 중복 선언을 허용하지 않는다.

  6. var와 다르게 선언문 이전에 참조를 할 경우 오류가 발생한다.

const a ;
a = 1004;
console.log(a); //Uncaught SyntaxError: Missing initializer in const declaration
  • const선언할당이 따로 일어날 시, 오류가 발생한다.
const a = 1004;
console.log(a); // 1004
  • 이처럼 선언 단계와 할당단계가 동시에 일어남을 알 수 있다. (자연스럽게 초기화도 같이..?)


3. 정리

  • 내용이 좀 많이 길어진 것 같다. 요약을 하자면 다음과 같다.
목록재할당(값변경)재선언(중복)호이스팅변수선언과정선언 이전 참조 오류사용
varOOO선언+초기화(동시)/할당XX(사용안하는 것이 좋다.)
letOXO선언/초기화/할당(단계별)OO
constXXO선언+초기화+할당(모두 동시)OO

(내가 제대로 이해한 것이 맞는지 모르겠다 ... 수정할 부분은 계속해서 수정해야겠다 ..!!)

profile
블로그를 이전하였습니다 => "https://jymini.tistory.com"

2개의 댓글

comment-user-thumbnail
2021년 3월 17일

let 재할당 X 인거 아마 오타신거 같아요!! (let 설명하실때는 재할당 가능한거 잘 적어두셔서 🙂) 변수별로 실제 작동 과정은 어떤지 설명해주신거 넘 잘 읽었습니다 👍👏👩‍💻

1개의 답글