DefineProperty and defineProperties of Object are very important in JS, Main function is used to define or modify these internal attributes, and at the same time getOwnPropertyDescriptor and getOwnPropertyDescriptors line is access to the description of the internal properties.

Article below I first introduce descriptors and data access descriptor attributes represent meaning, then simply introduces the basic function of the four methods mentioned above, these if know can skip, at last I’ll extension and an example shows that the internal properties under various scenarios of actual effect, that is the core content of this article. This article will try to use advanced javaScript tutorial, MDN website and other concepts to ensure accurate and easy to understand. The part of the explanation will combine personal understanding and examples.


Data (data descriptor) properties

Data properties have four features that describe internal properties

[[Configurable]]

Indicates whether the property can be deleted by delete, whether the property can be modified, or whether the property can be modified to an accessor property. The default value is true if the object is defined directly using a literal.

[[Enumerable]]

Indicates whether the property is enumerable, that is, whether the property is returned via a for-in loop or object.keys (). The default value is true if the Object is defined directly using a literal

[[Writable]]

Can change the value of an attribute. If you define an object directly using a literal, the default value is true

[[Value]]

The value of this property is undefined by default


Accessor (access descriptor) properties

Accessor properties also have four features that describe internal properties

[[Configurable]]

Like the [[64x]] of a data attribute, it indicates that the property can be deleted through delete, its features can be modified, and the property can be modified to an accessor property. The default value is true if the object is specified using a different token

[[Enumerable]]

Like the [[64x]] of a data attribute, it indicates whether the attribute is enumerable, whether it is returned via a for-in loop or object.keys (). The default value is true if the Object is specified using a different literal

[[GET]]

A method that provides a getter for a property (the function called when accessing an object property and returns the value of the current property), undefined if there is no getter. The value returned by this method is used as the attribute value. The default value is undefined

[[SET]]

A method that provides a setter for a property (the function called when setting a value for an object property), undefined if there is no setter. This method takes a unique parameter and assigns a new value for that parameter to the property. The default value is undefined


Methods to create/modify/get properties


YI, Object. DefineProperty ()

Function: Methods directly define a new property on an object, or modify an existing property of an object, and return the object. If no additional information is specified, the default value of these properties is false, and if no additional information is specified, the default value of these properties is undefined. DefineProperty (obj, prop, Descriptor) Obj: target Object to be operated on. Prop: Attribute name descriptor of the target Object to be defined or modified. Descriptor: Attribute descriptor to be defined or modified

var obj = new Object(); Object.defineProperty(obj, 'name', { configurable: false, writable: true, enumerable: true, value: }) console.log(obj.name) // Console. log(obj.name) // console.log(obj.nameCopy the code
ER, Object. DefineProperties ()

Function: A method directly defines one or more new properties or modifies existing properties on an object and returns the object. Object. DefineProperties (obj,props) obj: The Object to which attributes are to be added or modified. Props: One or more key-value pairs of this object define the specific configuration of the properties to be added or modified for the object

var obj = new Object(); Object. DefineProperties (obj, {name: {value: 'cx ', 64x: false, writable: true, Enumerable: true}, age: 64x: different} {value: 64x, different: true}}) console.log(64x, 64x, 64x, 64x, 64X, 64X, 64X, 64X, 64X, 64XCopy the code
SAN, Object. GetOwnPropertyDescriptor ()

Function: the method returns a specified Object has its own properties corresponding to the property description (self-owned property refers to the directly gives the Object’s properties, don’t need to look up from the prototype chain properties) syntax: Object. GetOwnPropertyDescriptor (obj, prop) / / obj. Prop: indicates the name of the property in the target object

Var person = {name: 'zhang' age: 18} var desc = Object. GetOwnPropertyDescriptor (person, 'name'); // {// different: true, // enumerable: true, // writable: true, // value: "64x" //}Copy the code

SI, Object. GetOwnPropertyDescriptors ()

Function: A descriptor for all of the specified object’s own properties, or returns an empty object if there are none. Grammar: Object. GetOwnPropertyDescriptors (obj) / / obj: need to find the target Object

Var person = {name: 'zhang' age: 18} var desc = Object. GetOwnPropertyDescriptors (person); console.log(desc) // age: { // value: 18, writable: true, enumerable: true, configurable: true} // name: { // value: Writable: true, enumerable: true, different: true} // __proto__: ObjectCopy the code

Extended example description of descriptor properties in various scenarios

.configurable

If the 64x property is set to false, the Delete operator cannot be used. Modifying all the internal property values throws an error

Adds a data descriptor property to the object
var person = {}; Object.defineProperty(person, 'name', { configurable: false, value: 'John' }) ; Delete person.name // Strict mode throws error console.log(person.name) // 'John' does not delete Object.defineProperty(person, 'name', {different: true // error}); Object.defineproperty (person, 'name', {enumerable: 2}); Object.defineproperty (person, 'name', {writable: true // error}); Object.defineproperty (person, 'name', {value: 2 // error});Copy the code

[[writable]] [[value]] [[value]] [[value]] [[value]] [[value]] [[value]] [[value]] [[value]] [[value]] [[value]] [[value]]

var obj = {}; Object.defineProperty(obj, 'a', { configurable: false, writable: true, value: 1 }); DefineProperty (obj, 'A ', {// different: true, // error // enumerable: true, writable: false, value: 2}); var d = Object.getOwnPropertyDescriptor(obj, 'a') console.log(d); // { // value: 2, // writable: false, // }Copy the code
Adds access descriptor properties to the object
var obj = {}; var aValue; AValue is not defined var b; aValue is not defined var b; Object.defineProperty(obj, 'a', { configurable : true, enumerable : true, get: function() { return aValue }, set: function(newValue) { aValue = newValue; B = newValue + 1}}) console.log(b) // undefined console.log(obj.a) // undefined console.log(obj. Return obj. A = 2; Log (obj. A); // Set = 2 console.log(obj. A); // get = 2 console.log(b) When assigning to obj. A, the set method is executed, and b is changed to 2. Incidentally, the evaluated properties in VUE are implemented using settersCopy the code

Note:

  • Getters and setters can be used at different times, but using only one in strict mode throws an error.
  • Data descriptors and access descriptors should not be mixed, otherwise an error will be thrown.
  • Use any variable defined by varconfigurableProperty values arefalseThe same is true for defining objects.
Writable

[value] can be modified via defineProperty without any additional assignment if Writable is false and signals are true.

var obj = {}; Object.defineProperty(obj, 'a', { configurable: true, enumerable: false, writable: false, value: 1 }); Object.defineProperty(obj, 'a', { configurable: false, enumerable: true, writable: false , value: 2 }); var d = Object.getOwnPropertyDescriptor(obj, 'a') console.log(d); // enumerable: true, // different: different; // different: different; False / /} but if direct copy modified var obj = {} Object. DefineProperty (obj, 'a', {configurable: true, enumerable: false, writable: false, value: 1 }); obj.a=2; var d = Object.getOwnPropertyDescriptor(obj, 'a') console.log(d); // enumerable: true, // different: false}Copy the code
Enumerable

Let’s go straight to the example

var obj = {}; Object.defineProperties(obj, { a: { value: 1, enumerable: false }, b: { value: 2, enumerable: true }, c: { value: 3, enumerable: false } }) obj.d = 4; / / is equivalent to / / Object. DefineProperty (obj, 'd', {/ / configurable: true, / / enumerable: true, / / writable: true, / / the value: 4 //}) for(var key in obj) { console.log(key); } var arr = object.keys (obj);} var arr = object.keys (obj); console.log(arr); // ['b', 'd']Copy the code
Get and set

Easy two-way data binding

//html <body> <p> input1=> <input type="text" id="input1"> </p> <p> input2=> <input type="text" id="input2"> </p> <div> <span id="span"></span> </div> </body> //js var oInput1 = document.getelementById ('input1'); var oInput2 = document.getElementById('input2'); var oSpan = document.getElementById('span'); var obj = {}; Object.defineProperties(obj, { val1: { configurable: true, get: function() { oInput1.value = 0; oInput2.value = 0; oSpan.innerHTML = 0; return 0 }, set: function(newValue) { oInput2.value = newValue; oSpan.innerHTML = Number(newValue) ? Number(newValue) : 0 } }, val2: { configurable: true, get: function() { oInput1.value = 0; oInput2.value = 0; oSpan.innerHTML = 0; return 0 }, set: function(newValue) { oInput1.value = newValue; oSpan.innerHTML = Number(newValue)+1; } } }) oInput1.value = obj.val1; oInput1.addEventListener('keyup', function() { obj.val1 = oInput1.value; }, false) oInput2.addEventListener('keyup', function() { obj.val2 = oInput2.value; }, false)Copy the code
Original link address:Segmentfault.com/a/119000001…