This is the 18th day of my participation in Gwen Challenge

No foreword, let’s cut to the chase this time!

The idea is as shown in the figure above

Object.defineproperty () is used to define attributes of an Object.

  1. Which object to add a property to
  2. What is the name of the property to be added
  3. Corresponding to the property namevalueWhat is the value

It happens that these three points correspond to its three required parameters:

let obj = {}
Object.defineProperty(obj, 'name', {
	value: 'Alice'
});
console.log(obj.name)//Alice
Copy the code

In the above code, means to add a property name to the obj object with the value Alice. One of the things that doesn’t work is why it’s {value:’Alice’} instead of ‘Alice’, but I’ll get to that later!

DefineProperty (obj, prop, Descriptor) is mandatory. If the parameters are missing or incorrectly formatted, an error will be reported! TypeError: Property description must be an object: undefined TypeError: Property description must be an object: undefined

But usually we use it. To add attributes to an object, or to change the value of an existing attribute, for example:

let obj = {}
obj.name = 'alice'
console.log(obj.name)//alice
Copy the code

The above code implements the same function as the previous code, which adds a property name to the obj object with the value Alice

At this point you may be led by a big question, since it can be used. Instead of object.defineProperty (), is it unnecessary to use Object.defineProperty()?

You should understand that every grammar has its own usage situation, the committee is not sb! Normally, there is no need to use Object.defineProperty() if you are just giving a value to an attribute of an Object. The form of the attribute = XXX is fine. But if you configure a property with some features, it can come into play!

The third argument to Object.defineProperty() is actually some configuration corresponding to the property, also known as the property descriptor, in which the property value in the example is one of the configurations. You must have a question: What else is there besides the value configuration? I’ll answer that later.

Note that attribute values added using Object.defineProperty() are immutable by default. For example, I modify attributes added by defineProperty in two ways:

  1. DefineProperty () :Uncaught TypeError: Cannot defineProperty: XXX;

  2. If you try to modify a property added with Object.defineProperty() as an Object.attribute = XXX, there are no syntax errors, but when accessed again, the result will still be the value defined before Object.defineProperty()

let obj = {}
Object.defineProperty(obj, 'name', {
	value: 'alice'
});
obj.name ='tom'
console.log(obj.name)//alice
Copy the code

In the above code, change the corresponding value again with obj.name=’ Tom ‘, accessing Alice as defined before Object.defineProperty();

In both cases, attribute values added using Object.defineProperty() are immutable by default

DefineProperty () ¶ If a property is defined first, it can be modified via object.defineProperty (). If the configuration is not modified, it can be modified through the Object. Attribute = XXX or modified again via Object.defineProperty()

let obj = {}
obj.name ='lbj'
console.log(obj.name)//lbj
Object.defineProperty(obj, 'name', {
	value: 'alice'
});
console.log(obj.name)//alice
obj.name ='tom'
console.log(obj.name)//tom
Object.defineProperty(obj, 'name', {
	value: 'aaa'
});
console.log(obj.name)//aaa
Copy the code

In the above code, because this attribute is present from the beginning, it can be changed repeatedly either by obj.name= XXX or with Object.defineProperty()

You might think, wow, how did that happen? In fact, don’t think too much about it, this is the mechanism behind it, just remember it.

To answer that question, what other configuration items are in the property description besides value?

Here’s a dry quote:

There are two main types of property descriptors that currently exist in objects: data descriptors and access descriptors. A data descriptor is a property with a value that can be writable or unwritable. Access descriptors are properties described by getter and setter functions. A descriptor can only be one of these two; You can’t be both.

In fact, both descriptors are objects. They share the following optional key values

  1. configurable

Indicates configurable. The default value is false. When the value is true, the descriptor of the property can be changed and the property can be deleted from the corresponding object

  1. enumerable

Represents enumerable and defaults to false; When set to true, this property is enumerated during object enumeration

In addition to the optional key values of Doubly and Enumerable, the data descriptor provides two optional keys:

  1. value

Represents the value of the property, undefined by default

  1. writable

Writable. The assignment operator can change the property value only when writable is true. The default value is false, so property values added using Object.defineProperty() are immutable by default

The access descriptor is not ill-treated and also has the following optional key values: get and set methods

  1. get

When the property is obtained, the get function is executed, and the property value is the return value of the get function, as follows

let obj = {}
Object.defineProperty(obj, 'name', {
	configurable: true.enumerable: true.get: function () {
		console.log('You accessed the obj.name attribute);
		return 'tom'; }})console.log(obj.name)
Copy the code

If get does not return a value, the default value is undefined. Get does not pass in any arguments. Note that: The “this” in it usually refers to that object, but not necessarily!

  1. set

The set function is called when an object’s properties are modified, for example

let obj = {}
Object.defineProperty(obj, 'name', {
	configurable: true.enumerable: true.set: function (val) {
		console.log('Set the value of obj.name to:${val}`)
	}
})
obj.name = 'aaa'//
Copy the code

In the code above, set obj.name to aaa. By default, the set aaa is passed as the first argument to the set function, which prints: set obj.name to aaa

So we can do all sorts of things with object.defineProperty. One of the most famous is the responsive data system in Vue2, which is implemented via Object.defineProperty! The principle is very simple, is through the set and get monitoring data changes, when the data changes, can notify the page to do update and other operations!

At this point, you should have a new understanding of Object.defineProperty. If there is no doubt, let me conclude by saying:

Object.defineproperty is used to define the value of an Object attribute. It takes three arguments: obj, prop, descriptor; Represents the object to which the property is added, the name of the property to be defined, and the configuration description of the property, the most important of which is the configuration description. There are two types: data descriptors and access descriptors

  • Data descriptors can have:

Different, Enumerable, Value, Writable

  • Access descriptors can have:

Different, Enumerable, GET, set

The default values of Doubly, Enumerable and writable are false. The default value of value, get, and set is undefined

A descriptor is considered a data descriptor if it does not have any of the keys of value, writable, GET, and set. If a descriptor has both value or writable and get or set keys, an error is reported, meaning that the two unique keys cannot be mixed

The return value of object.defineProperty () is the Object to which the attribute is to be added, which is the first argument

END~

A no-table experience: As long as the message is clear, it should be easy to read