This content originally appeared on Bits and Pieces - Medium and was authored by Priyabrata Chattaraj
You may not have noticed this before, but if you can create an array using the Object.create() method. If you did, however, you would notice that Array.isArray(Object.create(Array.prototype)) would return false.
Or why is it that a string is a primitive but has methods that you can apply with the . (period) syntax, such as .charAt() .charCodeAt()?
Well, it turns out that this is due to the concept of ‘exotic objects’.
For strings, the JavaScript engine — at runtime — replaces that string with the String object, takes the value of it, then applies its methods on the value. You can’t observe this process because it is an internal mechanism. More on what happens later!
Exotic Objects
In JavaScript, objects can be categorized into Ordinary Objects and Exotic Objects.
Ordinary Objects are any normal objects or we can say everything that is not an exotic object. Objects instantiated with {} or new Object() or new Array() are examples of Ordinary Objects.
Whereas, Exotic Objects are any objects that have different internal implementations for their properties. Examples of Exotic object include Array, Proxy, String, Arguments, Modules.
So what are these ‘different internal implementations’? Let’s look at an example with Array.
Can you guess why arrayByNew behaves as intended while arrayByCreate does not?
Well, we can’t fool Array.isArray() because array is an exotic object and it has some internal ‘magic’. Only assigning the prototype is not where the game ends. The code has to do something to it to make it behave like an array. When instantiating with the new or class keyword, our JS Engine connects this object with the implementation. This implementation cannot be copied as they are unique and reserved for them. Array implementations are written inside the JS Engine so they can’t be seen or touched. See ECMA 2022 for more.
Interesting array behavior
What is happening to our array in the below image?
Let's try to understand it from the pseudo-code below from the ECMA-22:
Here, the implementational difference is [[DefineOwnProperty]].
It says if you tried to assign a key that is not the word length and is a valid array index (integer number, 0 ≥ index ≤ 2³² -1) then the code inside [[DefineOwnProperty]] will treat it specially.
If the index is smaller than length it will replace the element at the index and if it is ≥ length it assigns the value at the index and length = index + 1.
Else if the key is not a valid array index it’ll be just added as a normal object property. So, null was not a valid array index it was added as object property.
What happens if the key we want to assign its value is the word length itself?
As you can see from the above picture from line number 1, control will go to ArraySetLength(Array, value_Description) ECMA-22
It says that the length should be [[writable]].
If the value is greater than length it will increase the length to the current value. And empty cells of the array will be shown as empty or whole (, ,) [same for assigning index that is greater than length] by the JS Engine.
If the value is lower than length then it has a catch. It will delete the elements that exceed on that provided new value for length. But, the elements have to be [[configurable]] whenever it will encounter an element that is configurable=false it will stop there.
That’s why the following happens:
Object.defineProperty(arr, 2, { value: 20, configurable: false });
arr.length = 0;
console.log(arr.length); //3
Conclusion
Exotic objects cannot be created. JavaScript ES6 provides some rules by only following these rules exotic objects and their’ subclass objects can be created, because of the internal implementation that is only reserved and unique to them.
It’s a confusing topic but I hope this has, at the very least, shone a light on what goes on under the hood of the JavaScript engine. If you found this interesting, be sure to like, comment, and share!
Build applications differently
OSS Tools like Bit offer a new paradigm for building modern apps.
Instead of developing monolithic projects, you first build independent components. Then, you compose your components together to build as many applications as you like. This isn’t just a faster way to build, it’s also much more scalable and helps to standardize development.
It’s fun, give it a try →
Learn more
- Building a React Component Library — The Right Way
- 7 Tools for Faster Frontend Development in 2022
- Microservices are Dead — Long Live Miniservices
Exotic Objects in JavaScript was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Priyabrata Chattaraj
Priyabrata Chattaraj | Sciencx (2022-02-22T09:17:18+00:00) Exotic Objects in JavaScript. Retrieved from https://www.scien.cx/2022/02/22/exotic-objects-in-javascript/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.