var vs let

v

공통점

박스 선언

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

함수 안에서 밖을 참조

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

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");
}

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

Engine이 context를 만들때 var로 표시된 변수는 undefined 를 넣어놓는반면, let 표시가된 myLet은 uninitialized 라고 표시를 해놓는다. 그래서 error가 난다.

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

재선언

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과 거의 동일하다. 다만, 재할당이 안되는 차이점이 있다.

공통점

박스 선언

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

함수 안에서 밖을 참조

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

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);

Add Comment