(JS) 변수 선언방식(var/ let / const)

호두파파·2020년 11월 20일
1

JavaScript

목록 보기
2/25


변수(variable) 선언

요약

자바스크립트에 let, const라는 새로운 타입의 두 가지 변수 선언이 추가되었다. 일부는 var와 유사하지만, letconst선언방식은 자바스크립트에서 발생하는 특성(호이스팅)으로 인해 발생하는 오류 중 일부를 방지할 수 있다.

개념을 이해하기 위해서는 스코프와 호이스팅을 이해해야 한다.

링크

1. var

var 키워드로 변수를 선언하면, 선언과 동시에 값을 할당할 수 있습니다. 지정된 초기값없이 선언된 변수는 undefined 값을 갖는다.

var a = 10;
function f() {
  var message = "hello, world";
  return message;
}

2.변수 선언 생략

선언되지 않은 변수를 읽으려면 참조 오류가 발생한다.
변수를 선언하지 않고 사용하는 행위는 버그의 원인이 될 수 있다. 때문에 반드시 선언하고 사용하는 것이 좋다.

📌 선언되지 않는 변수에 값을 대입하면?

var 문으로 선언되지 않는 변수에 대입하면 오류가 발생하지 않는다.
이유는 자바스크립트가 해당 변수를 자동으로 전역 변수로 선언 하기 때문인데,
이는 함수의 유효 범위와 관련이 있다.

// 선언되지 않은 변수를 읽으려고 할 때
console.log(x); // ➡ ReferenceError: x is not defined(오류 메세지)

// var 문으로 선언되지 않은 변수에 값을 대입할 때
y = 2;
console.log(y); // ➡ 2

🖍 var 변수 선언 방식의 단점

    var name = 'bathingape'
    console.log(name) // bathingape

    var name = 'javascript'
    console.log(name) // javascript

변수를 한번 더 선언했음에도 불구하고, 에러가 발생하지 않고 각기 다른 값이 출력되는 것을 볼 수 있다.

이는 자바스크립트 엔진의 유연한 변수 선언방식 때문으로 간단한 테스트에는 편리할 수 있으나, 코드량이 많아진다면 디버깅을 수행하기 어려워질 수 있다.

그래서 ES6 이후, 이를 보완하기 위해 추가된 변수 선언 방식이
letconst이다.

🐶 이제 var를 잊도록 하자.

let

    let name = 'bathingape'
    console.log(name) // bathingape

    let name = 'javascript'
    console.log(name) 
    // Uncaught SyntaxError: Identifier 'name' has already been declared

변수name이 이미 선언되엇따는 에러 메시지가 발생한다. 재선언이 되지 않았다.
하지만 let 선언방식은 선언한 변수에 재할당이 가능하다.

    let name = 'bathingape'
    console.log(name) // bathingape

    let name = 'javascript'
    console.log(name) 
    // Uncaught SyntaxError: Identifier 'name' has already been declared

    name = 'react'
    console.log(name) //react

이 점이 const 선언방식과 큰 차이를 가지는데
const 선언방식은 변수 재선언, 변수 재할당이 모두 불가능하다.

📌 호이스팅을 조심하자!

호이스팅(Hoisting)이란, 선언된 변수나 함수를 가장 최상단으로 끌어올리는 자바스크립트 엔진의 특성인다.

자바스크립트는 ES6에서 도입된 let, const를 포함하여 모든 선언(var, let, const, function, function*, class)을 호이스팅한다.

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

console.log(bar); // Error: Uncaught ReferenceError: bar is not defined
let bar;

let으로 선언된 변수는 스코프의 시작에서 변수의 선언까지 일시적인 사각지대(TDZ:Temporal Dead Zone)에 져서 참조오류가 발생했다.

변수는 선언 단계 > 초기화 단계 > 할당 단계 에 걸쳐 생성되는데

var으로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이뤄지는 반면, let으로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.

// 스코프의 선두에서 선언 단계와 초기화 단계가 실행된다.
// 따라서 변수 선언문 이전에 변수를 참조할 수 있다.

console.log(foo); // undefined

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

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

let 로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.

// 스코프의 선두에서 선언 단계가 실행된다.
// 아직 변수가 초기화(메모리 공간 확보와 undefined로 초기화)되지 않았다.
// 따라서 변수 선언문 이전에 변수를 참조할 수 없다.

console.log(foo); // ReferenceError: foo is not defined

let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

const

const는 변수 재선언, 변수 재할당 모두 불가능하다. 하지만, 변수를 재할당하지 않는 이상 const를 사용하는 것이 코드의 총체적이 관리면에서 유리하다.

const name = 'bathingape'
console.log(name) // bathingape

const name = 'javascript'
console.log(name) 
// Uncaught SyntaxError: Identifier 'name' has already been declared

name = 'react'
console.log(name) 
//Uncaught TypeError: Assignment to constant variable.

const로 변수를 선언하는 것을 우선으로 하고, 재할당이 필요한 경우 let으로 변수를 선언하는 습관을 들이자

객체를 재할당하는 경우는 생각보다 흔하지 않고,const를 사용하면 의도치 않은 재할당을 방지해 주기 때문에 보다 안전하다.

  • 재할당이 필요한 경우에 한정해 let을 사용한다. 이때, 변수의 스코프는 최대한 좁게 만든다.
  • 재할당이 필요 없는 상수와 객체에는 const을 사용한다.

참조

변수의 유효범위

먼저 var는 기본적으로 function scope를 가지게되고
let, const는 block scope를 가지게된다.

var

var foo = "This is String.";
if(typeof foo === 'string'){
	var result = true;
} else {
  var result = false;
}

console.log(result);    // result : true

let & const

var foo = "This is String.";
if(typeof foo === 'string'){
	const result = true;
} else {
  const result = false;
}

console.log(result);    // result : result is not defined

profile
안녕하세요 주니어 프론트엔드 개발자 양윤성입니다.

0개의 댓글