Javascript 101: Objects
Today we start by debunking a common misconception among Developers(and Spartans alike). Objects indeed are the general building block upon which much(not all) of JS is built. They do make up the eigth primary types in Javascript along with string, number, boolean, null, undefined, bigint, and Symbols. So to say that everything in Javascript stems from objects is clearly untrue. Apologies King Leonidas 😂.
But what are Objects really?
An object is a collection of properties, and a property is an association between a name (or key) and a value
In JavaScript, an object is a standalone entity, with properties and type. Compare it with a cup, for example. A cup is an object, with properties. A cup has a color, a design, weight, a material it is made of, etc. In the same way, JavaScript objects can have properties, which define their characteristics.
Objects in javascript come in two forms; declarative(literal) and constructed form.
The only difference really is that you can add one or more key/value pairs to the literal declaration, whereas with constructed-form objects, you must add the properties one by one.
In objects, property names are always strings. If you use any other value besides a string (primitive) as the property, it will first be converted to a string.
Computed Property Names
ES6 adds computed property names, where you can specify an expression, surrounded by a [ ] pair, in the key-name position of an object-literal declaration:
The perks of this feature come to light when the aim is to use a variable's value as an object’s key. This is a true testament to javascript's dynamism.
Property Descriptor
We can use Object.defineProperty(..) to add a new property or modify an existing one (if it’s configurable!), with the desired characteristics.
- Writable
The ability for you to change the value of a property is controlled by writable. - Enumerable
The name probably makes it obvious, but this characteristic controls whether a property will show up in certain object-property enumerations, such as the for..in loop. - Configurable
As long as a property is currently configurable, we can modify its descriptor definition, using the same defineProperty(..) utility: There’s a nuanced exception to be aware of: even if the property is already configurable(false), writable can always be changed from true to false without error, but not back to true if already false. Another thing configurable(false) prevents is the ability to use the delete operator to remove an existing property.
Object Immutability
Sometimes you want to make properties or objects that cannot be
changed (either by accident or intentionally). Although there are a number of ways to achieve this, It’s important to note that all of these approaches create shallow immutability. That is, they affect only the object and its direct property characteristics. Below are the ways in JS to achieve immutability
- Object constant
By combining writable: false and configurable: false, you can essentially create a constant (cannot be changed, redefined, or deleted) as an object property - Prevent Extention
If you want to prevent an object from having new properties added to it, but otherwise leave the rest of the object’s properties alone, call Object.preventExtensions(..). - Seal
Object.seal(..) creates a “sealed” object, which means it takes an existing object and essentially calls Object.preventExtensions(..) on it, but also marks all its existing properties as configurable: false. - Freeze
Object.freeze(..) creates a frozen object, which means it takes an existing object and essentially calls Object.seal(..) on it, but it also marks all “data accessor” properties as writable: false, so that their values cannot be changed.
Getters and Setters
Getters are properties that actually call a hidden function to retrieve a value. Setters are properties that actually call a hidden function to set a value. When you define a property to have either a getter or a setter or both, its definition becomes an “accessor descriptor” (as opposed to a “data descriptor”). For accessor descriptors, the value and writable characteristics of the descriptor are moot and ignored, and instead, JS considers the set and get characteristics of the property (as well as configurable and enumerable).
we created a property on the object that actually doesn’t hold a value, but whose access automatically results in a hidden function call to the getter
function, with whatever value it returns being the result of the property access. Since we only defined a getter for a, if we try to set the value of a later,
the set operation won’t throw an error but will just silently throw the
assignment away. Below is a complete getter and setter scenario which you will most likely encounter.
Conclusion
With this, we’ve come to the end of our introduction to Objects in Javascript. Objects are a critical piece and do have a lot of actions that can be carried out on them to make application creation easier in Javascript. But there is more…. In future lessons, we’ll delve deeper and examine prototypes and behavior delegation in order to fully grasp the power that lies within this seemingly primitive type. Catch ya later 👋.
PS — If you think the connection of Spartans was irrelevant to this topic… You are absolutely right 😂. But it sure broke the ice, didn't it?
Next stop — Handling Asynchrony — Part 1
References
You Don’t Know JS: this & Object Prototypes — https://www.amazon.com/You-Dont-Know-JS-Prototypes/dp/1491904151