We implemented a Set class by using "object id" properties to map objects. Every object has a unique object id. In order to ensure the same object is added only once, we make the id a property of the object
itself. So we bypass the addition if there exists the same id property in the set as the property of the object being added. Otherwise, we generate its id property and add the object to the set. When in a for/in loop, the property will be enumerated inevitably.
But here comes the problem: The id property has no more significance than a sign of whether the object id has been queried. As a result, we more often want it to be nonenumerable. Here is the situation where Object.defineProperty() comes into play.
We can simply use Object.defineProperty() to define the new property like this:
In this way, the |**objectid**| property will not be revealed by the for/in loop.
However, it is somewhat inconvenient when we expect an object to have such a property in other cases because we have to call Set._v2s which might be irrelevant.
So, we simply make the id property a property of the prototype of Object so that it will be inherited by all objects. How to make sure that every object has an id that is unique since the
id property is inherited by all objects? Good catch! We achieve this in the above codes by defining the property only when the property is queried so that we can base on the value increment to make the property unique. This enlightens us that the id property
is not necessarily a value property. It can be a getter to reveal the actual id property. If the id property is there, just return it, and if not, create one.
Making Properties Nonenumerable