내용에 들어가기 전,
use strict
에 대해 간단히 알아보자.
use strict
를 사용하지 않은 첫 번째 사진에서는 선언되지 않은 변수a
에 6을 재할당 했는데도 불구하고 참조 요류가 뜨지 않았다.
use strict
를 사용한 두 번째 경우에서는 선언되지 않은 변수a
에 대한 참조 오류가 생긴 것을 확인할 수 있다.
위와 괕이 strict 모드
는 자바스크립트의 문법과 런타임 동작을 모두 검사하여 실수를 에러로 변환 및 체크할 수 있다.
여기서 말하는 바닐라 자바스크립트는 라이브러리나 프레임워크 없는, 순수한 자바스크립트를 뜻한다.
사용하고자 할 시, 자바스크립트 최상단에 'use strict';
라고 추가하면 된다.
hoisting
이란, 선언된 변수가 스코프 내부 최상단에 위치하는 것을 말한다. ✔ 스코프(scope): 범위, 즉 "변수에 접근할 수 있는 범위"를 뜻함, 전역 스코프, 지역 스코프로 나뉜다.
✔ 전역 스코프(global scope): 함수나 특정 블록({}
)에 속하지 않고 어디든 접근이 가능하며 이때 지정된 변수를전역변수
라 한다. (함수 외부에서 선언된 변수는 무조건전역변수
이다.)
✔ 지역 스코프(local scope): 코드 내 특정 영역에만 활동 및 접근이 가능하며 이때 지정된 변수를지역변수
라 한다. 이러한지역 스코프
는 해당 함수 내에서 자유로운함수 레벨 스코프
,{}블록
안에서만 자유로운블록 레벨 스코프
가 속한다.
var
: 선언이함수 레벨 스코프
내의 최상단에 위치하게 된다. (함수 안에서만 움직일 수 있음, 중괄호 무시)function init (){ console.log(sayHi) var sayHi = 'hello' // init의 최상단으로 호이스팅 됨 } init() // undefine
{ var age = 20; }; console.log(age); // 20(블록 스코프를 뚫고 나온다.)
let
,const
: 선언이블록 레벨 스코프
내의 최상단에 위치하게 된다. (중괄호 안에서만 접근 가능, 외부에서 참조 X){ let age = 20; } console.log(age) // Uncaught ReferenceError: age is not defined
자바스크립트의 변수는 크게 var
, let
, const
가 존재한다.
let
과 const
는 var
단점을 보완하기 위해 ES6(2015)에 추가되었다.
스코프에 대해 알고 있어야 이해하는데 좀 더 빠를 수 있다.
var
함수 레벨 스코프 지역 변수 (해당 블록을 넘어 속한 함수 내에서 어디든 이동이 가능하다.)
변수의 중복 선언을 허용한다.(가장 큰 단점)
변수 선언 전에도 참조가 가능하다.
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
블록 레벨 스코프 지역 변수 (해당 블록 안에서만 접근이 가능하다.)
할당한 값의 변경은 가능하나 let
을 통한 변수의 중복 선언을 허용하지 않는다.
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) 에 빠지므로 참조 오류가 발생하게 된다. 즉초기화
및할당
이 일어나지 않으면 참조를 할 수 없다.(결론적으로 값이 할당되기 직전에 초기화가 되는듯?...)
const
변수값을 지정함과 동시에 추후 변경이 불가능하다.
블록 레벨 스코프 지역 변수(해당 블록 안에서만 접근이 가능하다.)
변수의 값들을 대부분 const
로 지정하는 데는 다음과 같은 이유가 있다.
1. 보안상의 이유: 해커나 악성 코드들에 의해 삽입된 코드로 변수들이 변경되는 것을 방지한다.
2. 실수 최소화: 값이 변경되는 것을 막아 추후 생기는 버그를 최소화 시킬 수 있다.
웬만한 변수 값들은 const
로 작성하는 것이 바람직한 습관이다. (반복문에서의 iterable
값 같은 필수적인 경우는 예외)
let
과 같이 중복 선언을 허용하지 않는다.
var
와 다르게 선언문 이전에 참조를 할 경우 오류가 발생한다.
const a ; a = 1004; console.log(a); //Uncaught SyntaxError: Missing initializer in const declaration
const
는선언
과할당
이 따로 일어날 시, 오류가 발생한다.const a = 1004; console.log(a); // 1004
- 이처럼
선언
단계와할당
단계가 동시에 일어남을 알 수 있다.(자연스럽게초기화
도 같이..?)
목록 | 재할당(값변경) | 재선언(중복) | 호이스팅 | 변수선언과정 | 선언 이전 참조 오류 | 사용 |
---|---|---|---|---|---|---|
var | O | O | O | 선언+초기화(동시)/할당 | X | X(사용안하는 것이 좋다.) |
let | O | X | O | 선언/초기화/할당(단계별) | O | O |
const | X | X | O | 선언+초기화+할당(모두 동시) | O | O |
(내가 제대로 이해한 것이 맞는지 모르겠다 ... 수정할 부분은 계속해서 수정해야겠다 ..!!)
let 재할당 X 인거 아마 오타신거 같아요!! (let 설명하실때는 재할당 가능한거 잘 적어두셔서 🙂) 변수별로 실제 작동 과정은 어떤지 설명해주신거 넘 잘 읽었습니다 👍👏👩💻