javascript var vs let

공통점

박스 선언

둘다 어떤 값을 넣기 위한 박스를 만드는데 사용된다.

함수 안에서 밖을 참조

함수 밖에있는 값들을 함수 안에서 참조할 수 있다.

var outVar = 100;
function test1() {
  console.log(outVar);
}
test1(); // 100


let outLet = 200;
function test2() {
  console.log(outLet);
}
test2(); // 200

함수 안에 함수가 있어도 마찬가지이다.

function outside() {
  var myVar = 100;
  let myLet = 200;
  function inside() {
    console.log(myVar); // 100
    console.log(myLet); // 200
  }
  inside();
}
outside();

if문(block) 안에서도 참조 가능하다.

var myVar = 100;
if (true) {
  console.log(myVar); // 100
}

let myLet = 200;
if (true) {
  console.log(myLet); // 200
}

함수 밖에서 안을 참조

함수 밖에서 안에있는 변수를 참조할 수 없다.

function test1() {
  var inVar = 100;
}
test1();
console.log(inVar); // error

function test2() {
  let inLet = 200;
}
test2();
console.log(inLet); // error

차이점

Scope

기본적으로 함수안에 박스(= var, let)를 선언하면, 해당 박스는 그 함수 안에서만 사용되지만, Block({ ~~ } )은 다르다.

if (true) {
  var myVar = 100;
}
console.log(myVar); // 100

if (true) {
  let myLet = 200;
}
console.log(myLet); // error

var는 Block안에다 써도 Context에 등록되기 때문에 어디서든지 참조할 수 있고, let은 Context에 등록 안되기 때문에 Block밖에서는 쓸 수 없다.

for(var i = 0; i < 10; i++) {
  /* do something */
}
console.log(i); // 10

for(let z = 0; z < 10; z++) {
  /* do something */
}
console.log(z); // error : z is not defined

같은 논리로 i는 10이지만 z는 에러가 뜬다. i는 Context라는 다른 Object에 할당되서 그 값을 계속 1씩 증가시키는것이기 때문에 참조가 가능한것이다.

그러면 Context.i 이렇게 써야하는거 아니냐는 생각이 들 수 있겠지만, Javascript Engine에는 Scope Chain이라는 기법(?)이 있기 때문에 알아서 Context안에서 i값을 찾는다.

Hoisting

Javascript Engine은 내 코드를 실행하기 전에 첫번째줄부터 삭~ 훑어보면서 Context안에 변수와 함수를 넣어놓는다. 그래서 아래의 코드는 에러없이 작동한다.

console.log(myVar); // undefined
var myVar = 100;

물론 실행한게 아니라, 한번 슥 훑어본것이기 때문에 대입연산자(=)가 작동하지는 않아서 undefined가 뜨기는 했지만 이것은 오류가 난건 아니다.

myFunc(); // Hello World
function myFunc() {
  console.log("Hello World");
}

같은 논리로 위의 코드도 잘 작동한다.

let도 hoisting이 된다고 하는데, 나는 잘 이해는 안간다. 다만, 아래의 예제를 보면 let으로 선언한 변수는 마치 hoisting이 안된것처럼 에러를 낸다.

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

그냥 hoisting이 안된다고 생각하는게 마음이 편할것 같다…

재선언

var myVar = 100;
var myVar = 200;
console.log(myVar); // 200

// SyntaxError: Identifier 'myLet' has already been declared
let myLet = 100;
let myLet = 200;
console.log(myLet);

var는 재선언이 가능하나, let은 재선언이 안된다. 재선언이 허용되는 문제는 프로그램에 심각한 버그를 야기할 수 있기 때문에, var대신 let을 쓰는게 좋다고 한다.

Const

const는 let과 거의 동일하다. 다만, 재할당이 안되는 차이점이 있다.

let myLet = 100;
myLet = 200;
console.log(myLet); // 200

const myConst = 100;
myConst = 200; // TypeError: Assignment to constant variable.
console.log(myConst);

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

Up Next:

Typescript 기초(1) - Basic Types

Typescript 기초(1) - Basic Types