[JS, TS] #variables

김상웅·2022년 8월 21일
0

✅ 키워드 비교


다음 세가지 항목은 변수 선언 키워드라고 불리우며,
이 키워드를 통해 변수와, 상수를 선언할 수 있습니다.

ES6 버전 이후 var 키워드 사용은 권장하지 않고 있으므로 let과 const를 활용한 변수 선언 방식을 권장합니다.

var (권장x)let (변수)const (상수)
값 재선언ΧΧ
값 재할당Χ
스코프 (scope)Function level
함수레벨 스코프Block({}) level
블록레벨 스코프Block({}) Scope
블록레벨 스코프
호이스팅 (hoisting)
Temporal Dead Zone
Temporal Dead Zone
//================================ 값 재선언 / 재할당
var a = 2;
var a = 3; // 3 재선언
a = 5; // 5 재할당

let b = "old";
let b = "new"; // SyntaxError! Identifier "b" has already been declared 재선언 불가능
b = "old friend" // "old friend" 재할당 가능

const c = "java"
const c = "javascript" // SyntaxError! Identifier "c" has already been declared. 재선언 불가능
c = "python" // TypeError! Assignment to constant variable. 재할당 불가능


✅ 스코프란? (Scope)


변수에 접근할 수 있는 범위를 가리킵니다.
범위는 중괄호(블록) 또는 함수에 의해 나누어집니다.

[주요 규칙]
1. 스코프 내부에서 외부로 접근할 수 있지만, 반대는 불가능합니다. (핵심)

- 스코프 외부에서 선언한 변수는 스코프 내부에서 사용할 수 있습니다.
- 스코프 내부에서 선언한 변수는 외부에서 사용할 수 없습니다.

2. 전역 스코프와 지역 스코프
- 전역 스코프 (Global Scope) 가장 바깥쪽의 스코프
- 지역 스코프 (Local Scope) 전역이 아닌 다른 스코프

3. 전역 변수와 지역 변수
- 전역 변수 전역 스코프에서 선언한 변수
- 지역 변수 지역 스코프에서 선언한 변수
- 지역 변수는 전역 변수보다 더 높은 우선 순위를 가집니다.

const div = document.querySelector(".box");

function 함수() {
	const 상수 = "변하지 않아요"
	console.log(상수)
	console.log(div)
}
함수() 
console.log(상수)
//스코프

//================================ 함수 스코프 ================================
// 함수 내부에서 선언된 스코프는 해당 함수 내에서만 선언할 수 있음.
// 함수의 중괄호 역시 블록스코프이기 때문에 let과 const는 함수 블록 내부 참조 불가

var outVar = "outer--var"
let outLet = "outer--let"
const outConst = "outer--const"

function a() {
	console.log(outVar, outLet, outConst); // "outer--var", "outer--let", "outer--const"

	var innerVar = "inner-var"
	let innerLet = "inner-ler"
	const innerConst = "inner-const"
	console.log(innerVar, innerLet, innerConst) // "inner-var" "inner-ler" "inner-const"

	// var 블록 스코프의 영향을 받지 않는다.
	for ( var i = 0; i < 5 ; i++ ) {
		console.log(i) // 0, 1, 2, 3, 4
	}
	console.log(i) // 5

}
a() // "outer--var", "outer--let", "outer--const"
		// "inner-var" "inner-ler" "inner-const"
		// 0 1 2 3 4
		// 5
				
console.log(outVar, outLet, outConst); // "outer--var", "outer--let", "outer--const"
console.log(innerVar, innerLet, innerConst); // ReferenceError: innerVariable is not defined

//================================ 블록 스코프 ================================

// 대표적인 블록스코프 예시
// let (const 사용 시 TypeError: Assignment to constant variable 에러 발생)	
for ( let i = 0; i < 5 ; i++ ) {
	console.log(i) // 0, 1, 2, 3, 4
}
console.log(i) //ReferenceError: i is not defined
	
	

{
	var blockVar = "block--var"
	const blockConst = "block--const"
	let blockLet = "block--let"
  console.log(blockVar, blockConst, blockLet) // "block--var" "block--const" "block--let"
}
console.log(blockVar); // "block--var"
console.log(blockConst); // ReferenceError: blockConst is not defined
console.log(blockLet); // ReferenceError: blockLet is not defined


✅호이스팅이란? (Hoisting)


MDN : 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 가리킵니다.

쉬운 말
아래에 있는 선언(let, const , function, class)을
해당 스코프의 최상단으로 끌어올린다!


function 함수() {
	console.log("클릭")
}

버튼.addEventListener("click", 함수);
// 호이스팅

//================================ 함수 먼저 ================================
function Hello() {
	console.log("안녕하세요")
}
Hello() // "안녕하세요"

//================================ 선언 먼저 ================================
Hello() // "안녕하세요"

function Hello() {
	console.log("안녕하세요")
}

// ================================ var ================================
// var*로 선언된 변수는 최상단으로 위치하게 되어 해당 코드가 정상적으로 실행된다.

var a = undefined // 선언 및 초기화 단계
console.log(a) // undefined
var a = 1
console.log(a) // 1*

// ================================ *let & const*================================
*// let과 const도 hoisting이 발생하지만 변수를 참조하기 위해서는
// 변수 선언한 부분을 넘어서야 된다. 그 이전까지를 일시적 사각지대라고 부른다.

console.log(b) // ReferenceError: Cannot access 'b' before initialization (TDZ ↑)
let b // 선언 단계
console.log(b) // undefined
let b = 2 // 변수에 값 할당을 통한 초기화
console.log(b) // 2*


✅ 결론


Hoisting이 발생하는 코드는 가독성 낮아지고, 유지보수가 어려워집니다.
의도치 않은 결과물 출력 등의 결과를 맞이할 수 있어 Hoisting을 일부러 할 필요는 없지만 방지하는 것이 좋습니다.

Hoisting을 방지하기 위해 함수의 경우 선언 후에 호출을 하도록 하며, const와 let을 사용할 것을 권장합니다.

블록스코프 추가 이해

constlet으로 선언한 값은 블록스코프로 선언이 되기 때문에 같은 블록 내에서 선언한 변수는 해당 블록 내에서만 사용이 가능합니다.

++ 블록 밖의 범위에서 똑같은 이름을 가진 값이 있다고 해도 영향을 주지 않습니다.

const value = '전역 스코프입니다!';

function functionScope() {
  const value = '함수 스코프입니다!';
  if (true) {
    const value = '블록 스코프입니다!';
    console.log('block scope: ');
    console.log(value);
  }
  console.log('function scope: ');
  console.log(value);
}

functionScope();
console.log('global scope: ');
console.log(value);

profile
누구나 이해할 수 있도록

0개의 댓글