frontend_dev frontend_dev - 3 months ago 7x
Javascript Question

Best (most performant) way to declare (class) properties with unknown values in v8

So I learned a bit about the hidden class concept in v8. It is said that you should declare all properties in the constructor (if using prototype based "pseudo classes") and that you should not

them or add new ones outside of the constructor. So far, so good.

1) But what about properties where you know the type (that you also shouldn't change) but not the (initial) value?

For example, is it sufficient to do something like this:

var Foo = function () {

... and assign concrete values later on, or would it be better to assign a "bogus" value upfront, like this:

var Foo = function () {
this.myString = "";
this.myNumber = 0;

2) Another thing is with objects. Sometimes I just know that an object wont have a fixed structure, but I want to use it as a hash map. Is there any (non verbose) way to tell the compiler I want to use it this way, so that it isn't optimized (and deopted later on)?


Thanks for your input! So after reading your comments (and more on the internet) I consider these points as "best practices":

  • Do define all properties of a class in the constructor (also applies for defining simple objects)

  • You have to assign something to these properties, even if thats just
    - just stating
    is apparently not enough

  • Because you have to assign something anyways I think assigning a "bogus" value in case you can't assign the final value immediatly cannot hurt, so that the compiler does "know" ASAP what type you want to use. So, for example
    this.myString = "";

  • In case of objects, do assign the whole structure if you know it beforehand, and again assign dummy values to it's properties if you don't know them immediatly. Otherwise, for example when intending to use the Object as a hashmap, just do:
    this.myObject = {};
    . Think its not worth indicating to the compiler that this should be a hashmap. If you really want to do this, I found a trick that assigns a dummy property to this object and
    s it immediatly afterwards. But I won't do this.

  • As for smaller Arrays it's apparently recommended (reference: to preallocate them especially if you know the final size, so for example:
    this.myArray = new Array(4);

  • Don't
    properties later on! Just
    them if needed

  • Don't change types after assigning! This will add another hidden class and hurt performance. I think thats best practice anyways. The only case where I have different types is for certain function arguments anyways. In that case I usually convert them to the same target type.

  • Same applies if you keep adding additional properties later on.

That being said, I also think doing this will lean to cleaner and more organized code, and also helps with documenting.

Yeah, so one little thing I am unsure remains: What if I define properties in a function (for example a kind of
method) called within the constructor?


Re 1): Just reading properties, like in your first snippet, does not do anything to the object. You need to assign them to create the properties.

But for object properties it doesn't actually matter much what values you initialise them with, as long as you do initialise them. Even undefined should be fine.

The concrete values are much more relevant for arrays, where you want to make sure to create them with the right elements (and without any holes!) because the VM tries to keep them homogeneous. In particular, never use the Array constructor, because that creates just holes.

Re 2): There are ways to trick the VM into using a dictionary representation, but they depend on VM and version and aren't really reliable. In general, it is best to avoid using objects as maps altogether. Since ES6, there is a proper Map class.