JavaScript의 Const : 언제 사용해야합니까?


349

최근 const에 JavaScript 에서 키워드를 발견했습니다. 내가 알 수있는 것에서 불변 변수 를 만드는 데 사용 되며 Node.js에서 변수를 다시 정의 할 수 없는지 테스트했습니다.

const x = 'const';
const x = 'not-const';

// Will give an error: 'constant 'x' has already been defined'

모든 브라우저에서 표준화되지는 않았지만 Node.js V8 의 컨텍스트에만 관심이 있으며 특정 개발자 / 프로젝트var키워드를 사용할 수있을 때 크게 선호하는 것으로 나타났습니다 . 같은 효과.

그래서 내 질문은 :

  • const대신에 var언제 사용해야 합니까?
  • 재할 당하지 않을 변수가 선언 될 때마다 사용해야합니까?
  • var대신 const또는 그 반대로 사용되는 경우 실제로 차이 가 있습니까?

1
그것은 아직 표준화되지 않은 것 같습니다 (아마도 EC6?). 여기에 대한 추가 정보는 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sebastien C.

답변:


462

귀하의 질문에는 두 가지 측면이 있습니다. const대신에 기술적 인 측면이 var무엇인지 , 그리고 인간과 관련된 측면은 무엇입니까?

기술적 인 차이가 중요합니다. 컴파일 된 언어에서, 상수는 컴파일 타임에 대체 될 것이며 데드 코드 제거와 같은 다른 최적화를 통해 코드의 런타임 효율성을 더욱 높일 수 있습니다. 최근에 많이 사용 된 용어 인 JavaScript 엔진은 실제로 더 나은 성능을 얻기 위해 JS 코드를 컴파일하므로 const 키워드를 사용하면 위에서 설명한 최적화가 가능하고 수행되어야 함을 알 수 있습니다. 결과적으로 성능이 향상됩니다.

인간과 관련된 측면은 키워드의 의미에 관한 것입니다. 변수는 변경 될 것으로 예상되는 정보가 포함 된 데이터 구조입니다. 상수는 절대 변하지 않는 정보를 포함하는 데이터 구조입니다. 오류의 여지가있는 경우 var항상 사용해야합니다. 그러나 프로그램 수명 기간 동안 절대 변하지 않는 모든 정보를로 선언 할 필요는 없습니다 const. 다른 상황에서 정보가 변경되어야 var하는 경우 실제 변경 사항이 코드에 나타나지 않더라도이를 나타 내기 위해 사용 하십시오.


4
건배, 나는 Mozilla / Google이 아무런 이유없이 JS 엔진에 const 지원을 추가하지 않았다고 가정했습니다. 해당되는 곳에 const를 사용하도록하겠습니다.
axdg

6
const객체는 변경 가능한 것으로 보이므로 JS 컴파일러가 실제로 얼마나 엄격한 지 잘 모르겠습니다. "엄격한 사용"모드에서도 차이가있을 수 있습니다.
Rudie

9
당신이라고 찾고있는 기능 @Rudie 동결 개체를. const"변수"를 다른 값으로 재할 당하지 않습니다. const a = {}; a = {};엄격 모드에서는 오류가 발생합니다.
Tibos

Java에서 대부분의 변수 선언에 final을 추가하는 것처럼 대부분의 변수에 let 대신 일반적으로 const를 사용합니다.
코딩

2
If there is room for error, var should always be used. ESLint와 같은 도구가 즉시 const위반을 가리키는 경우에는 더 이상 적용되지 않습니다 .
vitaly-t 2016

72

2017 년 업데이트

이 답변은 여전히 ​​많은 관심을 받고 있습니다. 이 답변은 2014 년 초에 게시되었으며 그 이후로 많은 변화가 있었다는 점에 주목할 가치가 있습니다.지원은 이제 표준입니다. 모든 최신 브라우저는 이제 지원 const하므로 문제없이 사용하는 것이 안전합니다.


2014 년 원문

상당히 괜찮은 브라우저 지원 에도 불구하고 지금은 사용하지 않는 것이 좋습니다. 에서 의 MDN의 기사const :

const의 현재 구현은 Mozilla 전용 확장이며 ECMAScript 5의 일부가 아닙니다. Firefox & Chrome (V8)에서 지원됩니다. Safari 5.1.7 및 Opera 12.00부터 이러한 브라우저에서 const를 사용하여 변수를 정의하면 나중에 해당 값을 변경할 수 있습니다. Internet Explorer 6-10에서는 지원되지 않지만 Internet Explorer 11에는 포함되어 있습니다. const 키워드는 현재 var로 선언 된 변수와 같이 함수 범위에서 상수를 선언합니다.

그런 다음 계속 말합니다.

constECMAScript 6에 의해 정의되지만 의미가 다릅니다. let 문으로 선언 된 변수와 유사하게 const로 선언 된 상수는 블록 범위가됩니다.

사용하는 경우 const약간 오래된 브라우저를 지원하려면 해결 방법을 추가해야합니다.


6
좋은 대답-이미 MDN에 대한 기사를 읽었지만. 내가 말했듯이, V8 이 실제로 const를 var와 다르게 취급 할 것인지에 더 관심 이있었습니다. @Tibos가 그것을 정리했다고 생각합니다.
axdg

James는 지원 측면을 지적 해 주셔서 감사합니다. 모든 자바 스크립트 답변에는 브라우저 지원 분석이 포함되어야합니다. 잘 설명
hubson bropa

4
참고 ES6은 2014 년 8 월에 기능이 정지되었습니다. 2015 년 7 월 표준이 공식적으로 릴리스되었습니다. 지금 읽고 있다면 최신 엔진으로 코드를 관리하는 경우 설명 된대로 수락 된 답변을 따라야한다는 의미입니다.
Filip Dupanović

OP 질문은 node.js에 따라 다릅니다.
Nicu Surdu

@NicolaeSurdu 확실합니다. 또한 2014 년 1 월부터 시작되었으므로 아마도 2017 년에 현재 대부분 중복 될 것입니다.
James Donnelly

41

const@Tibos의 답변 을 사용하는 이유는 훌륭합니다.

그러나 당신은 말했다 :

내가 알 수있는 것에서 불변의 변수를 만드는 데 사용됩니다.

잘못된 . 변수를 변경하는 것은 재 할당과 다릅니다.

var hello = 'world' // assigning
hello = 'bonjour!' // reassigning

const를 사용하면 그렇게 할 수 없습니다.

const hello = 'world'
hello = 'bonjour!' // error

그러나 변수를 변경할 수 있습니다.

const marks = [92, 83]
marks.push(95)
console.log(marks) // [92, 83, 95] -> the variable has been mutated.

따라서 부호 사용 하지 않고 변수 값을 변경하는 프로세스는 변수를 변경합니다 =.

참고 : +=예를 들어 ... 재 할당입니다!

var a = 5
a += 2 // is the same as a = a + 2

결론은 다음과 같습니다. 변수 const변경 하지 못하게하고 변수를 다시 할당 하지 못하게 합니다.


4
귀하의 진술 " 기호 사용 하지 않고 변수의 값을 변경하는 프로세스 =가 음소거되었습니다"는 기술적으로 잘못되었습니다. 예를 const marks=[92,83]; marks[2]=95; console.log(marks)들어을 출력 [92, 83, 95]합니다. marks등호를 통해 변경되었습니다.
chharvey

5
"그러나 당신은 말했다 : << 내가 말할 수있는, 그것은 불변 변수를 만드는 데 사용됩니다 >> 잘못되었습니다 . 변수를 변경하는 것은 재 할당과 다릅니다" 아니, 그렇지 않습니다. 재 할당은 변수를 변경합니다. 변수의 참조가 참조하는 객체를 변경하는 것에 대해 이야기하고 있습니다. 그것은 완전히 다른 것입니다.
TJ Crowder

const배열의 맥락에서 이해하려고하기 때문에 여기 에 있습니다 (@chharvey 사용 된 예제와 유사). 의 경우 마다 재 - 할당된다. 왜 사용 하지 않습니까? const countArray = countup(n - 1); countArray.push(n);constconstvar
YCode

1
@Y 코드 번호 당신이 사용하는 경우 const countArray, 그것은 것입니다 결코 재 할당되지 않습니다. 여전히 배열로 푸시하면 멤버와 길이가 변경되지만 해당 할당을 호출하지는 않습니다. 재 할당 const을 피 let하거나 대신 var할 때 사용 합니다 . 당신이 BTW 경우 않는 재 할당 허용 할, let거의 항상 더 나은보다 var.
chharvey

@chharvey 감사합니다! 귀하의 답변으로 저에게 "가치가 지나가는 대 참조가 지나가는", 새로운 개념, 가치 수정이 재 할당되는 이상한 개념이 있습니다. 추가 설명이 필요한 사람은 여기에서 답변을 확인해야합니다. stackoverflow.com/q/46131828/5965865
YCode

38

이전 답변을 통합하기 위해 성능상의 이유와는 별도로 상수 변수를 선언하면 명백한 이점이 있습니다. 실수로 코드에서 변수를 변경하거나 다시 선언하려고하면 프로그램이 각각 값을 변경하거나 오류를 발생시키지 않습니다.

예를 들어, 다음을 비교하십시오.

// Will output 'SECRET'

const x = 'SECRET'
if (x = 'ANOTHER_SECRET') {  // Warning! assigning a value variable in an if condition
    console.log (x)
}

와:

// Will output 'ANOTHER_SECRET'

var y = 'SECRET'
if (y = 'ANOTHER_SECRET') { 
    console.log (y)
}

또는

// Will throw TypeError: const 'x' has already been declared

const x = "SECRET"

/*  complex code */

var x = 0

// Will reassign y and cause trouble

var y = "SECRET"

/*  complex code */

var y = 0

이 "불변"동작은 문자열, 기본 유형에만 적용 할 수 있다고 말해야합니다. Objects, Arrays 등을 사용하면 값을 변경할 수 있지만 새 "Object"를 다시 할당 할 수는 없습니다. 예를 들어 const a = [ "a", "b"]; a = []; 그렇지 않으면 오류가 발생합니다
Fer To

상수 값을 시도하고 변경하는 예제도 있어야합니다.
Joshua Pinter

const를 사용하는 것은 액세스 수정 자와 매우 유사하며 진정한 불변성은 목표가 아닙니다.
StingyJack

32

const입니다 하지 불변.

로부터 MDN :

const 선언은 값에 대한 읽기 전용 참조를 만듭니다. 변수 식별자를 재 할당 할 수 없다는 것만으로 보유한 값이 변경 불가능하다는 의미는 아닙니다.


24
그래도 약간 오해의 소지가 있습니다. 숫자, 문자열, 부울 등 (프리미티브) const은 변경할 수 없습니다. 객체와 배열의 경우에는 다시 할당 할 수 없지만 내용은 변경할 수 있습니다 (예 : array.push).
Florian Wendelborn

2
JS 프리미티브는 항상 불변입니다. 사용 여부에 const영향을 미치지 않습니다.
12Me21

1
@Dodekeract 따라서 정의에 의해 불변하지 않습니다. 값이 변경 될 수있는 경우, 변경할 수없는 것은 아니지만 목록에있는 기본 요소에 대해서는 변경할 수없는 것입니다.
Anthony

13

var : 변수 선언, 값 초기화 옵션.

let : 블록 범위를 가진 지역 변수를 선언합니다.

const : 읽기 전용 명명 된 상수를 선언합니다.

전의:

var a;
a = 1;
a = 2;//re-initialize possible
var a = 3;//re-declare
console.log(a);//3

let b;
b = 5;
b = 6;//re-initiliaze possible
// let b = 7; //re-declare not possible
console.log(b);

// const c;
// c = 9;   //initialization and declaration at same place
const c = 9;
// const c = 9;// re-declare and initialization is not possible
console.log(c);//9
// NOTE: Constants can be declared with uppercase or lowercase, but a common
// convention is to use all-uppercase letters.

10

당신은 큰 대답을 가지고 있지만 간단하게 유지합시다.

const 정의 된 상수가있을 때 사용해야합니다 (읽기 : 프로그램 실행 중에 변경되지 않음).

예를 들면 다음과 같습니다.

const pi = 3.1415926535

나중에 실행할 때 변경 될 수 있다고 생각되면를 사용하십시오 var.

예제를 기반으로 한 실제 차이점 const은 항상 파이가 3.14 [...]라고 가정한다는 것입니다. 사실입니다.

로 정의하면 var3.14 [...]가 될 수 있습니다.

더 기술적 인 답변을 원하시면 @Tibos가 학문적으로 옳습니다.


7

내 경험상 나는 const 파일을 사용하여 하드 코딩 된 비트를 찾는 코드를 찾지 않고 파일 경로 또는 서버 이름과 같이 나중에 변경하고 싶을 수도 있습니다.

테스트의 오류는 또 다른 것입니다 .x라는 다른 변수를 만들려고하면 더 정확한 테스트입니다.

const x = 'const';
x = 'not-const';

9
나는 당신이 의미하는 바를 얻습니다.하지만 당신을위한 "일정한"은 "내가 바꾸고 싶은 것"을 의미한다는 것이 재미 있습니다. : P
Venryx

4

개인적 취향은 정말입니다. 당신이 말한 것처럼 const가 다시 할당되지 않고 상수 일 때 const를 사용할 수 있습니다. 예를 들어 생일을 할당하려는 경우. 생일은 변하지 않으므로 상수로 사용할 수 있습니다. 그러나 나이가 변해서 변수가 될 수 있습니다.


17
그것은 매우 오래 걸리는 스크립트 일 것입니다!
nullability

3
@nullability 추적하는 사람의 연령에 따라 다릅니다. 수십 개 이상이며 스크립트를 오래 실행할 필요가 없습니다. :).
Millie Smith

4

요약:

const는 불변 바인딩을 생성합니다. const 변수 식별자는 재 할당 할 수 없습니다.

const a = "value1";

다시 할당 할 수 없습니다

a = "value2";

그러나 const 식별자가 객체 또는 배열을 보유하면 객체를 다시 할당하지 않는 한 그 값을 변경할 수 있습니다.

const x = { a: 1 }

x.a = 2; //is possible and allowed

const numbers = [1, 2];
numbers.push(3); //is possible and allowed

제발 참고 CONST가 있는 블록 범위 처럼 하자 로 동일하지 않은 VAR (함수 범위 인)

간단히 말해, 재 할당을 통해 변경 될 가능성이없는 경우 const 범위를 사용하고 싶은 범위에 따라 let 또는 var를 사용 하십시오 .

재 할당을 통해 변경 될 수있는 것과 변경 될 수없는 것이 분명한 경우 코드에 대해 추론하기가 훨씬 쉽습니다. const를 let으로 바꾸는 것은 간단합니다. 그리고 const를 기본으로 설정하면 그렇게하기 전에 두 번 생각하게됩니다. 그리고 이것은 많은 경우에 좋은 것입니다.



2
Main point is that how to decide which one identifier should be used during development.
In java-script here are three identifiers.

1. var (Can re-declared & re-initialize)
2. const (Can't re-declared & re-initialize, can update array values by using push)
3. let (Can re-initialize but can't re-declare)

'var': 코드 표준에 대해 이야기 할 때 코딩 할 때 일반적으로 다른 사용자 / 개발자가 이해하기 쉬운 식별자 이름을 사용합니다. 예를 들어 입력을 사용하고 처리하고 다음과 같은 결과를 반환하는 많은 함수를 생각하고 있다면

**Example of variable use**

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2;
 return result;
}

위의 예에서 두 함수는 서로 다른 2 개의 결과를 생성하지만 동일한 이름의 변수를 사용합니다. 여기서 우리는 'process'와 'result'둘 다 변수로 사용되며 반드시 있어야 함을 알 수 있습니다.

 **Example of constant with variable**

 const tax = 10; 
 const pi = 3.1415926535; 

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

자바 스크립트에서 'let'을 사용하기 전에 js 파일 상단에 'use strict'를 추가해야합니다

 **Example of let with constant & variable**

 const tax = 10; 
 const pi = 3.1415926535; 
 let trackExecution = '';

function firstFunction(input1,input2)
{
 trackExecution += 'On firstFunction'; 
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 trackExecution += 'On otherFunction'; # can add current time 
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

 firstFunction();
 otherFunction();
 console.log(trackExecution);

위의 예에서 특정 작업 중에 사용되지 않은 기능과 사용하지 않은 기능을 추적 할 수 있습니다.


1

첫째, 약 3 유용한 것들 const(이 함께 공유 범위를 개선 이외의 let) :

  • 나중에 코드를 읽는 사람들이 값을 변경해서는 안된다고 문서화합니다.
  • 다시 돌아가서 의도적으로 선언을 변경하지 않는 한 값을 변경하지 못하게합니다.
  • 그것은 수있는 최적화의 관점에서 자바 스크립트 엔진에게 약간의 분석을 저장합니다. 예를 들어, 값을 변경할 수 없다고 선언 했으므로 엔진은 값이 변경되는지 여부를 파악하기 위해 작업 할 필요가 없으므로 변경되지 않는 값을 기반으로 최적화할지 여부를 결정할 수 있습니다.

당신의 질문:

const대신에 var언제 사용해야 합니까?

값이 변하지 않는 변수를 선언 할 때 언제든지 있습니다 . 적절하다고 생각하는지 여부는 전적으로 귀하의 선호 / 팀의 선호에 달려 있습니다.

재할 당하지 않을 변수가 선언 될 때마다 사용해야합니까?

그것은 당신 / 당신의 팀에 달려 있습니다.

var is used in place ofconst 또는 그 반대의 경우 실제로 차이가 있습니까?

예:

  • var그리고 const다른 범위 규칙이있다. (당신은 비교 싶었을 수도 있습니다 let보다는 var: 특히.) constlet전역 범위에서 사용될 때 전역 객체 (그들이 전역을 생성 할지라도)에 대한 속성을 생성하지 않는, 블록 범위이고. var전역 범위 (전역 범위에서 사용되는 경우) 또는 함수 범위 (블록에서 사용되는 경우에도)가 있고 전역 범위에서 사용되는 경우 전역 개체에 속성을 만듭니다.
  • 위의 "세 가지 유용한 사항"을 참조하십시오. 모두이 질문에 적용됩니다.

1

의 의미 varlet

var그리고 let기계와 다른 프로그래머에게 진술합니다.

나는이 과제의 가치가 실행 과정에 따라 변하기를 원합니다. 이 과제의 최종 가치에 의존하지 마십시오.

var및 사용의 의미let

varlet프로그램의 실행에 그 시점에서 할당의 가치에 대한 최종 사용에 선언하고, 이유에서 모든 중간에 코드를 읽는 다른 프로그래머를 강제로.

ESLint 및 기타 언어 서비스가 나중에 할당 할 때 잘못 입력 된 변수 이름을 올바르게 감지하고 내부 범위가 선언하지 못한 외부 범위 변수 이름의 범위 재사용을위한 기계 추론을 약화시킵니다.

또한 런타임이 모든 코드 경로에 대해 많은 반복을 실행하여 실제로 상수이기 때문에이를 최적화하기 전에 감지합니다. 이것은 버그 감지 및 개발자의 이해력보다 문제가 적습니다.

사용시기 const

참조 값이 실행 과정에서 변경되지 않으면 프로그래머의 의도를 표현하는 올바른 구문은 const입니다. 객체의 경우 참조 값을 변경하면 참조는 변경할 수 없지만 객체는 변경할 수 없으므로 다른 객체를 가리키는 것을 의미합니다.

" const"개체

객체 참조의 경우 포인터를 다른 객체로 변경할 수 없지만 const선언에 만들어지고 선언 된 객체 변경할 수 있습니다. const참조 된 배열 에서 항목을 추가 또는 제거 하고 const참조 된 객체의 속성 키를 변경할 수 있습니다 .

불변의 객체를 달성하기 위해 (사람과 기계에 대해 코드를 쉽게 추론 할 수 Object.freeze있도록) 선언 / 할당 / 창조에서 객체를 다음과 같이 할 수 있습니다.

const Options = Object.freeze(['YES', 'NO'])

Object.freeze는 성능에 영향을 주지만 다른 이유로 인해 코드가 느려질 수 있습니다. 프로파일 링하고 싶습니다.

상태 머신에서 변경 가능한 객체를 캡슐화하고 딥 카피를 값으로 반환 할 수도 있습니다 (이것이 Redux 및 React 상태 작동 방식). 첫 번째 원칙에서이를 빌드하는 방법에 대한 예제는 브라우저 JS에서 변경 가능한 글로벌 상태 방지를 참조하십시오 .

언제 var그리고 let잘 어울리는가

letvar변경 가능한 상태를 나타냅니다. 내 의견으로는 실제 변경 가능한 상태 를 모델링하는 데만 사용해야합니다 . " 연결이 살아 있습니까? "

이들은 " 연결의 현재 상태 "를 나타내는 상수 값을 노출하는 테스트 가능한 상태 머신에 가장 잘 캡슐화되어 있으며 , 이는 어느 시점에서나 일정하며, 코드의 나머지 부분에 실제로 관심이있는 항목입니다.

부작용을 작성하고 데이터를 변환하는 데 프로그래밍이 이미 충분히 어렵습니다. 변수를 사용하여 변경 가능한 상태를 생성하여 모든 기능을 테스트 할 수없는 상태 머신으로 전환하는 것은 복잡성에 있습니다.

더 미묘한 설명은 Shun the Mutant-The case for를const 참조하십시오 .



0

나는 JS 컴파일 비즈니스의 전문가는 아니지만 v8은 const 플래그를 사용한다고 말하는 것이 합리적입니다.

일반적으로 많은 변수를 선언하고 변경 한 후 메모리가 조각화되고 v8이 실행을 중지하고 몇 초 동안 일시 중지하여 gc 또는 가비지 수집을 수행합니다.

const v8로 변수를 선언하면 다른 const 변수 사이의 단단한 고정 크기 컨테이너에 변수를 넣을 수 있습니다. 유형이 변경되지 않으므로 해당 데이터 유형에 대한 올바른 작업을 저장할 수도 있습니다.


0

letconst 사이의 결정에 관해서는 항상 코드에서 사용법이 명확하도록 const를 선호 하십시오. 이렇게하면 변수를 다시 선언하려고하면 오류가 발생합니다. 다른 선택이 없으면 다시 선언하면 let으로 전환 하십시오 . 로, 그 주 앤서니는 말한다, 값이 (인스턴스를 들어, 불변하지 CONST의 개체가 속성이 변이 할 수 있습니다).

var에 관해서는 ES6이 없기 때문에 프로덕션 코드에서는 사용하지 않았으며 유스 케이스를 생각할 수 없습니다. 그러나 var로 선언 된 변수 에는 블록 범위가 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.