Categories
Modern JavaScript

Best of Modern JavaScript — __proto__ and Descriptors

Spread the love

Since 2015, JavaScript has improved immensely.

It’s much more pleasant to use it now than ever.

In this article, we’ll look at new OOP features in JavaScript.

The proto Property

We can use the __proto__ property to get and set the prototype of an object easily.

For example, we can write:

Object.getPrototypeOf({ __proto__: null })

Then it’ll return null since we set the __proto__ property to null .

This doesn’t work with the string version of the key as it creates its own property:

Object.getPrototypeOf({ ['__proto__']: null })

It’ll return Object.prototype .

And Object.keys({ [‘__proto__’]: null }) returns the array[ ‘__proto__’ ] .

Also, if we define our own property named __proto__ , it also won’t work.

For instance, we can write:

const obj = {};
Object.defineProperty(obj, '__proto__', { value: 'bar' })

Objects that don’t have Object.prototype as a Prototype

We can use the Object.create method with the argument null to create an object with no prototype.

For example, we can write:

const obj = Object.create(null);

Then obj has no __proto__ property.

This method makes it easy to create dictionary objects where we don’t want any inherited properties from it.

proto and JSON

__proto__ may be stringified with JSON.stringify .

For example, we can write:

JSON.stringify({['__proto__']: 'foo' })

And then that returns:

"{"__proto__":"foo"}"

Detecting support for ES6-style proto

There are several ways to detect the ES6 style __proto__ property.

We can check it with the Object.prototype.__proto__ property and the __proto__ in the object literals.

For example, we can write:

const supported = ({}).hasOwnProperty.call(Object.prototype, '__proto__');

We check if the Object.prototype.__proto__ property exists.

We can also check that getter and setter of __proto__ are functions to make sure that we can get and set the value of this property.

For example, we can write:

const desc = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__');
const supported = (
  typeof desc.get === 'function' && typeof desc.set === 'function'
);

And we can also use the Object.getPrototypeOf method to do the check by passing in an object with the __proto__ property set to null .

Then we can use that to check if the prototype returned is null .

For example, we can write:

const supported = Object.getPrototypeOf({__proto__: null}) === null;

Enumerability in ES6

In JavaScript, each object can have zero or more p[roperties.

Each property has a key and 3 or more descriptors.

All properties have the enumerable and configurable attributes

enumerable means that whether we show the property everywhere.

configurable set to false disables property value changes and prevents deletion.

Properties have the value and writable attributes.

value has the value of the property.

And writable controls whether we can change the value of the property.

Properties also have the getter get accessor and setter set accessor.

We can use the Object.getOwnPropertyDescriptor method to get the property descriptors.

For example, we can write:

const obj = { foo: 'bar' };
consr desc = Object.getOwnPropertyDescriptor(obj, 'foo')

Then desc is:

{
  value: "bar",
  writable: true,
  enumerable: true,
  configurable: true
}

Conclusion

Object properties have property descriptors.

Also, the __proto__ property acts differently in different contexts.

We can check if the property is available in different ways.

Leave a Reply

Your email address will not be published. Required fields are marked *