Object and the hidden values

Introduction

I have an object with many keys, which I can see when I use console.log.

I have Object.keys.

Ahhh, hold on, hold on. Why is it an empty array instead of an array with many key strings?

Have you ever tried using console.log with data returned by the Object.keys method, only to find an empty array instead of the expected array filled with many string values? Sounds a bit strange, doesn’t it? If you’ve encountered this issue and are still searching for a solution, you’ve come to the right place.

In this blog post, I will introduce you to the concepts of Enumerability and Ownership Properties in JavaScript objects. Additionally, I will provide examples to clarify these concepts and ensure a clear understanding.

So, first of all, what is Enumerability and Ownership of objects in JavaScript?

Breaking down the title, we can focus on two key aspects: Enumerability and Ownership.

Enumerability

Enumerability determines whether a property is included in certain JavaScript methods that traverse or query object properties. Enumerability is controlled by the internal enumerable flag of a property.

There are 2 types of Enumerability: Enumerable Properties and Non-enumerable Properties

  • Enumerable Properties
    • By default, all properties of an object are enumerable.
    • An enumerable property is one that can be retrieved and iterated through using a for...in loop or methods like Object.keys(), Object.values(), and Object.entries().

    Here, the Object.keys() method is used to get the enumerable properties of the object. The method returns an array containing the keys of the enumerable properties, which are 'name' and 'age'.

  • Non-enumerable Properties
    • Non-enumerable properties refers to object properties that are not included when iterating over the properties of an object using a loop or a method like Object.keys(). It means that non-enumerable properties have their internal enumerable flag set to be false.
    • Properties defined using Object.defineProperty() or certain built-in objects are non-enumerable.

    In this snippet, we define a non-enumerable property name on the object using Object.defineProperty(). When we call Object.keys() to get the object’s enumerable properties, it returns an empty array because the non-enumerable property is not included.

Ownership

Ownership of properties is determined by whether the property belongs to the object directly and not to its prototype chain.

  • Own properties
    • Own properties are defined directly on the object itself, not inherited from prototypes.
    • To determine whether a property is an own property, you can see methods such as Object.hasOwnProperty() or Object.hasOwn(). These methods allow you to check if a specific property is directly defined on the object or it is inherited through the prototype chain.

    Here, we use Object.hasOwnProperty() and Object.hasOwn() to see if the name property belongs directly to the object. Both methods return ‘true’ because the property is set directly on the object.

  • Inherited properties
    • Inherited properties are those obtained from the object’s prototype chain.
    • These properties are distinct from own properties in that they are not directly defined on the object itself but are accessible through prototype delegation.

    We make an object and link it to a parent object using Object.setPrototypeOf(). The object gets a ‘name’ property from its parent. When we check with obj.hasOwnProperty() or Object.hasOwn(), it says ‘false’ because ‘name’ is inherited, not set directly. But we can still get the property value using obj.name because it looks up the prototype chain.

Example

Now, let’s solve a specific problem:

Imagine you’re creating a div element, checking its styles with console.log, and using Object.keys to map the style keys. However, everything’s fine on Chrome, but on Safari, it returns an empty list.

 

What’s the issue here? Well, on Chrome, CSSStyleDeclaration is seen as both Enumerable Properties and Own Properties. This means we can smoothly use Object.keys to grab all the keys of CSSStyleDeclaration. However, Safari sees it differently – it categorizes CSSStyleDeclaration as Enumerable Properties and Inherited Properties. Unfortunately, this causes trouble, and we can’t use Object.keys in Safari either.

Now, how do we fix this problem and make it work seamlessly on both Chrome and Safari?

To better to know which method we could use at here, check out the detailed information provided in the Mozilla Developer Network’s documentation. This resource offers a comprehensive table listing all the methods available for use.

Upon careful examination, it becomes apparent that the most effective way to obtain an array with all style keys, ensuring compatibility with both Chrome and Safari, is by using the for...in method. Let’s put this knowledge into action and see if it works or not.

The outcome is impressive! The same result is achieved on both Chrome and Safari.

In conclusion, having a grasp of enumerability and ownership is vital for navigating object properties in JavaScript. I hope you find these insights valuable in tackling any challenges that may arise during your coding endeavors with objects in JavaScript.

Happy Coding!!!

References

Enumerability and ownership of properties – MDN Web Docs

Ron

 

Comments

Let’s make a great impact together

Be a part of BraveBits to unlock your full potential and be proud of the impact you make.