JavaScript의 객체 불변성

JavaScript에서 객체 불변성을 실현하려면 세 가지 방법이 있습니다.
  • 반대.예방적 확장(obj);
  • 반대.인장(obj);
  • 반대.동결(obj);
  • JavaScript에서 객체 불변성이 어떻게 작동하는지 이해하려면 먼저 객체의 속성이 어떻게 설명되는지 이해해야 합니다.

    속성 설명자
    JavaScript의 객체에는 ES5부터 모든 속성이 속성 설명자로 설명되어 있는 속성이 있습니다.다음과 같은 방법으로 객체의 속성에 대한 설명자를 가져올 수 있습니다.
    Object.getOwnPropertyDescriptor(obj, 'property');
    
    이것은 속성의 값과 특징을 포함하고 속성을 어떻게 설명하는지 포함하는 대상을 되돌려줍니다.다음은 당신이 그것을 어떻게 사용하는지
    const obj = {
        x: 'some value of x'
    }
    
    const descriptors = Object.getOwnPropertyDescriptor(obj, 'x');
    
    console.log(descriptors);
    
    /* Returns
    Object { 
        value: 'some value of x', 
        writable: true, 
        enumerable: true, 
        configurable: true 
    }*/
    
    기본적으로 대상 속성 설명자 (쓰기 가능, 설정 가능, 열거 가능) 는true로 설정됩니다.우리는 이 절에서 각 항목을 상세하게 소개할 것이다.
    속성에 대한 설명자를 변경하려면 Object.defineProperty(obj, prop, descriptor) 방법을 사용합니다.그것이 필요로 하는 세 가지 논점은

  • obj: 속성을 정의할 대상

  • 속성:정의하거나 수정할 속성 이름

  • 설명자: 속성을 정의하거나 수정하는 설명자입니다.
  • 주의해야 할 점은 defineProperty 방법으로 대상에게 속성을 추가할 때 새로운 속성에 대한 설명부호가 false로 표시되는 것이다.위의 예시에서 모든 설명자가 기본적으로 true 로 설정된 이유는 defineProperty 방법으로 'x' 를 정의하지 않았기 때문이다.위의 예와 비교하여 아래의 예를 고려하다.
    const obj1 = {};
    
    Object.defineProperty(obj1, 'prop1', {
      value: 42,
    });
    
    const descriptors = Object.getOwnPropertyDescriptor(obj1, 'prop1');
    
    console.log(descriptors);
    
    /* Returns
    Object { 
        value: 42, 
        writable: false, 
        enumerable: false, 
        configurable: false 
    }*/
    

    쓸 수 있다
    쓰기 가능한 설명자가true로 설정되었을 때 속성에 값을 부여하고 다시 부여할 수 있습니다.여기에 예가 하나 있다
    let myObject = {
        x: 'someValue'
    };
    
    myObject.x = 'some other value';
    myObject.x = 52;
    
    모든 것이 정상이다.그러나 쓰기 가능 설명자의 값이 false로 설정된 경우에는 값을 변경할 수 없습니다.
    이게 어떻게 된 일인지 한번 봅시다.
    let myObject = { x: 52 }; // writable is true
    
    Object.defineProperty(myObject, 'x', {
        writable: false
    });
    
    // The following will silently fail
    myObject.x = 42;
    
    속성 값을 재할당할 때 사용 가능'use strict'(엄격 모드)이 아닌 경우 재할당이 자동으로 실패합니다.엄격 모드가 활성화된 경우 JavaScript에서 읽기 전용이라는 오류를 내보냅니다.
    Error: "x" is read-only
    

    구성 가능
    이 설명자가true로 설정되면 속성의 설명자를 변경할 수 있습니다.여기에 예가 하나 있다
    let myObj = {
        x: 52
    };
    
    // By default the configurable descriptor on 'x' 
    // is set to true so you can do the following i.e. you can configure it.
    
    Object.defineProperty(myObj, x, {
        enumerable: false
    });
    
    단, 설정 가능한 설명자가false로 설정되면 속성 설명자를 변경할 수 없습니다. (writable와value를 제외하고는 속성을 설정할 수 없습니다.)뿐만 아니라 객체에서 속성을 제거할 수도 없습니다.코드의 다른 부분에서 의외로 속성을 삭제하는 것을 방지하기를 원할 때, 이것은 특히 유용합니다.아래는 그것의 외관이다
    let myObj = { x: 32 };
    
    Object.defineProperty(myObj, 'x', {
        configurable: false
    });
    
    // Other than the 'writable' and 'value' descriptors, you can't re-configure this property;
    
    // You also can't delete the property
    delete myObj.x;
    
    구성 가능한 설명자를false로 설정하고 엄격한 모드에서 속성을 다시 설정하려고 시도하면 다음과 같은 오류가 발생합니다
    'use strict';
    
    const object1 = { x: 2 };
    
    Object.defineProperty(object1, 'x', {
      configurable: false
    });
    
    Object.defineProperty(object1, 'x', {
      enumerable: false
    });
    
    // Error: can't redefine non-configurable property "x"
    
    속성을 삭제하려고 시도하면 던집니다
    'use strict';
    
    const object1 = { x: 2 };
    
    Object.defineProperty(object1, 'x', {
      configurable: false
    });
    
    delete object1.x;
    console.log(object1.x);
    
    // Error: property "x" is non-configurable and can't be deleted
    

    열거할 수 있다
    이 설명자가true로 설정되면, 대상 키를 교체할 때 이 속성을 읽습니다.이것은 이 키가 for…in 순환에 나타난다Object.keys().여기에 예가 하나 있다
    const obj = {
        x: 52 //enumerable is true
    };
    
    Object.defineProperty(obj, 'a’, {
        value: 1 // enumerable is false
    });
    
    Object.defineProperty(obj, 'b’, {
        value: 1, 
        enumerable: true // self explanatory
    });
    
    obj.c = 53; // When creating properties by setting them, the descriptors are defaulted to true.
    
    for (key in obj) {
        console.log(key) // x, b, c
    }
    
    console.log(Object.keys(obj)); // [x, b, c]
    
    당신은 또한 대상에 propertyIsEnumerable 방법을 사용하여 속성이 열거할 수 있는지 검사할 수 있습니다. 아래와 같습니다.
    obj.propertyIsEnumerable('x'); // true
    obj.propertyIsEnumerable('a'); // false
    obj.propertyIsEnumerable('b'); // true
    obj.propertyIsEnumerable('c'); // true
    

    대상 불변성
    드디어!대상의 속성이 어떻게 작동하는지, 그리고 그것이 어떻게 묘사되는지 알았기 때문에 대상의 불변성이 어떻게 작동하는지 이해하기는 매우 쉽다.서로 다른 단계의 대상의 불변성을 실현하는 세 가지 방법은
  • 반대.preventExtensions()
  • 반대.밀봉부재()
  • 반대.동결()
  • 이러한 방법은 본질적으로 속성 묘사자를 이용하여 대상을 변할 수 없게 한다.우리 하나씩 봅시다.

    반대, 반대하다확장 방지()
    기본적으로 객체는 확장이 가능하므로 속성을 추가할 수 있습니다.대상이 확장될 수 있는지 확인하려면 다음과 같은 방법을 사용하십시오 isExtensible
    const someObject = {};
    Object.isExtensible(someObject); // true
    
    이것은 preventExtensions 이런 방법으로 바꿀 수 있다
    const someObject = {};
    Object.preventExtensions(someObject);
    Object.isExtensible(someObject); // false
    
    이 대상에 속성을 추가하려고 시도할 때 오류가 발생합니다
    Object.defineProperty(someObject, 'nProp', { value: 52 });
    //  Error: can't define property "nProp": Object is not extensible
    
    대상의 사용자가 그것을 사용해서 어떤 일을 할 수 있기를 원하지만, 더 많은 속성을 추가하지 않을 때 매우 유용합니다.
    주의: 여기서 주의해야 할 점은 Object.preventExtensions() 대상 자체의 속성만 막는 것이다.객체의 [[Prototype]]에 속성을 추가할 수 있습니다.[[Get]][[Put]] 알고리즘이 자바스크립트에서 어떻게 작동하는지 다른 글의 주제입니다.

    반대, 반대하다도장.
    이 방법은 대상을 호출Object.preventExtensions()하고 모든 속성의 설정 가능한 설명자를false로 설정합니다.이렇게 하면 객체의 사용자가 추가 속성을 추가하거나 객체에서 속성을 제거(삭제)할 수 없습니다.여기에 예가 하나 있다
    const obj = {
      x: 42
    };
    
    Object.seal(obj);
    obj.x = 52;
    
    console.log(obj.x); // 52
    
    delete obj.x; // cannot delete when sealed
    console.log(obj.x); // 52
    
    Object.defineProperty(obj, 'y', { value: 24 });
    //  Error: can't define property "y": Object is not extensible
    

    반대, 반대하다얼어붙다
    이것이 바로 그것이 듣는 모습이다.이것은 Object.preventExtensions, Object.seal를 사용하여 대상을 동결하고 모든 속성의 쓰기 가능한 설명자를false로 한다.
    이것은 네가 가질 수 있는 가장 높은 형식의 불변성이다.새 속성을 추가하지 못하도록 방지하고, 기존 속성을 삭제하며, 기존 속성의 열거성, 구성 또는 쓰기 가능성을 변경하지 못하며, 기존 속성의 값을 변경하지 못하도록 방지합니다.이 밖에 수정 대상의[[Prototype]]도 방지할 수 있다.
    'use strict';
    
    const obj = { 
        x: 52 
    };
    
    Object.freeze(obj);
    
    obj.x = 32;
    // Error: "x" is read-only
    
    obj.y = 52; 
    // Error: can't define property "y": Object is not extensible
    
    Object.defineProperty(obj, 'y', { value: 52 });
    // Error: can't define property "y": Object is not extensible
    
    Object.defineProperty(obj, 'x', { enumerable: false });
    // Error: can't redefine non-configurable property "x"
    
    Object.defineProperty(obj, 'x', { writable: true});
    // Error: can't redefine non-configurable property "x"
    

    결론
    서로 다른 속성 묘사자가 어떻게 작동하는지 알고 다른 방법으로 바꾸면 대상의 불변성을 이해하기가 훨씬 쉬워진다.
    현재, 사용 가능한 서로 다른 속성 설명자, 그것들을 어떻게 수정하고, 부작용을 수정하며, 대상의 불변성에서 사용하는지, 그리고 그것들이 어떻게 사용되는지 이미 알고 있을 것입니다.이제는 서로 다른 등급의 대상의 불변성을 실현할 수 있는 세 가지 방법과 그 뒤에 있는 작업 방식도 알아야 한다.
    이전에 속성 설명자를 수정해야 했습니까?상대를 변치 못하게 하는 게 어때요?아래의 평론에서 당신이 이 물건들에 대한 체험과 그것을 사용할 때 겪는 어떤 문제도 저에게 알려주세요.
    건배!

    좋은 웹페이지 즐겨찾기