Object.freeze () 대 const


136

Object.freeze()constES6에서 사용하기 위해 전환하는 편리한 방법처럼 보입니다 .

코드에서 둘 다 발생하는 경우가 있거나 불변 데이터로 작업하는 선호되는 방법이 있습니까?

Object.freeze()지원하는 모든 브라우저를 사용할 때까지 사용해야 const하고 const대신 사용으로 전환해야 합니까?


2
빌드 프로세스에서 babeljs 를 사용하여 이러한 호환성 문제를 주로 무시할 수있었습니다.
쓰셨

22
아니요-그들은 다른 일을합니다. const는 재 할당을 방지합니다 (예 : const x = 1; x = 2는 불가능). 동결은 돌연변이를 방지합니다 (예 : Object.freeze (x); xa = 2);
joews

이것을 새로운 질문으로 만들거나 여기에 고정시키는 것이 타당한 지 확실하지 않지만 Symbols와 Object.freeze 사이에 큰 차이점이 있는지 궁금합니다. 나는 또한 그것들이 관련되어 있다고 느낀다 (즉, 심볼들은 고정 된 것으로 평가 Object.isFrozen되지만 그것들은 또한 그들 자신의 원시 데이터 타입이다 ...)
aug

1
돌연변이는 첫 번째 수준에서만 방지되므로 Object.freeze (x); xa = 2이지만 CAN Object.freeze (x); xab = 2. jsfiddle.net/antimojv/op6ea91w/8을 참조하십시오 . 완전 동결을 위해 임시 라이브러리를 사용하십시오
Antimo

답변:


232

constObject.freeze완전히 다른 두 가지 있습니다.

const바인딩에 적용됩니다 ( "변수"). 변경 불가능한 바인딩을 만듭니다. 즉, 바인딩에 새 값을 할당 할 수 없습니다.

Object.freeze ,보다 구체적으로 객체 값 에서 작동 합니다 . 객체를 불변으로 만듭니다. 즉, 속성을 변경할 수 없습니다.


3
기본적으로 const새로운 것입니다 var. 그것은 단지 블록 범위이며 재 할당을 방지합니다. 을 사용할 수 let있지만 변수가 가리키는 값을 변경하려는 경우에만 필요합니다. 이는 루프 제어 / 반복자 변수와 숫자 및 문자열과 같은 간단한 유형에 적합하지만 대부분의 객체 사용에는 적합하지 않습니다. 배열). 내용을 변경할 수없는 객체 / 배열을 원한다면 선언하는 것 외에도 const호출해야 Object.freeze()합니다.
Mark Reed

2
const새로운 아닙니다 var, let새로운 인var
파쿤도 COLOMBIER

84

ES5 Object.freeze에서는 프리미티브에서 작동하지 않으며 아마도 const객체보다 더 일반적으로 선언 됩니다. ES6에서 프리미티브를 고정 할 수 있지만을 지원합니다 const.

반면에 const객체를 선언하는 데 사용되는 것은 "동결"되지 않으며 전체 객체를 다시 선언 할 수는 없지만 키를 자유롭게 수정할 수 있습니다. 반면에 고정 된 개체를 다시 선언 할 수 있습니다.

Object.freeze 또한 얕으므로 중첩 된 객체에 재귀 적으로 적용하여 보호해야합니다.

var ob1 = {
   foo : 1,
    bar : {
        value : 2   
    }
};
Object.freeze( ob1 );

const ob2 = {
   foo : 1,
    bar : {
        value : 2   
    }
}

ob1.foo = 4;  // (frozen) ob1.foo not modified
ob2.foo = 4;  // (const) ob2.foo modified

ob1.bar.value = 4;  // (frozen) modified, because ob1.bar is nested
ob2.bar.value = 4;  // (const) modified

ob1.bar = 4;  // (frozen) not modified, bar is a key of obj1
ob2.bar = 4;  // (const) modified

ob1 = {};  // (frozen) ob1 redeclared
ob2 = {}; // (const) ob2 not redeclared

이 설명은 많은 질문을 한 번에 해결했습니다! 관련 ob1.bar.value = 4; // (frozen) modified, because ob1.bar is nested: 메소드의 범위 때문입니까?
YCode

14

요약:

constObject.freeze()완전히 다른 목적을 제공합니다.

  • const즉시 선언해야하고 재 할당 할 수없는 변수를 선언해야합니다. 에 의해 선언 된 변수 const는 블록 범위이며로 선언 된 변수 처럼 기능 범위가 아닙니다var
  • Object.freeze()객체를 받아들이고 동일한 객체를 반환하는 메서드입니다. 이제 개체의 속성을 제거하거나 새 속성을 추가 할 수 없습니다.

const:

예 1 : 재 할당 할 수 없음 const

const foo = 5;

foo = 6;

다음 코드는 const키워드 로 선언 된 변수 foo를 재 지정하려고하므로 오류를 발생시킵니다 . 재 지정할 수 없습니다.

예 2 : 할당 된 데이터 구조 const는 변경 가능

const object = {
  prop1: 1,
  prop2: 2 
}

object.prop1 = 5;   // object is still mutable!
object.prop3 = 3;   // object is still mutable!

console.log(object);  // object is mutated

이 예에서는 const키워드를 사용하여 변수를 선언하고 여기 에 객체를 할당합니다. object라는이 변수에 재 할당 할 수는 없지만 객체 자체를 변경할 수 있습니다. 기존 속성을 변경하거나 새 속성을 추가하면 효과가 있습니다. 개체에 대한 변경 사항을 비활성화하려면 필요합니다 Object.freeze().

Object.freeze():

예 1 : 고정 된 개체를 변형 할 수 없습니다

object1 = {
  prop1: 1,
  prop2: 2
}

object2 = Object.freeze(object1);

console.log(object1 === object2); // both objects are refer to the same instance

object2.prop3 = 3; // no new property can be added, won't work

delete object2.prop1; // no property can be deleted, won't work

console.log(object2); // object unchanged

이 예제에서 우리가 호출 Object.freeze()하고 object1인수로 줄 때 함수는 이제 '냉동 된'객체를 반환합니다. ===연산자를 사용하여 새 객체의 참조를 이전 객체와 비교 하면 동일한 객체를 참조한다는 것을 알 수 있습니다. 또한 속성을 추가하거나 제거하려고 시도해도 아무런 영향이 없음을 알 수 있습니다 (엄격 모드에서는 오류가 발생 함).

예 2 : 참조가있는 객체가 완전히 고정되지 않았습니다

const object = {
  prop1: 1,
  nestedObj: {
    nestedProp1: 1,
    nestedProp2: 2,
  } 
}


const frozen = Object.freeze(object);

frozen.prop1 = 5; // won't have any effect
frozen.nestedObj.nestedProp1 = 5; //will update because the nestedObject isn't frozen

console.log(frozen);

이 예제는 중첩 객체 (및 기타 참조 데이터 구조 별)의 속성이 여전히 변경 가능함을 보여 줍니다. 따라서 Object.freeze()참조 (예 : 배열, 객체) 속성이있을 때 객체를 완전히 '고정'시키지 않습니다.


12
var obj = {
  a: 1,
  b: 2
};
Object.freeze(obj);
obj.newField = 3; // You can't assign new field , or change current fields

위의 예제는 객체를 불변으로 만듭니다.

다음 예제를 보자.

const obj = {
  a: 1,
  b: 2
};
obj.a = 13; // You can change a field
obj.newField = 3; // You can assign new field.

오류가 발생하지 않습니다.

하지만 그렇게하면

const obj = {
      a: 1,
      b: 2
    };
obj = {
 t:4
};

"obj is read-only"와 같은 오류가 발생합니다.

다른 사용 사례

const obj = {a:1};
var obj = 3;

던질 것이다 Duplicate declaration "obj"

또한 mozilla docs const 설명 에 따르면

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

이 예는 babeljs ES6 기능에 따라 작성되었습니다.


4

간단하게하자.

그들은 다르다. 각 사례를 설명하는 코드에 대한 주석을 확인하십시오.

Const- let값을 재 할당 할 수없는 블록 범위 변수 입니다.

그것의 의미는

{
 const val = 10;  // you can not access it outside this block, block scope variable

}

console.log(val); // undefined because it is block scope 

const constvalue = 1;
constvalue = 2; // will give error as we are re-assigning the value;
const obj = { a:1 , b:2};

obj.a = 3;
obj.c = 4;
console.log(obj); // obj = {a:3,b:2,c:4} we are not assigning the value of identifier we can 
                  // change the object properties, const applied only on value, not with properties
obj = {x:1};     // error you are re-assigning the value of constant obj 
obj.a = 2 ;     // you can add, delete element of object

const는 블록 범위이며 그 값은 다시 할당되지 않는다는 것을 완전히 이해하고 있습니다.

Object.freeze: 객체 루트 속성은 변경할 수 없으며 더 많은 속성을 추가 및 삭제할 수 없지만 전체 객체를 다시 할당 할 수 있습니다.

var x = Object.freeze({data:1,
    name:{
    firstname:"hero", lastname:"nolast"
    }
});

x.data = 12;  // the object properties can not be change but in const you can do
x.firstname ="adasd"; // you can not add new properties to object but in const you can do

x.name.firstname = "dashdjkha"; // The nested value are changeable 

//The thing you can do in Object.freeze but not in const

x = { a: 1};  // you can reassign the object when it is Object.freeze but const its not allowed

// 둘 다 비슷한 것은 중첩 된 객체를 변경할 수 있다는 것입니다.

const obj1 = {nested :{a:10}};
var obj2 =  Object.freeze({nested :{a:10}});

obj1.nested.a = 20; // both statement works
obj2.nested.a = 20;

감사.

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