0

Learning about classes, prototypes etc. and it's finally all coming into place for me (which is quite exciting to say the least :))) However, my question has to do with finding the object prototype of a Class, where I should in theory find the its methods.

For example:

class Color {
    constructor(r, g, b, name) {
        this.r = r;
        this.g = g;
        this.b = b;
        this.name = name;
    }
    innerRGB() {
        const { r, g, b } = this;
        return `${r}, ${g}, ${b}`;
    }
    rgb() {
        return `rgb(${this.innerRGB()})`;
    }
    rgba(a = 1.0) {
        return `rgba(${this.innerRGB()}, ${a})`;
    }
}

const red = new Color(255, 67, 89, "tomato");

Where are innerRGB(), rgb() and rgba() stored? I can't find them on the window object. Where are they? Where is the class Color stored?

When I enter Color() in the console, I get:

Uncaught TypeError: Class constructor Color cannot be invoked without 'new'

I'm clear on the inner workings of constructor functions, what's unclear to me is where the prototype resides and how I can access and inspect it.

Vayl
  • 69
  • 1
  • 10
  • 2
    They are on `Color.prototype`. As to the error message near the end of your question: that is a different, unrelated question: you should create an instance with `new Color()`, just like the error message says. – trincot May 09 '21 at 18:35
  • `red.__proto__` or `Color.prototype` – Rahul Kumar May 09 '21 at 18:38
  • 1
    @RahulKumar `red.__proto__` points to `Color.prototype` – Yousaf May 09 '21 at 18:40
  • yes correct, both way you can get what you need – Rahul Kumar May 09 '21 at 18:41
  • Try logging the following on the console: `Object.getOwnPropertyNames(Object.getPrototypeOf(red))` – Yousaf May 09 '21 at 18:47
  • @trincot thank you for your answer. However, what I'm eager to know is: where is Color.prototype? As in in which scope? I can't find it on the global object (window), so where is it? Thanks again. – Vayl May 09 '21 at 21:34
  • 1
    It is not a global *variable* if that is what you are looking for. It is created when the class is created. The class (which is a constructor function) is represented in a global variable `Color`, and the prototype, that will be used for actual instances of that class, is a property of that global variable. – trincot May 10 '21 at 06:08

2 Answers2

2

Here are object relationships for your code snippet:

enter image description here

The object in the middle, red.__proto__, a.k.a red.constructor.prototype, a.k.a. Object.getPrototypeOf(red) a.k.a. Color.prototype is where methods are stored.

The scope of the class Color itself (which is ƒ Color on the diagram) is its containing block, like with any other variable. In Javascript, classes are functions and functions are variables:

{
   // block started

   class Color { // it's the same as "let Color = function...
      ...
   }

   // block ended

}

// "Color" doesn't exist here
georg
  • 211,518
  • 52
  • 313
  • 390
  • What visualisation tool is that? Why does it still use the deprecated `__proto__`? – Bergi May 09 '21 at 19:59
  • Thank you for the diagram, it's helpful to visualize things. Everything in it makes sense but for one thing, in which scope is Color? So the middle box, where is it? It's not on the global object, so where is it? Thanks again. – Vayl May 09 '21 at 21:33
  • 1
    @Vayl `class`es can be global [without being properties of the global object](https://stackoverflow.com/q/28776079/1048572) – Bergi May 09 '21 at 21:47
  • One last tangent if you don't mind, what kind of tool are you using to create these diagrams? Seems very handy. Thanks for everything :) @Bergi – Vayl May 10 '21 at 10:20
1

If you want to access prototype of the instance use __proto__ field. If you want to see the prototype on a class itself use prototype field.

What happens when you create an instance the __proto__ field of an instance is set to prototype field of a class.

instance.__proto__ === Class.prototype
Ayzrian
  • 2,279
  • 1
  • 7
  • 14