One of the new feature from the ECMAScript 2017 specification for JavaScript is the getOwnPropertyDescriptors
method. In a nutshell, this method returns the information for all properties of the given object including the information about getters and setters. It allow us to create copies of objects and clone it while copying all properties, including the getters and setters.
In JavaScript, we can create special properties that behave as methods inside the object and behave as a property outside of it. They are called get
and set
.
// object with get and set properties
const gator = {
name: 'Ben',
type: 'reptilian',
get fullName(){
return `${this.name}${this.type}`;
},
set gatorName(name){
this.name = name;
}
};
If we do console.log(gator)
we’ll get only the name and the type. Yet, we still have the access to the getter fullName, despite the fact it’s not visible in the console.
console.log(gator) // {name: 'Ben', type: 'reptilian',}
console.log(gator.fullName) // 'Benreptilian'
Notice we call the getter like it was a usual property, not a method.
We use Object.assign()
to clone objects in javaScript. If you’re not familiar with the Object.assign method, please read the article about how to manage objects in JavaScript. The main issue with this method is when we clone objects the result is not exactly as we’re expecting. The method is not working with getters and setters.
const cayman = {Object.assign({}, gator};
console.log(cayman) // {name: 'Ben', type: 'reptilian', fullName: Benreptilian, gatorName: undefined }
So the getter and setter became usual values. And if getter is a countered value, the setter will be undefined.
Let’s clone the object with the getOwnPropertyDescriptors
method instead.
const crocodilian = Object.defineProperties({}, Object.getOwnPropertyDescriptors(gator)));
And now let’s compare the descriptors of each object we have:
console.log(Object.getOwnPropertyDescriptors(gator));
/* name: {value:'Ben', writable: true, enumerable: true, configurable: true},
type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
fullName: {get: f, set: undefined, enumerable: '', configurable: ''},
gatorName: {get: undefined, set: f, enumerable: '', configurable: ''},
*/
console.log(Object.getOwnPropertyDescriptors(cayman));
/* name: {value:'Ben', writable: true, enumerable: true, configurable: true},
type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
fullName: {value: 'Benreptilian', writable: true, enumerable: '', configurable: ''},
gatorName: {value: undefined, writable: true, enumerable: '', configurable: ''},
*/
console.log(Object.getOwnPropertyDescriptors(crocodilian));
/* name: {value:'Ben', writable: true, enumerable: true, configurable: true},
type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
fullName: {get: f, set: undefined, enumerable: '', configurable: ''},
gatorName: {get: undefined, set: f, enumerable: '', configurable: ''},
*/
gator
’s object properties name
and type
are defined as usual properties, but fullName and gatorName are defined as getter and setter. They have no value
field, but have get
and set
fields. cayman
’s object getter and setter are described now as usual values. And with the crocodilian
object we manage to save its getters and setters, thanks to getOwnPropertyDescriptors
.
The getOwnPropertyDescriptors
method helps to avoid data loss and with it we can create deep copies of objects without relying on another utility function.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!