1

I can't understand the differences/reasons/pros/cons between properties declared in the class constructor, in the class prototype and declared directly in the class.

Class Human {
  constructor() {
    this.a = 0;
  }
}

Human.prototype.b = 1;

Human.c = 2;
Synoon
  • 2,297
  • 4
  • 22
  • 37
zayle
  • 13
  • 1
  • 2
  • 2
    `this.a` – on the instance. `prototype` – shared on *every* instance. `Human.c` – on the *class* (and not accessible through an instance). – deceze Jul 26 '19 at 08:50
  • Properties declared on prototype of class will be inherited by each of its instance. And the property directly added to class will not be on instance and will only be on class. It is just static property – Maheer Ali Jul 26 '19 at 08:50
  • Well, `a` and `c` are basically the same - a property on the instance. `b` exists on the prototype and thus the difference is [prototypal inheritance](https://stackoverflow.com/questions/12201082/prototypal-inheritance-concept-in-javascript-as-a-prototype-based-language) vs directly setting properties. – VLAZ Jul 26 '19 at 08:51
  • 1
    @VLAZ `a` and `c` are *not* the same. – deceze Jul 26 '19 at 08:52
  • @deceze I meant the same as they aren't on the prototype. There is no access to `c` through an instance of `Human`. However, both `a` and `c` are directly attached to an object and, yes, it is two *different* objects. – VLAZ Jul 26 '19 at 10:30

1 Answers1

0

There is one more related case, although in JS it can only define functions:

Class Human {
  d() {}  // Property d, its type is Function.
}

Basically your c is very different from the other three. You can only access your c as Human.c, while all the others can be accessed as properties of an instance of the Human class, e.g. new Human().a.

To define methods, the preferable syntax is probably like d, it looks most natural. It's effectively the same as if you assigned the function to Human.prototype, like b. So the above example is equivalent to Human.prototype.d = function() {}.

For instance variables (fields), the syntax for a is probably best. Every instance of the class receives its own a. If it was initialised to [] instead of 0, each of them would have a separate array, which is most probably what you expect.

On the other hand, properties assigned to class prototype like your b are visible via instances (so new Human().b works), but it's a single object that all existing instances of your class can access - which means they should be treated as immutable, unless you like bad designs, global mutable state etc. So this is a place where you can basically put:

  • functions - but for functions the better syntax is the method syntax (my d),
  • immutable values - but then you can as well define them as a constant outside of the class, or make them static (like your c),
  • shared state - which it might be better not to have at all.

So I would not use Class.prototype directly at all, instead define methods as methods, and fields in the constructor.

TPReal
  • 1,539
  • 12
  • 26