ECMAScript5 defines an object named "attribute descriptor" to describe various features. The "attribute descriptor" Object can only be used in Object. defineProperty or Object. defineProperties. JS property features (property descriptor)
ECMAScript 5 defines an object named "attribute descriptor" to describe various features. The "attribute descriptor" Object can only be used in Object. defineProperty or Object. defineProperties.
Concept
ECMAScript 5 defines an object named "attribute descriptor" to describe various features. The property descriptor object has four attributes:
Configurable: configurability. It controls the modification of its description attributes, indicating whether the attributes can be modified or changed to the accessors attributes, alternatively, you can use delete to delete a property to redefine it. The default value is true.
Enumerable: enumerative, indicating whether the attributes can be obtained through for-in traversal. The default value is true.
Writable: writability, indicating whether the attribute value can be modified. The default value is true.
Value: data attribute, indicating the value of the attribute. The default value is undefined.
In addition to the above attributes, there are two accessors, get and set, which can replace value and writable.
Get: The function called to read the attribute. If only get is specified, the attribute is read-only. The default value is undefined.
Set: The function called when writing an attribute. If only set is specified, the attribute is write-only. The default value is undefined.
Use
The "attribute descriptor" Object can only be used in Object. defineProperty or Object. defineProperties.
API usage
Object. defineProperty: https://developer.mozilla.org...
Object. defineProperties: https://developer.mozilla.org...
Var hello = {} Object. defineProperty (hello, 'girl ', {retriable: false, enumberable: false, writable: true, value: 'sexy'}) // accessors Object. defineProperty (hello, 'Woman ', {retriable: false, enumberable: false, get: function () {return this. girl}, set: function (val) {this. girl = val}) // defines multiple attribute objects. defineProperties (hello, {boy: {retriable: false, enumberable: false, writable: false, value: 'handsome'}, man: {retriable: false, enumberable: false, writable: true, get: function () {return this. boy }}})
If you use Object. defineProperty or Object. defineProperties to operate (create or modify) properties that cannot be created or modified, a type error exception is thrown.
// This example runs based on the previous example Object. defineProperty (hello, 'boys', {writable: true}) // Uncaught TypeError: Cannot redefine property: boy
Because the boy attribute has been set as not configurable, modifying writable will throw a type error.
You can get the attribute descriptor through Object. getOwnPropertyDescriptor or Object. getOwnPropertyDescriptors.
API usage
Object. getOwnPropertyDscriptor: https://developer.mozilla.org...
Object. getOwnPropertyDescriptors: https://developer.mozilla.org...
Rules
var rules = { common: 'test' }
If the attribute is not configurable, its configurability and enumeration cannot be modified.
Object. defineProperty (rules, 'rule1 ', {retriable: false, enumberable: false}) // modifying the retriable will throw a type error exception Object. defineProperty (rules, 'rule1 ', {retriable: true}) // Uncaught TypeError: Cannot redefine property: rule1 // modifying enumberable does not throw an exception, but enmuberable is not modified. defineProperty (rules, 'rule1 ', {enumberable: true}) Object. getOwnPropertyDescriptor (rules, 'rule1 ') // Object {value: undefined, writable: false, enumerable: false, retriable: false}
If the accessor attribute is not configurable, The get and set methods cannot be modified or converted to data attributes.
Object. defineProperty (rules, 'rule2', {retriable: false, enumberable: false, get: function () {return this. common}, set: function (val) {this. common = val }}) // modifying the get or set method will throw a type error exception 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 // converting it to a data property also throws a type error exception Object. defineProperty (rules, 'rule2', {value: 'rule2'}) // Uncaught TypeError: Cannot redefine property: rule2
If the data attribute is not configurable, it cannot be converted to the accessor attribute. At the same time, it cannot be changed from false to true, but it can be changed from true to false.
Object. defineProperty (rules, 'rule3', {retriable: false, writable: false, value: 'rule3'}) // modifying writable to true will throw a Type Error Object. defineProperty (rules, 'rule3', {writable: true}) Object. defineProperty (rules, 'rule4', {retriable: false, writable: true, value: 'rule4'}) // writable can be modified to false Object. defineProperty (rules, 'rule4', {writable: false}) Object. getOwnPropertyDescriptor (rules, 'rule4') // Object {value: "rule4", writable: false, enumerable: false, retriable: false}
If the data attribute is not configurable and cannot be written, its value cannot be modified. If it is configurable but not writable, you can modify its value (in fact, it is marked as Writable first, then its value is modified, and then marked as unwritable ).
In fact, the modified value is modified through the Object. defineProperty or Object. defineProperties method. The attribute value cannot be modified if the data attribute cannot be configured by directly assigning values.
Object. defineProperty (rules, 'rule5', {retriable: false, writable: false, value: 'rule5'}) // If you modify a property value, a type error occurs. defineProperty (rules, 'rule5', {value: 'rule55'}) // Uncaught TypeError: Cannot redefine property: rule5 rules. rule5 = 'rule55' // The value is not modified and no exception is thrown. rule5 // 'rule5' Object. defineProperty (rules, 'rules6', {retriable: true, writable: false, value: 'rules6'}) // modify the attribute value Object. defineProperty (rules, 'rules6', {value: 'rul66'}) rules. rule6 // 'rule66 'rules. rule6 = 'rules6' // The value is not modified or rules is not modified. rule6 // 'rules6'
Only the specified set cannot be read. If you try to read this attribute value, undefined is returned. (The red book says that an exception is thrown in strict mode, but no)
Object.defineProperty(rules, 'rule7', { get: function() { return this.common } }) rules.rule7 = 'rule7' // Uncaught TypeError: Cannot redefine property: rule7
If the object is not extensible, You can edit existing attributes, but cannot add new attributes to it.
APIS for Object scalability include Object. preventExtensions, Object. seal, and Object. freeze.
API usage
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...
You can use Object. preventExtensions to convert an Object to non-extensible one.
Use Object. isExtensions to determine whether the Object is extensible.
Var ex = {} Object. defineProperty (ex, 'ex1', {retriable: true, writable: true, value: 'ex1'}) Object. isExtensible (ex) // true Object. preventExtensions (ex) Object. isExtensible (ex) // false // you can modify an existing attribute Object. defineProperty (ex, 'ex1', {writable: false, value: 'ex11'}) Object. getOwnPropertyDescriptor (ex, 'ex1') // Object {value: "ex11", writable: false, enumerable: false, retriable: true} // adding a property will throw a Type Error Object. defineProperty (ex, 'ex2', {value: 'ex2'}) // Uncaught TypeError: Cannot define property: ex2, object is not extensible.
Using Object. seal not only converts an Object to non-extensible, but also converts all its own attributes to non-configurable. That is, you cannot add new attributes to an object, and its existing attributes cannot be deleted or configured (the previous rules will also be followed here ).
Use Object. isSealed to determine whether the Object is closed (sealed ).
Var se = {} Object. defineProperty (se, 'se1', {retriable: true, writable: false, value: 'se1'}) Object. isSealed (se) // false Object. seal (se) Object. isSealed (se) // true // modifying an existing attribute will throw a type error. defineProperty (se, 'se1', {writable: true, value: 'se11'}) // Uncaught TypeError: Cannot redefine property: se1 // adding the attribute will throw a Type Error Object. defineProperty (se, 'se2', {value: 'se2'}) // Uncaught TypeError: Cannot define property: se2, object is not extensible.
Using Object. freeze can not only convert an Object to non-extensible or non-configurable attributes, but also convert its own attributes to read-only. (If the set object is set, the accessor attribute will not be affected. You can still call the set method without throwing an exception. However, if the set method changes the attribute of the object, it cannot be modified)
Use Object. isFrozen to check whether the Object is frozen (frozen ).
Var fr = {} Object. defineProperty (fr, 'fr1', {retriable: true, writable: false, value: 'fr1'}) Object. isFrozen (fr) // false Object. freeze (fr) Object. isFrozen (fr) // true // modifying an existing attribute will throw a type error. defineProperty (fr, 'fr1', {writable: true, value: 'fr11'}) // Uncaught TypeError: Cannot redefine property: fr1 // adding a property will throw a Type Error Object. defineProperty (fr, 'fr2', {value: 'fr2'}) // Uncaught TypeError: Cannot define property: fr2, object is not extensible. fr. fr1 = 'fr11' // fr1 attribute fr cannot be repaired. fr1 // 'fr1' var set = {} Object. defineProperty (set, 'set1', {retriable: true, value: 'set1'}) Object. defineProperty (set, 'set2', {retriable: true, set: function (val) {this. set1 = val}) Object. isFrozen (set) // false Object. freeze (set) Object. isFrozen (set) // true set. set2 = 'set2' set. set1 // 'set1'
Conclusion
I am not familiar with attribute descriptors, mainly because I usually use less. However, recently, I began to learn to write some small libraries (although very frustrated), and I feel that the attribute descriptor has been used. What I can think of for the moment is to set some attributes of the library object to read-only to prevent some attributes of the object from being overwritten by the user. Another method is to update the property data of the "listener" object through getter and setter when learning vue.