7 ES6 for Vue.js - const & let

source: categories/study/vue-beginner-lv2/vue-beginner-lv2_7.md

7.1 const & let 소개

const & let - 새로운 변수 선언 방식

기존 자바스크립트의 애매모호함을 없애기 위한 것.
호이스팅이나 변수 재선언해도 괜찮다던지 이런 것들..

  • 블록 단위 {}로 변수의 범위가 제한되었음.
    ES5에선 function 스코프였다.
    ES5에선 for문의 {}블록으로 변수 범위가 제한되지 않았다.
  • const: 한번 선언한 값에 대해서 변경할 수 없음 (상수 개념)
  • let: 한번 선언한 값에 대해서 다시 선언할 수 없음
    한번 메모리에 해당 변수가 할당되고나면 그 변수를 다시 메모리에 할당할 수 없다. 이건 const도 마찬가지.

위 특징들에 대해서 자세히 알아보기 전에 ES5 특징 2가지를 리뷰

7.2 [ES5의 주요 특징] 변수 스코프와 호이스팅

ES5의 특징 - 변수의 Scope

  • 기존 자바스크립트(ES5)는 {}에 상관없이 스코프가 설정됨
var sum = 0;
for (var i = 1; i <= 5; i++) {
    sum = sum + i;
}
console.log(sum); // 15
console.log(i); // 6

ES5 특징 - Hoisting

  • Hoisting이란 선언한 함수와 변수를 해석기가 가장 상단에 있는 것처럼 인식한다.
  • js 해석기는 코드의 라인 순서와 관계 없이 함수 선언식과 변수를 위한 메모리 공간을 먼저 확보한다.
  • 따라서, function a() {}var는 코드의 최상단으로 끌어올려진 것(hoisted)처럼 보인다.
function willBeOveridden () {
    return 10;
}
willBeOveridden(); // 5
function willBeOveridden () {
    return 5;
}
console.log(b);
// Uncaught ReferenceError: b is not defined
console.log(a); // undefined
var a = 20;
sum(); // 30
function sum () {
    // 함수 선언문 function statement
    return 10 + 20;
}
sum(); // Uncaught TypeError: sum is not a function
var sum = function () {
    // 함수 표현식 function expression
    return 10 + 20;
}

아래와 같은 코드를 실행할 때 자바스크립트 해석기가 어떻게 코드 순서를 재조정할까요?

var sum = 5;
sum = sum + i;

function sumAllNumbers () {
    // ...
}

var i = 10;

// 내 기억으론 아래와 같은 순서로 실행됨
// 1. sum이란 변수를 메모리할당 (값은 미할당)
// 2. sumAllNumbers 함수를 메모리에 할당, 함수 내용도 할당
// 3. i란 변수를 메모리에 할당 (값은 미할당)
// 4. sum이란 변수에 값 5를 할당
// 5. sum = sum + i; 코드 실행 -> i에 값이 미할당된 상태 undefined 상태임. sum의 값은 5. 5 + undefined이므로 sum은 NaN이됨
// 6. i에 값 10 할당

// 즉, 변수와 함수에 대한 메모리할당이 먼저 일어남 - 그런데 함수 선언문은 함수 내용도 같이 먼저 할당됨.
// 변수는 변수 자체만 메모리할당 - 값은 나중에 각 코드 위에서 아래로 한줄한줄 실행하면서 할당.
// #1 - 함수 선언식과 변수 선언을 hoisting
var sum;
function sumAllNumbers () {
    // ...
}
var i;

// #2 - 변수 대입 및 할당
sum = 5;
sum = sum + i;
i = 10;

7.3 const와 let 추가 설명 및 정리

ES6 - {} 단위로 변수의 범위가 제한됨

let sum = 0;
for (let i = 1; i <= 5; i++) {
    sum = sum + i;
}
console.log(sum); // 10
console.log(i); // Uncaught ReferenceError: i is not defined

ES6 - const로 지정한 값 변경 불가능

const a = 10;
a = 20; // Uncaught TypeError: Assignment to constant variable.

하지만, 객체나 배열의 내부는 변경할 수 있다.

const a = {};
a.num = 10;
console.log(a); // {num: 10}
const a = [];
a.push(20);
console.log(a); // [20]

ES6 - let 선언한 값에 대해서 다시 선언 불가능

let a = 10;
let a = 20; // Uncaught SyntaxError: Identifier 'a' has already been declared

ES6 - const, let

function f() {
    {
        let x;
        {
            // 새로운 블록 안에 새로운 x의 스코프가 생김
            const x = 'sneaky';
            x = 'foo'; // 위에 이미 const로 x를 선언했으므로 다시 값을 대입하면 에러 발생
        }
        // 이전 블록 범위로 돌아왔기 때문에 `let x`에 해당하는 메모리에 값을 대입
        x = 'bar';
        let x = 'inner'; // Uncaught SyntaxError: Identifier 'x' has already been declared
    }
}
  • 그런데 궁금한게 위와 같이 함수 선언문을 작성한 것만으로 let x = 'inner'에 대한 에러가 뜬다.
  • 그럼 {const x = 'sneaky'; x = 'foo';에 대한 에러는 왜 안뜨지..? {} 블록 안에 있는건 실행이 안되나 처음에..? f()로 실행해야 이 부분이 에러로잡히네..
function f() {
    const x = 'sneaky';
    x = 'foo'; // 위에 이미 const로 x를 선언했으므로 다시 값을 대입하면 에러 발생
}
// 이렇게만 쓰면 에러 안뜸
// f(); 실행해야 에러뜸
function f() {
    let x = 'sneaky';
    let x = 'foo'; // 위에 이미 const로 x를 선언했으므로 다시 값을 대입하면 에러 발생
}
// Uncaught SyntaxError: Identifier 'x' has already been declared
// f(); 실행 안하고 위와 같이 선언문만 적어줬는데 에러뜸.

// 아 let 변수가 const 변수랑 메모리 할당되는 순서, 시점이 달랐나.... 이건 잘 기억이안나네. 다시 자바스크립트 공부해야겠다..

7.4 [리팩토링] const와 let

varconst로!
변수값이 재할당되지 않는 경우라면 const!
변수값이 재할당되면 let!