Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why declare an instance property in prototype instead of constructor?

I completely understand why it's better to use the prototype instead of the constructor to define a class method, (i.e. Use of 'prototype' vs. 'this' in JavaScript?) However, I recently came across a HashMap class that defines the count property in the prototype and the map property in the constructor:

js_cols.HashMap = function(opt_map, var_args) {

    /**
     * Underlying JS object used to implement the map.
     * @type {!Object}
     * @private
     */
    this.map_ = {};

    /...
}

/**
 * The number of key value pairs in the map.
 * @private
 * @type {number}
 */
js_cols.HashMap.prototype.count_ = 0;

Are there advantages of declaring an instance property like count in the prototype instead of saying this.count_ = 0; in the constructor? And if so, why not also js_cols.HashMap.prototype.map_ = {};?

Edit: A similar question was asked, Why declare properties on the prototype for instance variables in JavaScript, and "default values" was raised as a use case, but it was not explained why this is more desirable than just defining the default value in the constructor.

like image 998
moon prism power Avatar asked Aug 08 '14 16:08

moon prism power


People also ask

What is the purpose of an instance property?

Instance properties are those properties that are defined inside any class and require an instance that is created with the help of the class name itself. Without creating the instance of the class, we may not be able to access these properties which are defined inside the class.

What is the difference between constructor and prototype?

So what's the difference between constructor and prototype? A short answer is that the constructor is a function that is used to create an object, while the prototype is an object that contains properties and methods that are inherited by objects created from a constructor.

What is the use of prototype constructor in JavaScript?

constructor. The constructor property returns a reference to the Object constructor function that created the instance object. Note that the value of this property is a reference to the function itself, not a string containing the function's name.

Has a prototype constructor property that points back to the constructor itself?

prototype, constructor property. Every function has the "prototype" property even if we don't supply it. The default "prototype" is an object with the only property constructor that points back to the function itself. We can use constructor property to create a new object using the same constructor as the existing one.


3 Answers

I don't think the HashMap class is the best example of the benefits of declaring an instance property in the prototype. Consider instead a Response class:

function Response() {
   this.headers = {};
}
Response.prototype.statusCode = 200;

All instances of Response will share the statusCode of 200 — literally, the same number in memory will be shared across all instances. This makes sense if you expect your server to respond with status code 200 most of the time. Those Requests that need different status codes can overwrite their default statusCode, which creates a new number in memory.

I.e. If you have 10,000 concurrent requests, and 5 of them are 404's, you got away with only having 6 numbers in memory to represent all 10,000 statusCodes.

In summation, it might be worth it to use prototype if you expect a lot of instances to share the same default value most of the time. Otherwise, you can chalk it up to coding style. (Obviously for static properties, always use prototype.)

Note see Lucas's answer for why a property that's an object (e.g. map or headers) can't be in the prototype: all instances would be sharing the same reference, thus any update to that reference would update all instances.

like image 90
moon prism power Avatar answered Oct 06 '22 02:10

moon prism power


It depends on how it is used, are you sure count_ doesn't define the number of hash buckets there are, rather than the exact count of how many items are in the hash? Defining variables in the prototype is good if you expect the value to remain constant and global for all instances of the class, since only memory for one variable is being used regardless of how many class instances you make.

like image 24
Lochemage Avatar answered Oct 06 '22 02:10

Lochemage


It works for count_, but it wouldn't work for map_.

count_ is an integer value, while map_ is an object reference. If a HashMap instance updates count_, it will essentially create a count_ property on its own instance.

But, if it inserts something to the map_, as all instances share the same map_ reference, all instances would end up with the same values in the map. This wouldn't work, and that's why every instance get a different map_ reference in its constructor.

As for the count_ property, it's declared in the prototype just as a default. It would be the same if it was instantiated in the constructor. I guess it's just a matter of coding style.

like image 39
Lucas Trzesniewski Avatar answered Oct 06 '22 01:10

Lucas Trzesniewski