1

I was testing a getter in my class and I faced a contrast in my implementation and document, based on MDN document a class getter property should be defined inside the instance's prototype

Getter properties are defined on the prototype property of the class and are thus shared by all instances of the class.

so why I can see the getter directly on my instance,

img1

the issue I have with this implementation is, if we assume the getter property is only inside the instance's prototype so why the this is referred to the k not the Kevin.prototype because this in a getter function inherites the object which is located in it based on the MDN document

A function used as getter or setter has its this bound to the object from which the property is being set or gotten.

so in a nutshell, why we have getc directly in our class instance and why the getc value inside the prototype of k is lambo not undefined?

code:

class Kevin {
  constructor(x) {
    this.age = x;
    this.car = "lambo"
  }
  get getc() {
    return this.car;
  }
}

const k = new Kevin(3);
  • 2
    It's not really in the instance, that's just the console pretending it is. Notice that `getc` is a different color from `age` and `car`. That means it's not a real property. – Barmar Feb 15 '23 at 16:19
  • Chrome’s console is kind of tricking you. Here’s what it looks like in [Firefox](//i.stack.imgur.com/Vqd6n.png). You can also easily test `Object.keys(k)`, `Reflect.ownKeys(k)`, `Object.getOwnPropertyDescriptors(k)`, `Object.getOwnPropertyNames(k)`, `Object.hasOwn(k, "getc")`, etc. Also, why would the value be `undefined`? `this` still refers to the instance in this context, so `this.car` is `"lambo"`. `this` never refers to the prototype object in this context. That’s not how `this` works. – Sebastian Simon Feb 15 '23 at 16:23
  • so even we assume your words are correct, so why `this.car` is referring to `k` and setting the value of `this.car="lambo"` and not `undefined` because we have `car` inside the `k` not in `k's prototype` – scorpian111 Feb 15 '23 at 16:24
  • @scorpian111 Read my edited comment. See also [How does the "this" keyword work, and when should it be used?](/q/3127429/4642212). – Sebastian Simon Feb 15 '23 at 16:26
  • getter property inside of an class is non-enumerable so you cant iterate it, so all of these property are almost useless, what's the value of `getc` inside the firefox console?@SebastianSimon – scorpian111 Feb 15 '23 at 16:28
  • 1
    @scorpian111 It is `"lambo"`, as expected. `this` is derived from the context of how the getter is used. `k.getc` takes `k` as the context, so `k === this`. It doesn’t matter how `getc` is accessed, or if it even exists anywhere on the prototype chain. This also has nothing to do with enumerability. It has everything to do with how `this` works. The console assumes `k` as the context from the logged value (probably). – Sebastian Simon Feb 15 '23 at 16:29
  • 1
    The specific bit where the MDN docs mention "... has its `this` bound to the object from which..." is the key piece here. You can think of it as the function getting defined once for all instances of the entire class since the approximate behavior will be the same, but when you make a new class instance it implicitly has a `this` property that refers to the new instance. The getter function then implicitly receives this argument and gives you the expected behavior. – Shaavin Feb 15 '23 at 16:29
  • the context should be `Kevin.prototype` not `k` based on the document@SebastianSimon – scorpian111 Feb 15 '23 at 16:50
  • @scorpian111 Why? Where did you ever type `Kevin.prototype` or `Kevin.prototype.getc` or something similar? You only typed `k` in the console. Based on which document? Please cite the source. – Sebastian Simon Feb 15 '23 at 16:53
  • where I have written `k.getc` which my context should be `k` as you are trying to say, it's based on MDN document , read the https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#this_with_a_getter_or_setter@SebastianSimon – scorpian111 Feb 15 '23 at 16:56
  • 1
    @scorpian111 Yes. How does that contradict the fact that `k === this`? Why should `this` ever be equal to `Kevin.prototype`? _“`this` […] is based on which object the property is accessed on, not which object the property is defined on”_ is correct. You’re accessing the `getc` getter on the object `k`. As I said earlier, it is completely irrelevant _where_ the property is located exactly, or if it even exists. – Sebastian Simon Feb 15 '23 at 16:58
  • the context should be `Kevin.prototype` because in a getter or setter function the context is where the function is defined (based on document I have mentioned above), since I haven't accessed it like `k.getc` so there is no reason for `this` to mention `k`.@SebastianSimon – scorpian111 Feb 15 '23 at 17:02
  • the part you're quoting from document, it's for `Object.defineProperty` not `getter` and `setter`, the part you have to pay attention starts right after the part you have mentioned@SebastianSimon – scorpian111 Feb 15 '23 at 17:07
  • 1
    @scorpian111 _“because in a getter or setter function the context is where the function is defined”_ — No, this directly contradicts the documentation and reality: `const inherited = { get x(){ return this.y }, y: 1 }; const object = Object.create(inherited); object.y = 2; console.log(object.x);` will log `2`, not `1`. The context is based on the access, not on the location of definition. _“I haven't accessed it like `k.getc` so there is no reason for `this` to mention `k`”_ — You also haven’t accessed it like `Kevin.prototype.getc`, so there is no reason for `this` to be `Kevin.prototype`. – Sebastian Simon Feb 15 '23 at 17:32
  • 1
    @scorpian111 _“the part you have to pay attention starts right after the part you have mentioned”_ — There isn’t much else in this section after that. The part I quoted is _not_ specifically about `Object.defineProperty` anyway. Why do you believe there is a difference in how `this` is handled based on the usage of the `get` keyword vs. `Object.defineProperty` when the documentation specifically says “`this` in getters and setters is based on which object the property is accessed on”? Neither `get x(){}` nor `Object.defineProperty` _access_ the property. – Sebastian Simon Feb 15 '23 at 17:33

0 Answers0