Today, we will talk about Object. DefineProperty this method, learn vUE people all know, vUE hijacking principle is through this method for data interception, if you want to understand the principle of VUE, Object. DefineProperty is inevitable.

Let’s start with the syntax

define

Object.defineproperty defines a new property on an Object or modifies an existing property.

usage

/** * @param {Object} target Target Object whose properties are to be defined or modified * @param {String} propName Name of the property to be defined or modified * @param {Object} Descriptor */ object.defineProperty (target, propName, descriptor);Copy the code

I’m not going to go into target and name, but I’m going to go into desc.

The descriptor

Object.defineproperty () descriptors fall into two categories: the first is called data descriptors, which are used to specify restrictions on data, such as whether it can be modified, enumerated (iterated), deleted/modified, etc. The second type is called memory descriptor (accessor descriptor), used to obtain and modify data to explain, such as when I call the data I need to return what kind of data, the data needs to be modified according to what kind of logical modification. There are four data descriptors, which are value, writable, Enumerable, and different. There are two operation descriptors, get and set.

value

Value is the value of the property to be defined/modified, or as I prefer to call it, the default value.

Object.defineProperty(window, "name", {
    value: 'Joe'
});
console.log(window.name); // 'Joe'
Copy the code

For example, if I want to define a property called name in the global property window object, I can use this code, which is equivalent to var name = ‘span three ‘; But there’s a little bit of a difference, so don’t worry, I’ll go on, you go on, and I’ll tell you what the difference is in a second.

writable

Writable determines whether the property can be reassigned, which defaults to false when defined with object.defineProperty () and true when defined with var name = ‘three’.

Object.defineProperty(window, "name", {
    value: 'Joe'
});
window.name = 'bill'; console.log(window.name); / / zhang SAN Object. DefineProperty (window,"age", {
    value: 15,
    writable: true}); window.age = 20; console.log(window.age); / / 20Copy the code

As we can see from the two above, this property is not modifiable by default, and when we set writable to true, this property prints our new input value.

var name = 'Joe';
name = 'bill'; console.log(name); / / li siCopy the code

Considering that a variable can be changed at any time, we can assume that the default writable value of the attribute defined by the expression is true, which is one of the remaining differences. Let’s verify that.

Object.defineProperty(window, "name", {
    value: 'Joe'
});
var age = 12;
console.log(Object.getOwnPropertyDescriptor(window, 'name')); // {value: "Zhang", writable: false, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(window, 'age')); // {value: 12, writable: true, enumerable: true, configurable: false}
Copy the code

With the Object. GetOwnPropertyDescriptor () to view the specific value of the descriptor, the grammar I will detail below, now need not too entanglements, just know that the method can obtain the value the specific value of the descriptor. We can see that the writable of a property defined with var is true, while that defined with object.defineProperty is false. Can we think of constants here, and can the definition of constants also be defined by this descriptor? I’ll leave it to you to think about, but I won’t go into detail here.

enumerable

Enumerable determines whether the property’s value can be enumerated. True means it can be enumerated, false means it can’t be enumerated. Properties defined in object.defineProperty () default to false, and expression formats default to true.

var obj = {a: 1, b: 2}
Object.defineProperty(obj, 'c', {
  value: 3,
  enumerable:false
});
console.log(obj); // {a: 1, b: 2, c: 3}
for (let key inobj) {console.log(key)}; // a, b console.log(Object.keys(obj)); / / /'a'.'b']
Copy the code

We see that when we set Enumerable to false, no matter how we use for… In or object.keys (), you can’t get c when enumerable is set to true.

configurable

The target properties can be deleted, and the configured descriptor can be modified without additional information. The default value is false.

var a = 100;
delete a;
console.log(a); // 100

var obj = {};
Object.defineProperty(obj, 'a', { value: 100 }); delete obj.a; console.log(obj.a); / / 100Copy the code

get

Get is the method used to get the value of the property.

var obj = {};
Object.defineProperty(obj, 'a', {
  get () {
    return 100;
  }
});
console.log(obj.a); // 100
Copy the code

Note that get cannot coexist with a different information, otherwise an error will be reported.

set

Set is the method used to modify the value of the property.

var obj = {};
var value = 100;
Object.defineProperty(obj, 'a', {
  get () {
    return value;
  },
  set (val) {
    value = val;
  }
});
console.log(obj.a); // 100
obj.a = 99;
console.log(obj.a); // 99
Copy the code

Note that the set, like the get, cannot coexist with a different information, otherwise an error will be reported.

conclusion

1. Value: default value of the attribute to be defined/modified

2, writable: Determines whether the value can be modified

Enumerable: Determines whether a value can be enumerated

4, freely: Determines whether values can be deleted or other descriptors can be modified

5. Get: It is used to obtain the value of this property and cannot coexist with a different information

6. Set: Sets the value of this property, and it cannot coexist with a different information