What are “Internal Slots” and “Internal Methods” in JavaScript?
By: Uday Hiwarale
Tags: JavaScript, Ecmascript 6, Ecmascript, ES6, Ecmascript2015

The 6.1.7.2 section of the ECMAScript 2015 specification talks about some weird internal properties and internal methods objects (descendants of Object ) can have. These properties or methods are implemented by the JavaScript engine but they are abstracted away from the runtime, hence you won’t be able to access them on the objects like normal properties.

These are represented by the [[<name>]] notation in the ECMAScript specification where name is the name of the internal property or internal method. The internal property is called an internal slot and it contains a value associated with that object to represent some state of the object.

Let’s take a quick example. The [[GetPrototypeOf]] internal method is implemented by all the objects and its job is to return the prototype of the object. When you execute Reflect.getPrototypeOf(obj) method with obj being the object whose prototype needs to be inspected, JavaScript engine calls the [[GetPrototypeOf]] internal method of the obj which returns the value of [[Prototype]] internal slot of the object that contains the prototype.

💡 The obj.__proto__ also points to the prototype of the obj and accessing it would be like accessing the [[Prototype]] internal slot of the obj .

When an internal method is invoked on an object such as obj in the above example, it is called the “target” of the invocation. If the target doesn’t support an internal method, for example calling the Reflect.getPrototypeOf on null , a TypeError exception is thrown.

Objects can have multiple internal slots and internal methods. ECMAScript specification does not describe how these internal methods are implemented but it describes the signature of the method call. The following are ES2015 internal methods implemented by all objects (hence essential). These internal methods may accept some arguments of specific ECMAScript language types and may return a value.

Above are the ES2015 internal methods of a Function object. Below are the internal slots of a property descriptor object that represents the state of an object’s property. If you want to know what a property descriptor is, I have written a separate lesson on this topic.

Internal slots and internal methods are the aid to the ECMAScript specification and they are referenced inside the specification to convey the appropriate behavior. For example, whenever [[Protoype]] key appears, we know that specification is talking about the internal property that contains the prototype of the object.

Internal slots and internal methods help to achieve consistent behavior of the objects and an implementer (JavaScript engine) can correctly provide these implementations by looking at the specification. However, one doesn’t have to follow the exact signature as specified by the specification. This StackOverflow answer will guide you.

ES6 specification proposes the Reflect object which provides the ability to inspect and modify objects. For example, Reflect.has(target,key) method checks if target object has the key property on it or on its prototype which works exactly like the in operator but in a functional form.

When this method is called with a target , the JavaScript engine executes the [[HasProperty]] internal method of the target object which was implemented by the JavaScript engine. Different JavaScript engines can implement this method differently but it should follow this specification.

ES6 also gives us the Proxy constructor which is used to create a proxy around a target object. let proxy = new Proxy(target,handler); , here the proxy object provides an interface around the target object through the handler object. The handler object contains some methods that intercept the operation on the proxy and delegates that to the target .

Therefore these handler methods are called traps as they intercept the operations on the target . These handler methods are similar to the Reflect methods with the same name. For example, handler.has is executed when the in operator is invoked on the proxy .

If the handler object doesn’t have a particular method, for example has in this case, then JavaScript engine automatically executes the internal method associated with has (which is similar to Reflect.has ) on the target which is [[HasProperty]] internal method.

I know that it must be difficult to wrap your head around the concepts of internal slots and internal methods with the above examples. But worry not, I have written articles on Reflect and Proxy that will clear things up for you.

In the end, the JavaScript runtime is not exposed to these internal slots and internal methods and their use is limited to the ECMAScript specification documents only. But it is good to know that these things exist since they have started popping up in JavaScript documentation and tutorials.

To elaborate further, V8 team has written a concise article on how to read ECMAScript specifications which also contains some information about internal slots and internal methods. I think its a must-read for a JavaScript developer. Since it’s a short document, highly recommended.