Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
As we already know, objects can store properties.
Till now, we know that property is nothing but a “key-value” pair to us. But, an object’s property is much more stronger and powerful.
In this article, we will learn some additional configuration options and in the next articles, we will also learn how to invisibly turn them using getter/setter options.
There are three special attributes(also called “flags”):
writable: if this condition satisfies, then only values can be changed. Otherwise, it’s only read-only.
enumerable: if this condition is true, then only values are listed. Otherwise not listed.
configurable: if this condition is true, then the property can be deleted and modified, otherwise not.
Whenever we create a property, just the way we used to do, all the above flags are set to true by default. But we can change them anytime. First, we need to see how can we get those flags, come let’s find that out.
Here, obj is the object and propertyName is the name of the property. The descriptor is the property descriptor object.
If a property is present, defineProperty will be updating the flags. Otherwise, the property is created with provided value and flags. In other words, if a flag is not supplied, then it is assumed to be false.
Compare both the codes provided above, one with normally created and another with object declaration. We will find that all the flags are false. If we want to set their values, then change them to true.
Non-writable
By changing the writable flag, the user.name can be made non-writable.
user.name = "Peter"; // Error: Cannot assign to read only property 'name' </script>
On running the above code, errors will come. Errors will only appear in the strict mode. In the non-strict mode, when writing to non-writable properties, no errors will be occurring. Another consequence is that many flag violating actions will simply get violated.
<!DOCTYPE html> <script> "use strict";
let user = { };
Object.defineProperty(user, "name", { value: "James", // new properties need to be explicitely listed enumerable: true, configurable: true });
alert(user.name); // James user.name = "Peter"; // Error </script>
Output:
Non-enumerable
Now, let’s see how we can add custom toString to the user. The built-in function for the strings is generally enumerable. But if we create a toString on our own, then by default it shows up like this:
<!DOCTYPE html> <script> "use strict";
let user = { name: "James", toString() { returnthis.name; } };
// By default, both our properties are listed: for (let key in user) alert(key); // name, toString </script>
Output:
If you want to change it, it can be changed by writing enumerable:false. This will change the default value and you can try it on an online javascript compiler.
<!DOCTYPE html> <script> "use strict";
let user = { name: "James", toString() { returnthis.name; } };
// Now our toString disappears: for (let key in user) alert(key); // name </script>
Output:
Object.keys don’t include the enumerable properties.
Non-configurable
The presence of a non-configurable flag is very less for built-in objects and properties. Non-configurable properties can’t be modified or deleted. Math.PI is non-enumerable, non-writable, and non-configurable.
<!DOCTYPE html> <script> "use strict";
let descriptor = Object.getOwnPropertyDescriptor(Math, 'PI');
Here, the programmer will not be able to change the value of Math.PI or overwrite it. Hence, we can conclude that if any property is made non-configurable nothing can be done to it. It’s just like a one-way road. It cannot be changed back with defineProperty.
If we prefer using configurable: false, the values can be changed to some extent. Configurable: false prevents changes of property flags and deletion.
For getting all property descriptors at once, the method Object.getOwnPropertyDescriptors(obj) can be used.
If used together with object.defineProperties, it can be used as “flags-aware” way of cloning an object. Syntax for the same is:
let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));
Normally, for cloning any object, an assignment is used for copying the properties:
for (let key in user) { clone[key] = user[key] }
But, the flags cannot be copied with this. For better cloning, Object.defineProperties is used.
Sealing an object globally
At the level of individual properties, property descriptors play their roles. Access to the whole object can be restricted by some methods. Let’s look at some of them:
Object.preventExtensions(obj) : this method restricts the addition of new properties to the object.
Object.freeze(obj): this method restricts the addition or removal or modification of properties. This also resets the configurable: false and writable: false for all the existing properties.
Object.seal(obj): this method restricts the addition or removal of properties. This resets the value configurable: false for all the existing properties.
Object.isExtensible(obj): this method returns false, if addition of properties is restricted. Otherwise, returns true.
Object.isSealed(obj): this method returns true if removal or addition of new properties is forbidden and all existing properties have default value configurable: false.
Object.isFrozen(obj): this method returns true if the addition or modification or changing of new properties is restricted and the default value set is configurable: false and writable: false.
FAQs
Mention the significance of object define property? defineProperty() helps to define new properties for an object, and if already present modifies the existing one and returns the object.
Define property descriptors in Javascript? It is a simple Javascript object that is present with every object and contains information about its properties like object and its meta-data.
What are the types of object properties in Javascript? There are two types of properties in Javascript: data properties and accessor properties.
Key takeaways:
In this article, we are introduced with property flags, non-writable, non-enumerable, non-configurable, and some of the important methods like object.defineProperties, and many more. We also covered some of the frequently asked questions which you might have come to your mind while going through this article.
Keeping the theoretical knowledge at our fingertips helps us get about half the work done. To gain complete understanding, practice is a must. To achieve thorough knowledge, visit our page.