JavaScript - 변수(var, let, const)의 차이는?

김민재·2021년 7월 22일
0

TIL, Deep Javascript

목록 보기
3/22
post-thumbnail

*🔐Study Keyword :

변수(var, let, const) 🔑차이점에 대해서 이해하자!

- var vs let vs const의 차이점


(이미지 출처: https://thenextweb.com/news/how-to-declare-interact-and-scope-variables-in-javascript/)

  • 자바스크립트의 세 변수 타입에 차이에 대해서 살펴보기 전에 알아야한 세 가지 키워드가 있다.
  • var는 let과 const와 달리 블럭스코프가 아니며 호이스팅이 적용된다.
  • const와 let은 재할당 부분에서 차이가있으며 var는 let과 const와 재선언 부분에 차이가 있다.

#1.🔑var vs const & let 유효 범위(scope)

#2.🔑호이스팅(hoisting)

#3.🔑재할당과 재선언(reassign & redeclare)

#1. 변수의 유효 범위(variable scope)

  • WHAT IS❓변수의 유효 범위(scope)란 변수와 그 값이 어디서부터 어디까지 유효한지를 판단하는 것을 의미합니다.
  • WHY & WHNE USE❔❕ 프로그래밍할때 코드의 양이 많아지면 선언된 변수가 충돌할 때가 있는데 scope는 이러한 충돌을 막기위해 고안된 것입니다.
  • HOW TO USE❕❓ 이처럼 스코프는 참조 대상 식별자(identifier, 변수, 함수의 이름과 같이 어떤 대상을 다른 대상과 구분하여 식별할 수 있는 유일한 이름)를 찾아내기 위한 규칙이다.
  • 자바스크립트의 경우 기본적으로 함수가 선언되는 동시에 자신만의 scope 규칙을 가지게 되는데 구분해보면 다음과 같이 2가지로 나눠진다.

-규칙 1. Global scope와 Local scope

🔶전역 스코프 (Global scope) - 전역 스코프는 코드 어디에서든지 참조할 수 있다.
🔶지역 스코프 (Local scope or Function-level scope) - 함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조할 수 있다.

-규칙 2. Block Scope와 Function scope

🔶블록 레벨 스코프(block-level scope) - 블록 레벨 스코프란 코드 블록{…}내에서 참조(접근)할 수 있는 스코프로 block 밖은 접근할 수 없다.
🔶함수 레벨 스코프(function-level scope) - 함수 레벨 스코프란 함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 유효하고 함수 외부에서는 유효하지 않아 함수 밖에선 접근할 수 없다.

  • 모든 변수는 스코프를 갖는다. 따라서 변수의 관점에서 스코프를 구분하면 다음과 같이 2가지로 나눌 수 있다.

    🔷전역 변수 (Global variable) - 전역에서 선언된 변수이며 어디에든 참조할 수 있다.
    🔷지역 변수 (Local variable) - 지역(함수) 내에서 선언된 변수이며 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.

    🔻따라서 변수는 선언 위치(전역 또는 지역)에 따라서 자신 만의 스코프를 가지게 된다.
    -전역에서 선언된 변수는 전역 스코프를 갖는 전역 변수가 되고 전역변수는 전역(코드 어디서든지)에서 참조할 수 있다.
    -지역(자바스크립트의 경우 함수 내부)에서 선언된 변수는 지역 스코프를 갖는 지역 변수가 된되고 지역 변수는 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.

#1-α. 🔑var vs const & let 유효 범위(scope)

  • var 변수는 함수블록 이외의 블록은 무시하고 선언되어 모든 영역에서 사용할 수 있는
    🗝️전역스코프와 지역스코프(함수 레벨 스코프) 모두의 유효범위 규칙을 따른다.
  • var는 함수블록 이외의 블록은 무시하고 선언되어 모든 영역에서 사용할 수 있는 전역 변수가 된다.
<script>
//예시1
var globalVar = 1 // 전역변수
function varTest() {
  var localVar = 2; // 지역변수, 함수 내에서 선언된 매개변수와 변수는 함수 외부 유효하지 않다.
}
console.log(globalVar) //1
console.log(localVar) // "localVar" is not defined
//따라서 var는 함수 밖에서는 접근할 수 없어 ReferenceError가 발생!
//예시2
var iAmVar = 0;
{
  var iAmVar = 1;
  console.log(iAmVar); // 1
  // var는 코드 블록 내에서 선언되었다 할지라도 모두 전역 스코프를 가진다.
}
console.log(iAmVar);   
// 따라서 var는 0이 아닌 블록 안에 1값이 나온다.
</script>
  • 반면 const와 let 변수는 블록 안에 있으면 블록 안에 있는 변수를 볼 수 없고 블록 밖으로도 접근할 수 없는 🗝️블록 레벨 스코프만의 유효범위 규칙을 따른다.
//예시3
<script>
let iAmLet = 0;
{
  let iAmLet = 1;
  console.log(iAmLet); // 1
  // let과 const는 블록 안에 선언된 변수는 블록 밖에서 보이지 않는다. 
}
console.log(iAmLet);   
// 따라서 1이 아닌 블록 밖, 전역에 있는 0값이 나온다.
</script>

*💡TIP

  • 전역 변수는 어플리케이션이 시작되서 끝날 때까지 항상 메모리에 탑재되어있기 때문에 최소한으로 쓰는 것을 권장한다.
  • 가능하면 클래스, 함수, if나 for을 활용해 필요한 부분에서만 정의해서 쓰는 것이 좋다.

#2. 🔑호이스팅(hoisting)

  • hoisted 측면에서 var는 hoisted가 가능하지만 const와 let은 불가능하다.
  • WHAT IS❓ 호이스팅(hoisting)이란 변수 선언이 함수 또는 전역 코드의 상단에 이동하는 것과 같은 행동으로 즉, 어디에 선언했는지와 상관없이 항상 제일 위로 선언을 끌어올려주는 현상을 말합니다.
  • HOW TO USE❕❓
    -var변수의 경우 값을 선언하기도 전에 사용할 수 있는데 이러한 현상을 var hoisting이라 부른다.
<script>
hoisting = 2
var hoisting;
// var변수는 코드 안에서 어디서든 변수 선언을 최상위에 선언한 것과 같게된다.
</script>

#3. 🔑재할당과 재선언(reassign & redeclare)

  • const와 let은 재할당과 측면에서 비교해 봤을 때 const는 재할당이 가능하며 let은
    불가능하다. 그 이유는 let은 변수, const는 상수이기 때문이다.

3-1. Variable, rw(read/write)

  • WHAT IS❓ Variable, 변수란 변경될 수 있는 값들로 메모리에 값을 읽고 쓰는게 가능하다.

  • HOW TO USE❕❓
    -어플케이션을 실행하면 어플리케이션 마다 쓸 수 있는 메모리가 할당되어진다.
    -텅빈 박스와 같은 메모리는 어플케이션 마다 쓸 수 있는 메모리가 제한적으로 할당된다.
    -step1. let 키워드로 name 변수를 정의하게 되면 텅빈 박스 한 공간(?)인 메모리를 가리킬 수 있는 '포인터'가 생긴다.
    -step2. name 변수가 가리키고 있는 메모리 어딘가에 'elle'라는 값을 저장할 수 있다.
    -step3. 추후에 name 변수가 포인터를 가리키고 있는 곳에 다른 값을 넣어서 저장할 수도 있다.
    (= let 키워드는 값의 재할당이 가능하다🎇).

3-2. Constant, r(read only)

  • WHAT IS❓ Constant, 상수는 변하지 않는 값들로 메모리에 값이 한 번 할당되면 절대로 바뀌지 않고 오직 값을 읽기만 가능합니다.


-step1. const 키워드로 maxNumber 변수를 선언하고 값을 '5'를 할당할 수 있다.
-step2. const 키워드를 사용하면 maxNumber 변수가 메모리에 가리키고 있는 포인터에 자물쇠가 형성되어서 잠겨있는 상태가 된다.
-step3. 따라서 const는 오직 읽기만 가능하여 다른 값으로 쓰는 것이 불가능해 선언함과 동시에 값을 할당한 뒤로엔 절대 값을 변경할 수 없다.
(= const 키워드는 값의 재할당이 불가능하다🎇).

+α. 데이터 타입

  • 데이터 타입은 두가지로 구분된다.

-WHAT IS❓ mutable data type은 let과 같이 값이 계속 변경될 수 있는 데이터 타입으로, javscript에선 모든 object, 객체가 변경이 가능하다.
-WHAT IS❓ immutable data type은 반대로 값이 변경이 불가능한 데이터 타입으로, 원시형 타입과 같이 데이터 자체를 변경할 수 없고 객체 중에서도 frozen object와 같은 객체는 변경이 불가능하다.

변수의 생명주기

지역변수의 생명주기는 함수의 생명주기와 일치한다

호이스팅은 스코프를 단위로 동작한다.
호이스팅은 변수 선언이 스코프으 ㅣ선두로 끌어올려진 것처럼 동작한다는 것이 더 정확하다

var 키워드로 선언한 전역변수의 생명주기는 전역 객체의 생명 주기와 일치한다

번외) 전역변수의 사용억제방법

전역 변수의 문제?

  • 암묵적 결합, 전역변수 선언 의도 코드 어디서든 참조 할당 할수 있는 변수를 사용한다.
  • 모든 코드가 전역 변수를 참조하고 변경할 수 있는 암묵적 결합을 허용한 것
  • 긴 생명주기, 전역변수는 생명ㅈ주기가 길다
  • 스코프 체인상에서 종점에 존재
  • 전역변수의 검색속도가 가장 느리다
  • 네임스페이스 오염
    => 전역변수를 반드시 사용해야할 이유를 찾지 못한다면 지역변수를 사용해야한다. 변수의 스코프는 좁을수록 좋다.
  1. 즉시 실행함수
  • 모든 코드를 즉시 실행함수로 감싸면 모든 변수는 즉시실행 함수의 변수가 된다,
(function(){
var foo = 10
}());
console.log(foo)//참조에러
  1. 네임스페이스 객체
  • 전역에 네임스페이스 역할을 담당할 객체를 생성하고 정녁변수 처럼 사용하고 싶은 변수를 프로퍼티로추가하는 방법
var MYAPP={} //전역 네임스페이스 객체
MYAPP.name = 'minjae'
console.log(MYAPP.name)/

3.모듈 패턴화

*💡conclusion

  • WHY❔❕ var 변수를 사용하면 안되는 이유 2가지.
    1> var는 var hoisting이 일어나서 선언하지 않아도 값을 불러오게 되는 오류가 생긴다.
    2> var변수는 또한 블록 스콥을 철저히 무시한다.
    🔅참고🔅)이러한 위험성으로 인해 ES6이후 새로 등장한 변수가 let과 const 변수!
  • WHY❔❕ 변수를 선언시 const 사용을 권하는 대표적인 이유 3가지.
    1>security -
    코드를 해커들이 다른 코드를 삽입해서 값을 변경하는 것을 방지한다.
    2>thread safety -
    다양한 쓰레드들이 동시에 변수에 접근하여 값을 변경하는 건 위험 부담이있다. 따라서 가능하면 값이 변하지 않는 상수를 사용하는 것이 좋다.
    3>reduce human mistakes -
    본인이나 다른 개발자가 코드 변경할 때도 실수를 방지해준다.

#📑Study Source

  1. 유튜브 드림코딩by앨리
profile
자기 신뢰의 힘을 믿고 실천하는 개발자가 되고자합니다.

0개의 댓글