This article brings you relevant knowledge about JavaScript, which mainly introduces related issues about object-oriented, including attribute descriptors, data descriptors, access descriptors, etc. Let’s take a look at it together. I hope Helpful to everyone.
[Related recommendations: javascript video tutorial, web front-end]
JavaScript actually supports a variety of programming paradigms, including functional programming and object-oriented programming:
Objects in JavaScript are designed as an unordered collection of attributes , like a hip-hop table, consisting of keys and values;
The key is an identifier name, and the value can be of any type, or other object or function type;
If the value is a function, then we can call it a method of the object ;
The most common way to create objects in the early days is to use the Object class, and use the new keyword to create an object, and then store the properties or methods into the object:
var obj = new Object() obj.name = 'why' console.log(obj.name, obj) // why { name: 'why' }
Later, for the sake of convenience, many developers created objects directly in the form of literals:
//Literal method var obj2 = { name: 'jam', age: '8' } console.log(obj) // { name: 'jam', age: '8' }
Previously, our properties were directly defined inside the object, or added directly to the object;
But in this way we cannot impose some restrictions on this attribute: for example, can this attribute be deleted through delect
, and can it be traversed during for-in
traversal?
If we want to have more precise operational control over an attribute, then I can use attribute descriptors . The properties of an object can be accurately added or modified through property descriptors;
Property descriptors need to use Object.defineProperty
to add or modify properties.
属性描述符分为两种:数据描述符和存取描述符
A data descriptor is a property with a value that may or may not be writable. The data descriptor has the following optional key values:
value: The value corresponding to this attribute. Can be any valid JavaScript value (numeric value, object, function, etc.). The default is undefined.
writable: If and only if the writable of this attribute is true, the value can be changed by the copy operator. The default is false.
configurable: If and only if the attribute's configurable is true, the attribute descriptor can be changed, and the attribute can also be deleted from the corresponding object. The default is false.
enumerable: If and only if the enumerable of the property is true, the property can appear in the enumeration property of the object. The default is false.
The Object.getOwnPropertyDescriptor() method returns the property descriptor corresponding to an own property on the specified object.
Object.getOwnPropertyDescriptor(obj, prop)
obj: the target object to be found
prop: attribute name in the target object (String type).
Return value: If the specified property exists on the object, its property descriptor object is returned, otherwise undefined is returned.
Note: If the first parameter of this method is not an object, an error (TypeError) will be reported.
The Object.defineProperty() method directly defines a new property on an object, or modifies an existing property of an object, and returns the object.
Object.defineProperty(obj, prop, descriptor)
obj: The object on which the properties are to be defined.
prop: The name of the property to be defined or modified.
descriptor: the attribute descriptor to be defined or modified
Return value: the object passed to the function
The following sample code shows the setting and obtaining of attribute descriptors var obj = { name: 'jam', age: 8 } Object.defineProperty(obj, 'job', { value: 'lawyer' }) console.log(Object.getOwnPropertyDescriptor(obj, 'age')) // { value: 8, writable: true, enumerable: true, configurable: true } console.log(obj.job) // Lawyer // New property through defineProperty, this new property is non-modifiable, non-deletable and non-enumerable console.log(Object.getOwnPropertyDescriptor(obj, 'job')) / / {value: 'Lawyer', writable: false, enumerable: false, configurable: false}
注意:通过defineProperty新增的属性,该新属性是不可修改、不可删除以及不可枚举的
var obj = { name: 'jam', age: 8 } Object.defineProperty(obj, 'address', { value: 'Hebei', // configurable This property cannot be deleted, nor can you use defineProperty to modify the property descriptor again configurable: false, }) delete obj.address // I want to use delete to delete this attribute obj.address = 'Guangzhou' // I want to modify the attribute address value in obj to Guangzhou console.log(obj.address) // Output result: Hebei
Because the attribute descriptor configurable value is false and cannot be deleted or modified, deletion and modification will not take effect.
var obj = { name: 'jam', age: 8}Object.defineProperty(obj, 'sex ', { value: 'Male', // enumerable configures whether this property can be enumerated enumerable: true})for (i in obj) { console.log(i)}
When enumerable: false, the output result is name age
When enumerable: true, the output result is name age sex
var obj = { name: 'jam', age: 8}Object.defineProperty(obj, 'score', { value: 80, // writable: true writable: false})obj.score = 100 console.log(obj.score) // 80
Because the value of writeable is false, when the score is modified to 100, the modification is not successful, and the final output is 80.
Do you feel that it is cumbersome to set the property descriptor of only one property at a time? Object.defineProperties can help you solve the problem.
The Object.defineProperties() method defines one or more new properties or modifies existing properties for an object, and returns the object.
Object.defineProperties(obj, props)
obj: The object on which the properties are to be defined.
props: The object whose enumerable properties or modified property descriptors are to be defined.
Return value: The object passed to the function.
The sample code is as follows:
var obj = { name: 'jam',}Object.defineProperties(obj, { 'age': { value: 28, writable: true, configurable: false, enumerable: true }, 'job': { value: 'lawyer', writable: true, configurable: false, enumerable: true }, 'sex': { value: 'Male', writable: false, configurable: false, enumerable: true }, 'height': { value: '1.8 m', writable: false, configurable: false, enumerable: true }})console.log(obj) // name: 'jam', age: 28, job: 'lawyer', sex: 'male', height: '1.8m' }
Access descriptors are properties described by getter-setter function pairs. The access descriptor has the following optional key values:
get: Provides a getter method for the property. If there is no getter, it is undefined. When this property is accessed, the method will be executed. No parameters are passed in when the method is executed, but the this object will be passed in.
set: Provides a setter method for the property. If there is no setter, it will be undefined. This method is triggered when the property value is modified. This method will accept the only parameter, which is the new parameter value of the property.
configurable: If and only if the attribute's configurable is true, the attribute descriptor can be changed, and the attribute can also be deleted from the corresponding object. The default is false.
Enurnerable: If and only if the enurnerable of the attribute is true, the attribute can appear in the enumeration attribute of the object. The default is false.
The use of configurable and enurnerable is consistent with that in data descriptors, so I won’t explain them in detail here.
Mainly talk about the use of get and set methods
var obj = { name: 'jam', age: 8, _address: 'Hebei' } // Usage scenarios of access descriptors // 1. Hide a certain private attribute that is expected to be directly used and assigned by the outside world // 2. If we want to understand the process of accessing and setting the value of a certain attribute, we will also use it Storage property descriptor Object.defineProperty(obj, 'address', { enumerable: true, configurable: true, get: function () { foo() return this._address }, set: function (value) { bar() this._address = value } }) function foo () { console.log("Intercepted the value of address once") } function bar () { console.log("The value of address is set once") }
The above sample code console prints the following results: