🦖 var,let,const 의 역사
var,let 키워드는 변수를 선언할때 사용하고 const 키워드는 상수를 선언할때 사용한다.
Let과 Const는 2015년 ES6 에 탄생한 문법이다. 그 이전에는 변수와 상수 구분없이 Var키워드를 사용했었다.
❓왜 Let 과 Const가 탄생하게 된것일까?
Var와 Let은 변수를 선언할때 사용하는 키워드이다. 변수이기 때문에 값을 변경 할 수 있다.
얼핏보면 같은 느낌이지만 그렇지 않다.
🆚 Var와 Let의 차이점은 크게 3가지가 있다.
1️⃣ 스코프 (Scope)
2️⃣ 중복 선언 (Variable redeclatation)
3️⃣ 호이스팅 (Hoisting)
📌 스코프
자바스크립트에서 스코프란 코드가 변수에 접근할 수 있는 범위를 뜻한다.
✅ 스코프의 종류 3가지
1️⃣ Var 키워드로 선언된 변수는 함수 스코프를 가진다.
2️⃣ Let 키워드로 선언된 변수는 블록 스코프를 가진다.
3️⃣ 만약 변수가 어느함수에도 속하지 않은 최상위 함수 외부에 선언된 변수라면 글로벌 스코프를 가진다.
🆚 블럭 스코프(Let) vs 함수 스코프(Var)
function varkeyword () {
var a = 'hello'
if(true){
var a = 'hi'
}
console.log(a) // hi
// var 키워드는 함수스코프를 가지기 때문에 if 블럭 안에 있는 변수 a와 바깥에 있는 변수 a는 같은 스코프를 가진다.
// var는 같은 스코프를 가지게 되면 중복 선언을 허용한다. 그러므로 hi 가 출력된다.
}
varkeyword();
function letkeyword () {
let a = 'hello'
if(true){
let a = 'hi'
}
console.log(a); // hello
// 'hi'값은 if블럭 내부에서만 유효하기 때문에 블럭 바깥에서 접근하는 a 변수는 같은 스코프인 'hello'를 가르킨다.
}
letkeyword();
function main() {
for (let i=0; i<5; i++){
console.log(i); // 0~4 까지 한번씩 찍힌다.
}
console.log(i); // 레퍼런스 에러
}
main()
function main2() {
for (var i=0; i<5; i++){
console.log(i); // 0~4 까지 한번씩 찍힌다.
}
console.log(i); // 5 까지 찍힌다.
//var은 함수스코프이기때문에 for블럭 외부에서도 증감식에 증가된 값이 찍히는 것이다.
}
main2()
let 키워드와 var 키워드의 스코프 차이점 예제이다. 직접 실행해보자!
🌏 글로벌 스코프(전역 스코프)
var aVar = 'varHello';
let aLet = 'letHello';
이 두 변수는 함수로 감싸져 있지 않기 때문에 프로그램에서 전역적으로 접근 할 수 있는 전역변수라고 볼 수 있다.
🆚 여기서도 var 와 let은 차이점이 존재한다..
우리 브라우저에는 window라는 객체가 있는데, window라는 객체는 단 하나밖에 없는 전역객체이다.
❗️우리가 var 키워드를 사용해서 전역변수로 만들면 window객체의 속성으로 등록이 된다.
❗️하지만 let 키워드를 사용해서 전역변수로 만들면 window객체의 속성으로 등록이 되지않는다.
이 window 객체는 우리 브라우저의 정보를 담고있는 단 하나밖에없는 객체이며 이 객체는 우리가 작성한 코드 , 우리가 사용하고있는 모든 라이브러리들이 공유하고 있는 전역객체이다.
그렇기 때문에 window 객체에 속성을 추가하는 것은 위험하다. 왜냐하면 window 객체는 전역적으로 공유되고 있는 객체이기 때문에 여러 곳에서 접근을 할 수 있고 값을 변경 할 수 있기 때문이다.
우리가 등록한 aVar라는 속성이 다른 코드로 인해 덮어 씌워질 수 도 있다. 혹은 우리가 덮어 씌워버릴 수 도 있다. 그러면 예상치 못한 버그를 발생 시킬 수 있다.
그렇기 때문에 var 키워드를 사용해서 전역변수를 만드는 것은 정말정말 좋지 않은 습관이다..😭
📌 중복선언 - var를 사용하면 할 수 있는 대표적인 미친 짓(?)이 있다..😡
var x = '강동욱';
var x = '강동원';
console.log(x); // 강동원
우리는 지금 같은 이름을 가진 변수를 중복 선언했다.
다른 프로그래밍 언어를 공부 한 사람들은 "아니, 이게 에러가 안난다고? 미친거야..😡"라 할 것 이다.
이 var키워드를 사용하면 같은 이름의 변수를 중복해서 선언 할 수 있다.
그리고 위에서 선언한 변수가 아래에서 선언한 변수때문에 덮어 씌워진다..
이게 코드를 굉장히 헷갈리게 만들고 다른 개발자들과 협업을 할 때 미움을 살수도 있다.😭
let x = '강동욱';
let x = '강동원'; // Uncaught SyntaxError: Identifier 'x' has already been declared
하지만 let 키워드를 사용하면 이미 x 가 선언 되었다고 에러를 발생시켜준다.
만약에 프로그램이 커지고 코드 양이 많아지다보면 작성한 변수이름을 까먹기가 굉장히 쉽다.
let은 이렇게 중복 선언을 시도하면 에러를 발생시켜주니까 훨씬 더 안전하게 코딩 할 수 있게 해준다.
💡 그러므로 꼭 let 을 사용하자!
📌 호이스팅
변수 호이스팅 ⬆️
변수 호이스팅이란 프로그램이 실행되기 이전에 변수의 선언과 변수의 초기화를 분리해서
변수의 선언부분만 프로그램 맨위로 끌어올려주는것을 의미한다.
비유로 이야기하자면 프로그램이 실행되기 이전에 자바스크립트한테 우리가 사용하는 변수들의 존재를 미리 알려주는 것이다.
console.log(num); // undefined
// 왜 undefined가 찍힐까??
//var키워드의 호이스팅 특징이다. var키워드는 변수의 선언을 맨 위로 호이스팅 할때 undefined로 초기화시킨다.
var num = 10;
console.log(num); // 10
변수 선언문 이전에 변수에 접근하는 이런 엉뚱한 짓은 하면 안된다. 그래서 let 을 사용하게 된다 밑의 설명을 보자
console.log(num2); // Uncaught ReferenceError: Cannot access 'num2' before initialization
// 참조 에러 : num2를 초기화하기 이전에 접근 할 수 없다.
let num2 = 10;
// let의 호이스팅 특징 - 변수 선언 부분 을 위로 호이스팅을 하긴 하지만 var과 다르게 초기화 시키진 않는다.
let도 var 처럼 변수의 선언부분을 맨 위로 호이스팅 하긴 하지만 var와는 다르게 변수를 초기화 시키지 않는다.
이 일시적 사각지대 때문에 변수 선언문 전에 변수에 접근하는 이런 엉뚱한 짓을 막을 수 있고 더 안전하게 코딩할수 있다!
💬 Const
const는 let과 정말 비슷하다. 블록스코프이고, 중복선언을 허용하지않고, 그리고 호이스팅시에 초기화를 하지 않기 때문에 let과 마찬가지로 선언문 이전 접근 불가이다.
🆚 let과 한가지 다른점
const는 변수가 아니라 상수를 선언한다. 그 말은 한번 값을 할당하면 또 다시 할당연산자를 사용해서 재할당 할수 없다는 것이다.
const a; // Uncaught SyntaxError:Missing initializer in const declaration
a = "123";
const는 선언만 할수 없다. 꼭 초기화를 같이 해줘야한다.
왜냐하면 const는 할당연산자를 사용해서 새로운 값을 할당 할 수 없기 때문이다.
⚡️ const 주의 할점
const 에 참조자료형인 객체나 배열을 선언하면 마찬가지로 재할당은 불가능 하지만 속성,요소를 바꾸는 것은 가능하다.
코드로 보여주겠다.
const a = {
x: 1,
y: 2
};
a = { x:3 } // Uncaught TypeError: Assignment to constant variable.
// 재할당 불가능
const a = {
x: 1,
y: 2
};
a.z = 3;
console.log(a); // {x: 1, y: 2, z: 3}
이렇게 객체의 속성을 바꿀 수 있는 이유는 이것은 새로운 객체를 할당 하는게 아니라 원래 갖고 있는 객체는 유지하면서 내부적인 속성을 변경하는거니까 가능한 것이다.(객체나 배열은 참조자료형이므로 변수에 주소를 저장하므로
그런데 나는 객체의 속성을 변경하는 것을 막고싶다. 객체의 불변성을 유지하고싶다 하면 아래처럼 Object.freeze( ) 함수를 사용하자.
const a = Object.freeze({
x: 1,
y: 2
});
a.z = 3;
console.log(a); // {x: 1, y: 2}
'코드스테이츠 > 헷갈리는거 정리' 카테고리의 다른 글
HTTP,AJAX,XHR,XML,JSON 정리 (0) | 2023.01.19 |
---|---|
type , const (0) | 2023.01.04 |
원시 자료형과 참조 자료형 (0) | 2023.01.02 |
배열 복사하기 (0) | 2023.01.02 |
GUI 와 CLI (0) | 2023.01.01 |