변수(Variable)

고유한 식별자(변수명)에 의해 구별해서 값을 참조할 수 있다.

식별자는 데이터가 저장된 메모리 상의 주소를 기억해서 메모리에 저장된 값을 참조한다.

 

식별자(변수명) 명명 규칙

  • 반드시 영문자(특수문자 제외), underscore ( _ ), 또는 달러 기호($)로 시작하여야 한다. 이어지는 문자에는 숫자(0~9)도 사용할 수 있다.
  • 자바스크립트는 대/소문자를 구별하므로 사용할 수 있는 문자는 “A” ~ “Z” (대문자)와 “a” ~ “z” (소문자)이다.

동적 타입 언어

자바스크립트는 동적 타입 언어.

타입 지정 없이 값이 할당되는 과정에서 값의 타입에 의해서 자동으로 타입이 결정됨. 

같은 변수에 여러 타입의 값을 할당가능. 이를 동적 타이핑

var foo;

console.log(typeof foo);  // undefined

foo = null;
console.log(typeof foo);  // object

foo = {};
console.log(typeof foo);  // object

foo = 3;
console.log(typeof foo);  // number

foo = 3.14;
console.log(typeof foo);  // number

foo = 'Hi';
console.log(typeof foo);  // string

foo = true;
console.log(typeof foo);  // boolean

 

var vs let vs const 

  var let const
global scope o x x
script scope x o o
functional local scope o o o
block scope x o o
재선언 o x x
재할당 o o x

이고잉님 유튜브 참고: https://www.youtube.com/watch?v=61iolhWgQt0&t=543s

 

 

ES5까지는 변수를 참조할 수 있는 방법은 var 키워드밖에 없었음

var은 타 언어와 달리 여러 특징이 있는데 이것은 심각한 문제를 일으킬 수 있다

  1. 함수레벨 스코프
    => for 문의 변수 선언문에서 선언한 변수를 for 문의 코드 블록 외부에서 참조할 수 있다, 전역변수의 남발
    for(var i=0; i<5; i++){
        console.log(i) // 0, 1, 2, 3, 4
    }
    console.log(i) //5​
  2. var 키워드 생략 허용
  3. 변수 중복 선언 허용
  4. 변수 호이스팅
    => 변수를 선언하기 전에 참조 가능

=> 대부분의 문제는 전역변수로 인해 발생, 전역변수는 유효범위가 넓어서 어디서 어떻게 사용할지 파악하기 힘들며 복잡성을 증가시킬 수 있다. 따라서 변수의 스코프는 좁을수록 좋다

 

=> ES6부터 나온 let과 const가 var의 단점을 보완하기 위해 도입

 

let

  1. 블록레벨 스코프
    for(let i=0; i<5; i++){
    	console.log(i) //0, 1, 2, 3, 4
    }
    console.log(i) //Uncaught ReferenceError: i is not defined
  2. 변수 중복 선언 금지
    var foo = 123;
    var foo = 456;  // 중복 선언 허용
    
    let bar = 123;
    let bar = 456;  // Uncaught SyntaxError: Identifier 'bar' has already been declared
  3. 호이스팅 - 일시적 사각지대 (Temporal Dead Zone)
    **호이스팅(Hoisting): var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성

    변수가 선언문 이전에 참조하면 var는 undefined를 반환하지만 let은 ReferenceError가 발생한다.
    -> let 선언은 var 선언과 달리 TDZ에 의해 제약을 받는다.

    console.log(foo) //undefined
    var foo;​

    var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다. (호이스팅)
    변수 선언문 이전에 변수에 접근하여도 에러가 발생하지 않는다.  
    console.log(bar); // Error: Uncaught ReferenceError: bar is not defined => TDZ
    let bar; // let bar = undefined; 와 같다, 변수 선언문에서 초기화가 이루어진다.
    
    console.log(bar); // undefined
    
    bar = 1; // 할당문에서 할당 단계가 실행된다.
    console.log(bar); // 1

    let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.
    선언단계만 호이스팅되기 때문에 초기화 이전에 변수에 접근하려고 하면 Reference Error가 발생한다
    그래서 초기화 단계가 진행돼야 참조할 수 있게 된다. (let 변수는 변수 선언문에서 초기화가 이루어진다.)
    변수 선언문 이후에 변수에 접근해야 에러가 발생하지 않는다.


    스코프의 선두부터 초기화 지점까지의 구간을 일시적 사각지대 (Temporal Dead Zone)이라고 부른다
    코드 실행이 변수가 실제 있는 위치에 도달할 때까지 액세스할 수 없는 것이다.
    let 변수가 선언된 시점에서 제어 흐름은 TDZ를 떠난 상태이며, 변수를 사용할 수 있게 된다.

 

const

  1. 블록레벨 스코프
  2. let은 재할당이 자유로우나 const는 재할당이 금지
    => const는 반드시 선언과 동시에 할당이 이루어져야 한다
    const FOO = 123;
    FOO = 456; // TypeError: Assignment to constant variable.
    const FOO; // SyntaxError: Missing initializer in const declaration
  3. 상수
  4. const와 객체
    => const는 재할당은 불가능하지만 할당된 객체의 내용(프로퍼티의 추가, 삭제, 프로퍼티 값의 변경)은 변경할 수 있다.
    const user = { name: 'Lee' };
    
    // 객체의 내용은 변경할 수 있다.
    user.name = 'Kim';
    
    console.log(user); // { name: 'Kim' }

 

결론, 정리

  • 재할당이 필요치 않은 원시 값과 객체에는 const 키워드를 사용한다
  • 재할당이 필요한 경우에 한정해 let 키워드를 사용한다. 이때 변수의 스코프는 최대한 좁게 만든다
  • ES6를 사용한다면 var 키워드는 사용하지 않는다.

 

 

참고, 출처:

https://poiemaweb.com/es6-block-scope

https://poiemaweb.com/js-data-type-variable

https://medium.com/korbit-engineering/let%EA%B3%BC-const%EB%8A%94-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85-%EB%90%A0%EA%B9%8C-72fcf2fac365

 

https://www.youtube.com/watch?v=61iolhWgQt0&t=543s 

 

'엘리스 ai 트랙 > FE' 카테고리의 다른 글

구조분해할당  (0) 2022.03.07
IIFE (즉시 호출 함수 표현식)  (0) 2022.02.28
스코프  (0) 2022.02.14
BFC (Block Formatting Context)  (0) 2022.02.05
z-index  (0) 2022.02.02

+ Recent posts