# JS Tip of the Day: Internal Slots

**URL:** <https://forum.kirupa.com/t/js-tip-of-the-day-internal-slots/643171>\
**Category:** web dev\
**Created:** [February 25, 2020, 12:20pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-internal-slots/643171 "2020-02-25T12:20:13Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![senocular](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/senocular/32/7217_2.png) [@senocular](https://forum.kirupa.com/u/senocular)\
**Post date:** [February 25, 2020, 12:20pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-internal-slots/643171/1 "2020-02-25T12:20:13Z")

</div>

**Internal Slots**  
Level: Advanced

JavaScript maintains hidden properties within your objects known as internal slots. These are used internally by the runtime for things like managing how the object behaves, or what kind of data it it might store internally. Internal slots are usually represented by a property name surrounded by two square brackets (`[[<name>]]`) but they are not directly accessible as properties to JavaScript code. For those that can be accessed from JavaScript, you’d need to go through an alternative API.

An object’s prototype is an example of something that is stored in an internal slot. When an object needs to see what it inherits, it looks to its internal `[[Prototype]]` which is the internal slot that stores its prototype object. While user code can’t access `[[Prototype]]` directly, there are APIs like `Object.getPrototypeOf()` and the ` __proto__ ` getter which will provide its value to JavaScript.

```javascript
let map = new Map(); // map.[[Prototype]] = Map.prototype
let proto = Object.getPrototypeOf(map); // returns map.[[Prototype]]
console.log(proto === Map.prototype); // true

```

Internal slots usually hide in the background allowing you to ignore their existence as they secretly work to ensure your objects behave as they should. But sometimes the nature of internal slots work can cause unexpected problems.

Unlike normal object properties, internal slots are not inherited. If you create an object that inherits from another object with a certain internal slot, that slot will not be accessible from the new object. Map instances, like `map` in the example above, use an internal slot called `[[MapData]]` (which you may see represented as `[[Entries]]` in developer tooling) to store their key-value pairs. If you created an object that inherited from `map`, Map methods of that object would fail because of the lack of `[[MapData]]` in that new object.

```javascript
let map = new Map([['Home', '37.7N-122.5W']]);
console.log(map.get('Home')); // 37.7N-122.5W

let fakeMap = Object.create(map); // new fakeMap object inherits from map
console.log(fakeMap.get('Home'));
// TypeError: incompatible receiver

```

Maps aren’t the only type that suffer from this problem. There are a number of other objects that would behave similarly, including, but not limited to:

```javascript
Object.create(new Set()).size; // TypeError
Object.create(new Date()).getTime(); // TypeError
Object.create(new Number(1)).valueOf(); // TypeError
Object.create(Promise.resolve(1)).then(() => {}); // TypeError

```

While you may not be able to create working objects that inherit from instances of these types, using `class` syntax, you are able to subclass them.

```javascript
class FakeMap extends Map {
    constructor (entries) {
        super(entries); // initializes this instance with Map internal slots
    }
}

let fakeMap = new FakeMap([['Home', '37.7N-122.5W']]);
console.log(fakeMap.get('Home')); // 37.7N-122.5W (not so fake anymore)

```

This version of `fakeMap` doesn’t fail when calling the Map `get` method because it was initialized with the proper internal slot expected by that method (and others like it) having gone through the `FakeMap`, and therefore `Map`, constructor.

More info:

- [Map on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map)
- [Internal slots in the ECMAScript spec](http://www.ecma-international.org/ecma-262/#sec-object-internal-methods-and-internal-slots)
