In addition to ordinary object property assignment and traversal, we can also perform many other operations using JavaScript objects. In this article, we'll learn how to use them, including accessing internal properties, manipulating property descriptors, and inheriting read-only properties.
1. Access internal properties
JavaScript objects have internal properties that cannot be accessed in a conventional way. Internal property names are enclosed in square brackets [[]] and are available when creating an object.
Internal properties cannot be added dynamically to existing objects.
Internal properties can be used in some built-in JavaScript objects, which store internal state specified by the ECMAScript specification.
There are two internal properties, one is a method for operating objects, and the other is a method for storing data. For example:
[[Prototype]] — The prototype of the object, which can be null or the object
[[Extensible]] — Indicates whether it is allowed Dynamically add new properties to the object
[[PrivateFieldValues]] — used to manage private class fields
2. Property descriptor object
The data attribute contains the location of a data value from which the value can be read and written. In other words, data attributes can be accessed through Object.Attributes, which means that they will return whatever values are assigned by the users we usually interact with, and they will not do anything extra.
The data attribute has 4 characteristics that describe its behavior (in order to represent the internal value, the attribute is placed in two square brackets), which is called a descriptor object.
The value descriptor is the data value of the attribute. For example, we have the following object:
let foo = { a: 1}
Then, the value attribute descriptor of a is 1.
Writable refers to whether the value of the attribute can be changed. The default value is true, which means the property is writable. However, we can make it unwritable in a number of ways.
Configurable means that the properties of an object can be deleted or its property descriptors can be changed. The default value is true, which means it is configurable.
enumerable means it can be traversed by for...in loop. The default value is true, which means that the property can be returned through a for-in loop.
Before adding the property key to the returned array, the Object.keys method also checks the enumerable descriptor. However, the Reflect.ownKeys method does not check this property descriptor and instead returns all own property keys.
Prototype descriptor has other methods, get and set are used to get and set values respectively.
When creating a new object, we can use the Object.defineProperty method to set the descriptor, as shown below:
let foo = { a: 1}Object.defineProperty(foo, 'b', { value: 2, writable: true, enumerable: true, configurable: true,});
The new value of foo is {a: 1, b: 2} .
We can also use defineProperty to change the descriptor of an existing property. For example:
let foo = { a: 1}Object.defineProperty(foo, 'a', { value: 2, writable: false, enumerable: true, configurable: true,});
So when we try to assign a value to foo.a, such as:
foo.a = 2;
If strict mode is turned off, the browser will ignore it, otherwise it will throw an error because we will writable is set to false, indicating that the property is not writable.
We can also use defineProperty to convert the property into a getter, as shown below:
'use strict'let foo = { a: 1}Object.defineProperty(foo, 'b', { get() { return 1; } })
When we write like this:
foo.b = 2;
Because the b property is a getter property, when using strict mode, we get an error: Getter properties cannot be reassigned.
3. Inherited read-only properties cannot be assigned
Inherited read-only properties cannot be assigned. This makes sense, since we set it up like this, it is inherited, so it should be propagated to the object that inherits the property.
We can use Object.create to create an object that inherits properties from the prototype object, as shown below:
const proto = Object.defineProperties({}, { a: { value: 1, writable: false }})const foo = Object.create(proto)
In the above code, we set the writable descriptor of proto.a to false, so we cannot assign another value to it.
If we write like this:
foo.a = 2;
In strict mode, we will get an error message.
Summary
We can do a lot of things with JavaScript objects that we may not know about.
First of all, some JavaScript objects (such as the built-in browser object) have internal properties, which are surrounded by double square brackets. They have internal state that cannot be added dynamically by object creation.
JavaScript object properties also have property descriptors, which allow us to control their values and whether they can be set, or whether their property descriptors can be changed, etc.
We can use defineProperty to change the property descriptor of a property, it is also used to add new properties and their property descriptors.
Finally, the inherited read-only property remains read-only, which makes sense since it is inherited from the parent prototype object.
Recommended tutorial: "javascript tutorial"
The above is the detailed content of A few things you can do with JavaScript objects. For more information, please follow other related articles on the PHP Chinese website!