Reason for using .prototype in Javascript

What are the technical reasons for using .prototype instead of declaring functions and members inside the object itself. This is easiest to explain with code examples.

What are the advantages of using:

RobsObject = function(data){ this.instanceID = data.instanceID; this._formButton = document.getElementById('formSubmit_' + this.instanceID); if(this._formButton) { //set a click listener that //points to this._onSubmit, this._onSuccess, and this.onFailure } }; RobsObject.prototype = { _onSubmit: function(type, args) { //make an ajax call }, _onSuccess: function(type, args) { //display data on the page }, _onFailure: function(type, args) { //show an alert of some kind }, }; 

How to contrast the declaration of your functions inside an object, for example:

 RobsObject = function(data){ this.instanceID = data.instanceID; this._formButton = document.getElementById('formSubmit_' + this.instanceID); if(this._formButton) { //set a click listener that //points to this._onSubmit, this._onSuccess, and this.onFailure } this._onSubmit = function(type, args) { //make an ajax call } this._onSuccess = function(type, args) { //display data on the page } this._onFailure = function(type, args) { //show an alert of some kind } }; 

Thanks.

Edit:. Many of you have indicated that my functions in the second code snippet must have 'this' in front of them in order to be publicly available. So I added. Just a mistake on my part.

+4
source share
3 answers

All declared in the prototype constructor function are shared by all instances of this constructor function. If you define functions in a constructor function, each instance gets its own copy of the function, which takes memory (and can potentially cause problems when comparing properties between two instances later).

In addition, in your example, functions declared in a constructor function are private to the scope of the function. They cannot be called as member methods in instances. To do this, you will need to assign them to the properties of the object:

 MyObject = functon() { // ... this.myMethod = function() { // ... }; } 

Douglas Crockford has a good record of prototypal inheritance, which is definitely worth checking out: Prototypal inheritance in JavaScript .

UPDATE: a brief description of the prototype

When you create a new object using the constructor function, the value of the prototype property is assigned to the object's prototype object. (Yes, the names are confusing!) This is very similar to assigning a superclass in a cool language (but not quite!) Read Crockford's page!)

 // MyObject constructor function: MyObject = function() { this.a = 1; } // Define an object to use as a prototype. var thePrototype = { b: 2 }; // Assign thePrototype as the prototype object for new instances of MyObject. MyObject.prototype = thePrototype; // Create an instance of MyObject. var x = new MyObject(); // Everything in thePrototype is available to x. console.log(xb); // x prototype is a reference to thePrototype, so updating it affects x. thePrototype.c = 3; console.log(xc); // Setting properties on x always sets them *on x*, even if the property is // defined on the prototype: xb = 0; y = new MyObject(); console.log(xb); console.log(yb); 
+14
source

The answer is memory. If you put members inside the object itself, then EVERY instance of this object will contain (in memory) all members. If you use a prototype, on the other hand, it exists only once, and all instances will access these members as if they were their own.

+3
source

In the first case, an object built using new RobsObject() has the functions _onSubmit() , _onSuccess() as properties. These are the so-called public functions of the object.

In the second case, these functions are not properties of new RobsObject() . However, they will be visible to any of the "public" functions (in your case they are not). In essence, these are private functions.

However, if you wrote your second snippet this way ...

 RobsObject = function(data){ this.instanceID = data.instanceID; this._formButton = document.getElementById('formSubmit_' + this.instanceID); if(this._formButton) { //set a click listener that //points to this._onSubmit, this._onSuccess, and this.onFailure } this._onSubmit = function(type, args) { //make an ajax call } this._onSuccess = function(type, args) { //display data on the page } this._onFailure = function(type, args) { //show an alert of some kind } }; 

The result is the same.

An important difference between the two conventions is that in the first method you cannot define private functions that can be shared between many public functions, as in the second method. The object literal used to define the prototype does not form closures similar to the body of a function.

For instance,

 function MyConstructor() { var myPrivate = function() { } this.myPublic1 = function() { myPrivate(); } this.myPublic2 = function() { myPrivate(); } } 

myPrivate() is a function that is visible to both public functions.

0
source

All Articles