[javascript] 자바 스크립트에서 상수 값을 변경할 수있는 이유

ES6가 아직 표준화되지 않았다는 것을 알고 있지만 현재 많은 브라우저 const 가 JS에서 키워드를 지원 합니다.

사양에서 다음과 같이 작성되었습니다.

상수의 값은 재 할당을 통해 변경할 수 없으며 상수를 다시 선언 할 수 없습니다. 이 때문에 초기화하지 않고 상수를 선언 할 수 있지만 그렇게하는 것은 쓸모가 없습니다.

그리고 이렇게하면 :

const xxx = 6;
xxx = 999;
xxx++;
const yyy = [];
yyy = 'string';
yyy = [15, 'a'];

나는 모든 것이 괜찮 볼 xxx여전히 6하고 yyy있다 [].

그러나 그렇게 yyy.push(6); yyy.push(1);하면 내 상수 배열이 변경되었습니다. 지금 [6, 1]은 그렇고 나는 여전히 yyy = 1;.

이건 버그인가요, 아니면 뭔가 빠졌나요? 나는 최신 크롬과 FF29에서 그것을 시도했다



답변

문서는 다음과 같이 설명합니다.

… 상수는 재 할당을 통해 변경할 수 없습니다
… 상수는 다시 선언 할 수 없습니다.

배열이나 객체에 추가 할 때 상수를 재 할당하거나 다시 선언하는 것이 아니라 이미 선언되고 할당 된 것이며 상수가 가리키는 “목록”에 추가하는 것입니다.

따라서 이것은 잘 작동합니다.

const x = {};

x.foo = 'bar';

console.log(x); // {foo : 'bar'}

x.foo = 'bar2';

console.log(x); // {foo : 'bar2'}  

이:

const y = [];

y.push('foo');

console.log(y); // ['foo']

y.unshift("foo2");

console.log(y); // ['foo2', 'foo']

y.pop();

console.log(y); // ['foo2']

하지만 둘 다 :

const x = {};
x = {foo: 'bar'}; // error - re-assigning

const y = ['foo'];
const y = ['bar']; // error - re-declaring

const foo = 'bar'; 
foo = 'bar2';       // error - can not re-assign
var foo = 'bar3';   // error - already declared
function foo() {};  // error - already declared


답변

이것은 상수가 실제로 배열에 대한 참조 를 저장하기 때문에 발생합니다 . 배열에 무언가를 결합 할 때 상수 값을 수정하는 것이 아니라 가리키는 배열을 수정하는 것입니다. 객체를 상수에 할당하고 그 속성을 수정하려는 경우에도 마찬가지입니다.

수정할 수 없도록 배열 또는 개체를 고정하려면 Object.freeze이미 ECMAScript 5의 일부인 메서드를 사용할 수 있습니다 .

const x = Object.freeze(['a'])
x.push('b')
console.log(x) // ["a"]


답변

이것은 내가 생각할 수있는 모든 프로그래밍 언어에서 일관된 동작입니다.

C를 고려하십시오-배열은 단지 영광스러운 포인터입니다. 상수 배열은 포인터의 값이 변경되지 않음을 의미 할뿐입니다. 실제로 해당 주소에 포함 된 데이터는 자유롭게 사용할 수 있습니다.

자바 스크립트에서는 상수 객체의 메소드를 호출 할 수 있습니다 (물론-그렇지 않으면 상수 객체가 그다지 목적을 이루지 않습니다!) 이러한 메소드는 객체를 수정하는 부작용이있을 수 있습니다. 자바 스크립트의 배열은 객체이기 때문에이 동작은 그들에게도 적용됩니다.

당신이 확신하는 것은 상수가 항상 같은 객체를 가리킬 것이라는 것입니다. 개체 자체의 속성은 자유롭게 변경할 수 있습니다.


답변

const 선언은 값에 대한 읽기 전용 참조를 만듭니다. 보유한 값이 변경 불가능하다는 의미가 아니라 변수 식별자를 재 할당 할 수 없다는 의미입니다. 예를 들어 콘텐츠가 객체 인 경우 이는 객체의 내용 (예 : 매개 변수)이 변경 될 수 있음을 의미합니다.

또한 중요한 참고 사항 :

전역 상수는 창 개체의 속성이되지 않습니다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const


답변

https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0 문제에 대해 더 명확하게 설명 할 수 있다고 생각합니다 .

기본적으로 const항상 메모리에서 동일한 주소를 가리키는 것으로 요약됩니다 . 해당 주소에 저장된 값을 변경할 수 있지만 const가리키는 주소도 변경할 수 없습니다 .

const언급 한 정의 const는가 원시 값을 보유하는 주소를 가리킬 때 참 입니다. 이것은 const주소를 변경하지 않고 는 값을 할당 할 수없고 (기본 값 할당이 작동하는 방식이기 때문에) a의 주소를 변경할 const수 없기 때문입니다.

const가 원시 값이 아닌 값을 가리키는 것처럼 주소 값을 편집 할 수 있습니다.


답변

이 기사를 통해 객체를 .zip으로 정의한 후에도 업데이트 할 수 있었던 이유를 검색했습니다 const. 따라서 여기서 요점은 직접 Object가 아니라 업데이트 할 수있는 속성이 포함되어 있다는 것입니다.

예를 들어, 내 개체는 다음과 같습니다.

const number = {
    id:5,
    name:'Bob'
};

위의 답변은 속성이 아닌 const 인 Object임을 올바르게 지적했습니다. 따라서 다음을 수행하여 ID 또는 이름을 업데이트 할 수 있습니다.

number.name = 'John';

그러나 다음과 같이 개체 자체를 업데이트 할 수 없습니다.

number = {
    id:5,
    name:'John'
  };

TypeError: Assignment to constant variable.


답변

const에서 객체의 값을 변경할 수 있으므로 객체는 실제로 할당 데이터를 저장하지 않고 대신 해당 데이터를 가리 킵니다. 따라서 Javascript의 기본 요소와 객체에는 차이가 있습니다.