>  기사  >  웹 프론트엔드  >  JS 속성 특성(속성 설명자)

JS 속성 특성(속성 설명자)

高洛峰
高洛峰원래의
2016-10-31 11:55:53995검색

JS 속성 특성(속성 설명자)

ECMAScript 5는 다양한 특성을 설명하는 데 사용되는 "속성 설명자"라는 개체를 정의합니다. "속성 설명자" 개체는 Object.defineProperty 또는 Object.defineProperties에서만 사용할 수 있습니다.

Concept

ECMAScript 5는 다양한 특성을 설명하는 데 사용되는 "속성 설명자"라는 객체를 정의합니다. 속성 설명자 객체에는 4가지 속성이 있습니다.

configurable: 설명하는 속성의 수정을 제어하는 ​​구성 가능성으로, 속성의 특성이 수정될 수 있는지 여부, 속성이 접근자 속성으로 수정될 수 있는지 여부, 또는 속성을 재정의하기 위해 삭제를 통해 속성을 삭제할지 여부입니다. 기본값은 true입니다.

열거 가능: 열거 가능성, for-in 순회를 통해 속성을 얻을 수 있는지 여부를 나타냅니다. 기본값은 true입니다.

writable: 쓰기 가능성, 속성 값을 수정할 수 있는지 여부를 나타냅니다. 기본값은 true입니다.

값: 데이터 속성, 속성 값을 나타냅니다. 기본값은 정의되지 않습니다.

위 속성 외에도 값과 쓰기 가능을 대체할 수 있는 get 및 set이라는 두 가지 접근자 속성이 있습니다.

get: 속성을 읽을 때 호출되는 함수입니다. get만 지정하면 속성이 읽기 전용임을 의미합니다. 기본값은 정의되지 않습니다.

set: 속성을 쓸 때 호출되는 함수입니다. set만 지정한다는 것은 속성이 쓰기 전용 속성임을 의미합니다. 기본값은 정의되지 않습니다.

"속성 설명자" 개체 사용은 Object.defineProperty 또는 Object.defineProperties에서만 사용할 수 있습니다.

API 사용법

Object.defineProperty: https://developer.mozilla.org...

Object.defineProperties: https://developer.mozilla.org. ..

var hello = {} 
 
Object.defineProperty(hello, 'girl', { 
    configurable: false, 
    enumberable: false, 
    writable: true, 
    value: 'sexy' 
}) 
 
// 存取器 
Object.defineProperty(hello, 'woman', { 
    configurable: false, 
    enumberable: false, 
    get: function() { 
        return this.girl 
    }, 
    set: function(val) { 
        this.girl = val 
    } 
}) 
 
// 定义多个属性 
Object.defineProperties(hello, { 
    boy: { 
        configurable: false, 
        enumberable: false, 
        writable: false, 
        value: 'handsome' 
    }, 
    man: { 
        configurable: false, 
        enumberable: false, 
        writable: true, 
        get: function() { 
            return this.boy 
        } 
    } 
})

Object.defineProperty 또는 Object.defineProperties를 사용하여 생성 또는 수정이 허용되지 않는 속성을 조작(생성 또는 수정)하는 경우 유형 오류 예외가 발생합니다.

// 此例子运行在前面的例子的基础上 
Object.defineProperty(hello, 'boy', { 
    writable: true 
})    // Uncaught TypeError: Cannot redefine property: boy

boy 속성은 이전에 구성 불가능으로 설정되었기 때문에 여기에서 쓰기 가능 항목을 수정하면 유형 오류 예외가 발생합니다.

속성 설명자는 Object.getOwnPropertyDescriptor 또는 Object.getOwnPropertyDescriptors를 통해 얻을 수 있습니다.

API 사용법

Object.getOwnPropertyDscriptor: https://developer.mozilla.org...

Object.getOwnPropertyDescriptors: https://developer.mozilla.org. ..

규칙

var rules = { 
    common: 'test' 
}

속성을 구성할 수 없는 경우 구성 가능성과 열거 가능성을 수정할 수 없습니다.

Object.defineProperty(rules, 'rule1', { 
    configurable: false, 
    enumberable: false 
}) 
 
// 修改configurable会抛出类型错误异常 
Object.defineProperty(rules, 'rule1', { 
    configurable: true 
})    // Uncaught TypeError: Cannot redefine property: rule1 
 
// 修改enumberable不会抛出异常,但enmuberable没有被修改 
Object.defineProperty(rules, 'rule1', { 
    enumberable: true 
}) 
Object.getOwnPropertyDescriptor(rules, 'rule1')    // Object {value: undefined, writable: false, enumerable: false, configurable: false}

접근자 속성을 구성할 수 없는 경우 get 및 set 메서드를 수정할 수 없으며 데이터 속성으로 변환할 수도 없습니다.

Object.defineProperty(rules, 'rule2', { 
    configurable: false, 
    enumberable: false, 
    get: function() { 
        return this.common 
    }, 
    set: function(val) { 
        this.common = val 
    } 
}) 
 
// 修改get或者set方法会抛出类型错误异常 
Object.defineProperty(rules, 'rule2', { 
    get: function() { 
        return this.common + 'rule2' 
    } 
})    // Uncaught TypeError: Cannot redefine property: rule2 
 
Object.defineProperty(rules, 'rule2', { 
    set: function(val) { 
        this.common = 'rule2' 
    } 
})    // Uncaught TypeError: Cannot redefine property: rule2 
 
// 将它转换为数据属性同样会抛出类型错误异常 
Object.defineProperty(rules, 'rule2', { 
    value: 'rule2' 
})    // Uncaught TypeError: Cannot redefine property: rule2

데이터 속성을 구성할 수 없으면 동시에 접근자 속성으로 변환할 수 없으며 쓰기 가능성을 false에서 true로 수정할 수는 없지만 true에서 true로 수정할 수는 있습니다. 거짓.

Object.defineProperty(rules, 'rule3', { 
    configurable: false, 
    writable: false, 
    value: 'rule3' 
}) 
 
// 修改writable为true会抛出类型错误异常 
Object.defineProperty(rules, 'rule3', { 
    writable: true 
}) 
 
 
Object.defineProperty(rules, 'rule4', { 
    configurable: false, 
    writable: true, 
    value: 'rule4' 
}) 
 
// 可以修改writable为false 
Object.defineProperty(rules, 'rule4', { 
    writable: false 
}) 
Object.getOwnPropertyDescriptor(rules, 'rule4')    //   Object {value: "rule4", writable: false, enumerable: false, configurable: false}

데이터 속성이 구성 불가능하고 쓰기 불가능하면 해당 값을 수정할 수 없습니다. 구성 가능하지만 쓰기 가능하지 않으면 해당 값을 수정할 수 있습니다(실제로 쓰기 가능으로 표시됨). 그런 다음 해당 값을 수정하고 마지막으로 다시 쓸 수 없는 것으로 표시합니다.

사실 여기서 언급한 수정값은 Object.defineProperty나 Object.defineProperties 메소드를 통해 수정된 것입니다. 데이터 속성을 구성할 수 없는 경우 직접 할당을 통해 속성 값을 수정할 수 없습니다.

Object.defineProperty(rules, 'rule5', { 
    configurable: false, 
    writable: false, 
    value: 'rule5' 
}) 
 
// 修改属性值会抛出类型错误异常 
Object.defineProperty(rules, 'rule5', { 
    value: 'rule55' 
})    // Uncaught TypeError: Cannot redefine property: rule5 
 
rules.rule5 = 'rule55' 
// 值没有被修改,也不会抛出异常 
rules.rule5            // 'rule5' 
 
 
Object.defineProperty(rules, 'rule6', { 
    configurable: true, 
    writable: false, 
    value: 'rule6' 
}) 
 
// 修改属性值 
Object.defineProperty(rules, 'rule6', { 
    value: 'rule66' 
}) 
rules.rule6            // 'rule66' 
 
rules.rule6 = 'rule6' 
// 值没有被修改,也不会修改 
rules.rule6            // 'rule6'

지정된 세트만 읽을 수 없습니다. 속성 값을 읽으려고 하면 정의되지 않은 값이 반환됩니다. (Red Book에서는 예외가 엄격 모드에서만 발생한다고 나와 있지만 그렇지 않습니다.)

Object.defineProperty(rules, 'rule7', { 
    get: function() { 
        return this.common 
    } 
}) 
rules.rule7 = 'rule7'    // Uncaught TypeError: Cannot redefine property: rule7

객체가 확장 가능하지 않은 경우 기존 자체 속성을 편집할 수는 있지만 새 속성을 추가할 수는 없습니다. 그것.재산.

객체 확장성을 작동하기 위한 API에는 Object.preventExtensions, Object.seal 및 Object.freeze의 세 가지가 있습니다.

API 사용법

Object.preventExtensions: https://developer.mozilla.org...

Object.seal: https://developer.mozilla.org. ..

Object.freeze: https://developer.mozilla.org...

Object.isExtensions: https://developer.mozilla.org...

Object.isSealed: https://developer.mozilla.org...

Object.isFrozen: https://developer.mozilla.org...

Object.preventExtensions 사용 객체는 확장 불가능한 객체로 변환될 수 있습니다.

객체가 확장 가능한지 확인하려면 Object.isExtensions를 사용하세요.

var ex = {} 
Object.defineProperty(ex, 'ex1', { 
    configurable: true, 
    writable: true, 
    value: 'ex1' 
}) 
Object.isExtensible(ex)        // true 
Object.preventExtensions(ex) 
Object.isExtensible(ex)        // false 
 
// 可以修改已有的属性 
Object.defineProperty(ex, 'ex1', { 
    writable: false, 
    value: 'ex11' 
}) 
Object.getOwnPropertyDescriptor(ex, 'ex1')    // Object {value: "ex11", writable: false, enumerable: false, configurable: true} 
 
// 添加属性会抛出类型错误异常 
Object.defineProperty(ex, 'ex2', { 
    value: 'ex2' 
})    // Uncaught TypeError: Cannot define property:ex2, object is not extensible.

객체를 확장 불가능으로 변환하는 것 외에도 Object.seal을 사용하면 객체 자체의 모든 속성을 구성 불가능으로 변환할 수도 있습니다. 즉, 새 속성을 개체에 추가할 수 없으며 기존 속성을 삭제하거나 구성할 수 없습니다. 여기서는 이전과 동일한 규칙을 따릅니다.

객체가 봉인되었는지 확인하려면 Object.isSealed를 사용하세요.

var se = {} 
Object.defineProperty(se, 'se1', { 
    configurable: true, 
    writable: false, 
    value: 'se1' 
}) 
Object.isSealed(se)        // false 
Object.seal(se) 
Object.isSealed(se)        // true 
 
// 修改已有的属性会抛出类型错误异常 
Object.defineProperty(se, 'se1', { 
    writable: true, 
    value: 'se11' 
})    // Uncaught TypeError: Cannot redefine property: se1 
 
// 添加属性会抛出类型错误异常 
Object.defineProperty(se, 'se2', { 
    value: 'se2' 
})    // Uncaught TypeError: Cannot define property:se2, object is not extensible.

Object.freeze를 사용하면 객체를 확장 불가능으로 변환하고 해당 속성을 구성 불가능으로 변환하는 것 외에도 자신의 속성을 읽기 전용으로 변환할 수도 있습니다. (객체를 설정한 경우 접근자 속성은 영향을 받지 않으며 set 메서드를 계속 호출할 수 있으며 예외가 발생하지 않습니다. 그러나 set 메서드가 객체의 속성을 변경하면 성공적으로 수정할 수 없습니다.)

객체가 동결되었는지 여부를 감지하려면 Object.isFrozen을 사용하세요.

var fr = {} 
Object.defineProperty(fr, 'fr1', { 
    configurable: true, 
    writable: false, 
    value: 'fr1' 
}) 
Object.isFrozen(fr)        // false 
Object.freeze(fr) 
Object.isFrozen(fr)        // true 
 
// 修改已有的属性会抛出类型错误异常 
Object.defineProperty(fr, 'fr1', { 
    writable: true, 
    value: 'fr11' 
})    // Uncaught TypeError: Cannot redefine property: fr1 
 
// 添加属性会抛出类型错误异常 
Object.defineProperty(fr, 'fr2', { 
    value: 'fr2' 
})    // Uncaught TypeError: Cannot define property:fr2, object is not extensible. 
 
fr.fr1 = 'fr11' 
// 不能修fr1属性 
fr.fr1            // 'fr1' 
var set = {} 
Object.defineProperty(set, 'set1', { 
    configurable: true, 
    value: 'set1' 
}) 
Object.defineProperty(set, 'set2', { 
    configurable: true, 
    set: function(val) { 
        this.set1 = val 
    } 
}) 
Object.isFrozen(set)        // false 
Object.freeze(set) 
Object.isFrozen(set)        // true 
 
set.set2 = 'set2' 
set.set1                    // 'set1'

결론

저는 속성 설명자를 거의 사용하지 않기 때문에 매우 익숙하지 않습니다. 그러나 최근에 나는 몇몇 작은 라이브러리를 작성하는 법을 배우기 시작했고(비록 매우 실망스러웠지만) 속성 설명자를 사용하는 시나리오가 있다는 것을 느꼈습니다. 일단 제가 생각할 수 있는 것은 사용자가 객체의 일부 속성을 덮어쓰는 것을 방지하기 위해 라이브러리 객체의 일부 속성을 읽기 전용으로 설정하는 것입니다. Zhihu에서 Vue를 배울 때 배운 또 다른 사용법이 있는데, 이는 getter 및 setter를 사용하여 객체 속성의 데이터 업데이트를 "모니터링"하는 것입니다


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:태그의 href 값다음 기사:태그의 href 값