JavaScript Initializing object properties with null


Example

All modern JavaScript JIT compilers trying to optimize code based on expected object structures. Some tip from mdn.

Fortunately, the objects and properties are often "predictable", and in such cases their underlying structure can also be predictable. JITs can rely on this to make predictable accesses faster.

The best way to make object predictable is to define a whole structure in a constructor. So if you're going to add some extra properties after object creation, define them in a constructor with null. This will help the optimizer to predict object behavior for its whole life cycle. However all compilers have different optimizers, and the performance increase can be different, but overall it's good practice to define all properties in a constructor, even when their value is not yet known.

Time for some testing. In my test, I'm creating a big array of some class instances with a for loop. Within the loop, I'm assigning the same string to all object's "x" property before array initialization. If constructor initializes "x" property with null, array always processes better even if it's doing extra statement.

This is code:

function f1() {
    var P = function () {
        this.value = 1
    };
    var big_array = new Array(10000000).fill(1).map((x, index)=> {
        p = new P();
        if (index > 5000000) {
            p.x = "some_string";
        }

        return p;
    });
    big_array.reduce((sum, p)=> sum + p.value, 0);
}

function f2() {
    var P = function () {
        this.value = 1;
        this.x = null;
    };
    var big_array = new Array(10000000).fill(1).map((x, index)=> {
        p = new P();
        if (index > 5000000) {
            p.x = "some_string";
        }

        return p;
    });
    big_array.reduce((sum, p)=> sum + p.value, 0);
}


(function perform(){
    var start = performance.now();
    f1();
    var duration = performance.now() - start;

    console.log('duration of f1  ' + duration);


    start = performance.now();
    f2();
    duration = performance.now() - start;

    console.log('duration of f2 ' + duration);
})()

This is the result for Chrome and Firefox.

       FireFox     Chrome
 --------------------------
 f1      6,400      11,400
 f2      1,700       9,600   

As we can see, the performance improvements are very different between the two.