# How does super work as an object？

**URL:** <https://es.discourse.group/t/how-does-super-work-as-an-object/1279>\
**Category:** I have questions\
**Created:** [April 6, 2022, 9:26am UTC](https://es.discourse.group/t/how-does-super-work-as-an-object/1279 "2022-04-06T09:26:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![fltenwall](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/fltenwall/32/1324_2.png) [@fltenwall](https://es.discourse.group/u/fltenwall)\
**Post date:** [April 6, 2022, 9:26am UTC](https://es.discourse.group/t/how-does-super-work-as-an-object/1279/1 "2022-04-06T09:26:08Z")

</div>

```javascript
class A {
  constructor() {
    this.x = 1;
  }
}

A.prototype.x = 5;

class B extends A {
  constructor() {
    super();
    this.x = 2;
    // Super refers to this when it is assigned
    super.x = 3;
   // When set, super refers to the prototype of the parent class
    console.log(super.x); // 5
    console.log(this.x); // 3
  }
}

let b = new B();

```

But, why？

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [April 6, 2022, 12:07pm UTC](https://es.discourse.group/t/how-does-super-work-as-an-object/1279/2 "2022-04-06T12:07:00Z")

</div>

When I try to understand these types of cases I like to use babel to see what the code becomes when it is transpiled back to ES5.

When I do that. [playground](https://babeljs.io/repl#?browsers=defaults%2C%20%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&corejs=3.21&spec=false&loose=false&code_lz=MYGwhgzhAECC0G8BQ1rAPYDsIBcBOArsDungBQCUiKq0OAFgJYQB0AHtALzQCMA3DQC-SYUlgsADnnQkcATwkBTdl2gBWAUlCQYAIWiK2ORZgAmMeMlQZs-IiXJUrtCASWOBtaDVQB6X9AAym6KeNB4igBmoTAkdEwwAO70JtCMOGkwOowA5piKpj7Qru4q3ADMni4heOxVwqIAbuiMptBk-YnQupQUfEA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Creact%2Cstage-2&prettier=false&targets=&version=7.17.8&externalPlugins=&assumptions=%7B%7D)

```javascript
super.x = 3;
super.x;

```

becomes roughly:

```javascript
_set(_getPrototypeOf(B.prototype), "x", 3, this, /* isStrict: */ true);
_get(_getPrototypeOf(B.prototype), "x", this);

```

Which can be roughly compiled back to 'modern JS' as:

```javascript
class A {
  constructor() {
    this.x = 1;
  }
}

A.prototype.x = 5;

class B extends A {
  constructor() {
    super();
    this.x = 2;
      
    // Set
    Reflect.set(Reflect.getPrototypeOf(B.prototype), "x", 3, this);
      
    // Get
    let v = Reflect.get(Reflect.getPrototypeOf(B.prototype), "x", this);
    console.log(v); // 5
    console.log(this.x); // 3
  }
}

void (new B());

```

So now we no longer have to think about `super`, and only look into the difference between [Reflect.set](https://tc39.es/ecma262/multipage/reflection.html#sec-reflect.set) and [Reflect.get](https://tc39.es/ecma262/multipage/reflection.html#sec-reflect.get).

(to be continued...)

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [April 6, 2022, 12:27pm UTC](https://es.discourse.group/t/how-does-super-work-as-an-object/1279/3 "2022-04-06T12:27:32Z")

</div>

...continued.

This example can now be reduced to this:

```javascript
let thePrototypeObject = { x: 5 };
let theReceiverObject = { x: 2 };

Reflect.get(thePrototypeObject, 'x', theReceiverObject); // 5
Reflect.set(thePrototypeObject, 'x', 3, theReceiverObject); // true (it worked)

thePrototypeObject.x; // still 5
theReceiverObject.x; // now 3

```

Which shows that ['[[set]]'](https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver) can create or update a property on the receiver parameter. But ['[[get]]'](https://tc39.es/ecma262/multipage/#sec-ordinary-object-internal-methods-and-internal-slots-get-p-receiver) only uses the receiver when a `getter` is encountered.

---

<div class="post-metadata">

**Author:** ![senocular](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/senocular/32/642_2.png) [@senocular](https://es.discourse.group/u/senocular)\
**Post date:** [April 6, 2022, 1:13pm UTC](https://es.discourse.group/t/how-does-super-work-as-an-object/1279/4 "2022-04-06T13:13:00Z")

</div>

> [@aclaymore](#):
>
> So now we no longer have to think about `super`, and only look into the difference between [Reflect.set](https://tc39.es/ecma262/multipage/reflection.html#sec-reflect.set) and [Reflect.get](https://tc39.es/ecma262/multipage/reflection.html#sec-reflect.get).

I think its worth pointing out that MDN does a bad job with the role of receiver with respect to set. It's description for the receiver argument is simply:

> The value of `this` provided for the call to `target` if a setter is encountered.

This ignores the very important fact that when present, if not calling a setter, the receiver becomes the target for the property being set.

```javascript
const a = { x: 1 }
const b = { x: 2 }
Reflect.set(a, 'x', 3, b) // sets on b, not a
console.log({a, b}) // a: { x: 1 }, b: { x: 3 }}

```

Especially important in this particular case since that's exactly what's happening with super and `this` in:

```javascript
Reflect.set(Reflect.getPrototypeOf(B.prototype), "x", 3, this); // super.x = 3;

```

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [April 6, 2022, 1:40pm UTC](https://es.discourse.group/t/how-does-super-work-as-an-object/1279/5 "2022-04-06T13:40:41Z")

</div>

> [@senocular](#):
>
> I think its worth pointing out that MDN does a bad job with the role of receiver with respect to set

Agreed, feels important to mention this. Issue raised: [Issue with "Reflect.set()": Incomplete details on the consequences of the receiver parameter · Issue #14744 · mdn/content · GitHub](https://github.com/mdn/content/issues/14744)
