const

const

const 선언은 블록 스코프(block-scoped) 지역 변수를 선언합니다. 상수의 값은 할당 연산자를 사용한 재할당으로는 변경할 수 없지만, 상수가 객체라면 그 속성은 추가, 갱신, 제거될 수 있습니다. Baseline Widely available — 2015년 7월부터 여러 브라우저에서 지원되는 잘 정착된 기능입니다.

출처: const

본문

const 선언은 블록 스코프 지역 변수를 선언합니다. 상수의 값은 할당 연산자를 통한 재할당으로는 변경할 수 없지만, 상수가 객체라면 그 속성은 추가되거나 갱신되거나 제거될 수 있습니다.

시도해 보기 (Try it)

const number = 42;

try {
  number = 99;
} catch (err) {
  console.log(err);
  // Expected output: TypeError: invalid assignment to const 'number'
  // (Note: the exact output may be browser-dependent)
}

console.log(number);
// Expected output: 42

구문 (Syntax)

const name1 = value1;
const name1 = value1, name2 = value2;
const name1 = value1, name2 = value2, /* …, */ nameN = valueN;
  • nameN: 선언할 변수의 이름입니다. 각각은 유효한 JavaScript 식별자이거나 구조 분해 바인딩 패턴이어야 합니다.
  • valueN: 변수의 초기 값입니다. 유효한 표현식이면 무엇이든 될 수 있습니다.

설명 (Description)

const 선언은 let과 매우 비슷합니다:

  • const 선언은 함수뿐만 아니라 블록으로도 스코프됩니다.
  • const 선언은 선언 위치에 도달한 후에만 접근할 수 있습니다(시간적 사각지대 참고). 이런 이유로 const 선언은 흔히 호이스팅되지 않는 것으로 간주됩니다.
  • const 선언은 스크립트의 최상위 수준에서 선언될 때 globalThis에 속성을 만들지 않습니다.
  • const 선언은 같은 스코프의 다른 어떤 선언으로도 재선언될 수 없습니다.
  • const는 문(statement)이 아니라 선언(declaration)을 시작합니다. 즉, 단독 const 선언을 블록의 본문으로 사용할 수 없습니다(변수에 접근할 방법이 없으므로 말이 됩니다). if (true) const a = 1; // SyntaxError: Lexical declaration cannot appear in a single-statement context

상수에는 이니셜라이저가 필요합니다. 같은 선언에서 그 값을 지정해야 합니다. (나중에 변경할 수 없으므로 말이 됩니다.)

const FOO; // SyntaxError: Missing initializer in const declaration

const 선언은 값에 대한 변경 불가능한(immutable) 참조를 만듭니다. 이는 그것이 담고 있는 값이 변경 불가능하다는 뜻이 아니라, 변수 식별자를 재할당할 수 없다는 뜻입니다. 예를 들어 내용이 객체인 경우, 이는 객체의 내용(예: 속성)은 변경될 수 있음을 의미합니다. const 선언은 "값이 일정하게 유지되는 변수"가 아니라 "정체성(identity)이 일정하게 유지되는 변수를 만들라" — 또는 "변경 불가능한 값"이 아니라 "변경 불가능한 바인딩(binding)을 만들라"로 이해해야 합니다.

많은 스타일 가이드(MDN의 것 포함)는 변수가 스코프 안에서 재할당되지 않을 때마다 let보다 const를 사용할 것을 권장합니다. 이렇게 하면 변수의 타입(또는 원시 값의 경우 값)이 절대 바뀌지 않는다는 의도가 명확해집니다. 다른 사람들은 변경된(mutated) 비원시 값에 대해 let을 선호할 수도 있습니다.

const 키워드 뒤의 목록은 바인딩 목록이라고 불리며 쉼표로 구분됩니다. 여기서 쉼표는 쉼표 연산자가 아니고 =는 할당 연산자가 아닙니다. 목록의 뒷부분 변수의 이니셜라이저는 목록의 앞부분 변수를 참조할 수 있습니다.

예제 (Examples)

기본 const 사용법

상수는 대문자나 소문자로 선언될 수 있지만, 일반적인 관례는 특히 진정으로 변경 불가능한 원시 값의 경우 전체 대문자를 사용하는 것입니다.

// define MY_FAV as a constant and give it the value 7
const MY_FAV = 7;

console.log(`my favorite number is: ${MY_FAV}`);
// Re-assigning to a constant variable throws an error
MY_FAV = 20; // TypeError: Assignment to constant variable

// Redeclaring a constant throws an error
const MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
var MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
let MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared

블록 스코핑 (Block scoping)

블록 스코핑의 특성을 주목하는 것이 중요합니다.

const MY_FAV = 7;

if (MY_FAV === 7) {
  // This is fine because it's in a new block scope
  const MY_FAV = 20;
  console.log(MY_FAV); // 20

  // var declarations are not scoped to blocks so this throws an error
  var MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
}

console.log(MY_FAV); // 7

객체와 배열에서의 const

const는 객체와 배열에서도 동작합니다. 객체를 덮어쓰려 하면 "Assignment to constant variable" 오류가 발생합니다.

const MY_OBJECT = { key: "value" };
MY_OBJECT = { OTHER_KEY: "value" };

그러나 객체의 키는 보호되지 않으므로 다음 문장은 문제없이 실행됩니다.

MY_OBJECT.key = "otherValue";

객체를 변경 불가능하게 만들려면 Object.freeze()를 사용해야 합니다.

배열에도 동일하게 적용됩니다. 변수에 새 배열을 할당하면 "Assignment to constant variable" 오류가 발생합니다.

const MY_ARRAY = [];
MY_ARRAY = ["B"];

그래도 배열에 항목을 push해 변경(mutate)하는 것은 가능합니다.

MY_ARRAY.push("A"); // ["A"]

구조 분해를 사용한 선언

=의 왼쪽도 바인딩 패턴일 수 있습니다. 이를 통해 한 번에 여러 변수를 만들 수 있습니다.

const result = /(a+)(b+)(c+)/.exec("aaabcc");
const [, a, b, c] = result;
console.log(a, b, c); // "aaa" "b" "cc"

자세한 내용은 구조 분해(Destructuring) 문서를 참고하세요.

명세 (Specifications)

const 문은 ECMAScript 언어 명세에 정의되어 있습니다.

브라우저 호환성 (Browser compatibility)

이 기능은 대부분의 현대 브라우저에서 널리 지원됩니다(Baseline Widely available). 자세한 호환성 표는 MDN의 브라우저 호환성 섹션을 참고하세요.

더 알아보기

  • var
  • let
  • JavaScript 안내서의 상수 (Constants in the JavaScript Guide)
  • 호이스팅 (Hoisting)