Exotic Objects in JavaScript

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.

Code, comparing creating an instance with the new keyword and Object.create() method

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?

Some javascript array behaviour

Let’s try to understand it from the pseudo-code below from the ECMA-22:

Explanation from ECMA script for assigning index to an array

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

Expiation for assigning to ‘length’ key of array from ECMA script

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 →

An independent product component: watch the auto-generated dependency graph

Learn more


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

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.

Code, comparing creating an instance with the new keyword and Object.create() method

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?

Some javascript array behaviour

Let's try to understand it from the pseudo-code below from the ECMA-22:

Explanation from ECMA script for assigning index to an array

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

Expiation for assigning to ‘length’ key of array from ECMA script

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 →

An independent product component: watch the auto-generated dependency graph

Learn more


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


Print Share Comment Cite Upload Translate Updates
APA

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/

MLA
" » Exotic Objects in JavaScript." Priyabrata Chattaraj | Sciencx - Tuesday February 22, 2022, https://www.scien.cx/2022/02/22/exotic-objects-in-javascript/
HARVARD
Priyabrata Chattaraj | Sciencx Tuesday February 22, 2022 » Exotic Objects in JavaScript., viewed ,<https://www.scien.cx/2022/02/22/exotic-objects-in-javascript/>
VANCOUVER
Priyabrata Chattaraj | Sciencx - » Exotic Objects in JavaScript. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/02/22/exotic-objects-in-javascript/
CHICAGO
" » Exotic Objects in JavaScript." Priyabrata Chattaraj | Sciencx - Accessed . https://www.scien.cx/2022/02/22/exotic-objects-in-javascript/
IEEE
" » Exotic Objects in JavaScript." Priyabrata Chattaraj | Sciencx [Online]. Available: https://www.scien.cx/2022/02/22/exotic-objects-in-javascript/. [Accessed: ]
rf:citation
» Exotic Objects in JavaScript | Priyabrata Chattaraj | Sciencx | 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.

You must be logged in to translate posts. Please log in or register.