Reason for using `prototype` instead of` this`

I am using Lightbox2

https://github.com/lokesh/lightbox2/blob/master/js/lightbox.js

And I donโ€™t understand why all the internal elements of Lightbox are prototyped ( Lightbox.prototype.init ), and not just members ( Lightbox.init )?

If they are specific to each lightbox instance, would it be easier to use this.init ?

+6
source share
2 answers

Confused? Do not be ...

Think of it this way:

  • A lightbox is a definition of your class, but it is not an instance.

  • Everything you put directly into the class looks like a static member:

     Lightbox.staticFunc = function() { // "this" will not point to instance object }; 
  • Regardless of what you put on its prototype, this is a common member of the instance:

     Lightbox.prototype.instanceFunc = function() { // "this" will point to object instance so members can be accessed }; 
  • When you instantiate a class, all members of the instance are accessible through the tt this keyword, and static through the class definition:

     var someData = Lightbox.staticFunc(); var l = new Lightbox(); l.instanceFunc(); 

Does this mean you understand the elements of the prototype?

Lightbox code then

The code you were looking for means the following:

 // this is a constructor that accesses instance properties (using "this") // ------ // since properties are accessed via "this.something" means that they are // not shared between instances but are part of one particular instance // ------ function Lightbox(options) { this.options = options; this.album = []; this.currentImageIndex = void 0; this.init(); } // adding an instance method that will be accessible to lightbox object instance // that why it can also access instance members (using "this") // ------ // all functions that are defined on the prototype are shared between // all instances so they consume less resources because not every // object instance created them separately. // ------ Lightbox.prototype.init = function() { this.enable(); return this.build(); }; 

But some parts of this code are a bit confusing ie

 LightboxOptions = (function() { function LightboxOptions() { this.fileLoadingImage = 'images/loading.gif'; this.fileCloseImage = 'images/close.png'; this.resizeDuration = 700; this.fadeDuration = 500; this.labelImage = "Image"; this.labelOf = "of"; } return LightboxOptions; })(); 

LightboxOptions class is contained in the closure of the function, even if it does not define any private data, so the external function of immediate execution can be omitted in this example, having identical results:

 LightboxOptions = function() { this.fileLoadingImage = 'images/loading.gif'; this.fileCloseImage = 'images/close.png'; this.resizeDuration = 700; this.fadeDuration = 500; this.labelImage = "Image"; this.labelOf = "of"; }; 

Of course, it would be possible to define these functions in the constructor using this , but then they will not be used between instances, so each instance of the object will define the same function, therefore, consuming more resources. So this is not the same, although from the execution point it looks the same:

 CustomClass = function() { this.prop = true; }; CustomClass.prototype.method = function() { alert("I'm shared."); }; 

slightly different from:

 CustomClass = function() { this.prop = true; this.method = function() { alert("I'm duplicated in every instance."); }; }; 

It consumes more resources later, while a function is defined for each instance of the object.

... and a little more to completely clear this thing

Suppose we have this class definition:

 var C = function() { this.prop = true; this.method = function() { console.log("Per instance method"); }; } C.prototype.method = function() { console.log("Shared instance method"); }; 

What happens if we call these lines of code

 var a = new C(); var b = new C(); a.method(); b.method(); delete a.method; a.method(); b.method(); 

What do you think will be the result? Should you at least confuse what happens after delete ? Which method will be deleted? For one copy? Common? Both? Well, as it should be, every instance of a method is deleted in an instance of a , so after that it reports that the generic method is being called. But only on a . b still has its own instance method.

Thus, without any additional errors, the output is as follows:

 Per instance method // a.method Per instance method // b.method Shared instance method // a.method Per instance method // b.method 

What about prototype properties

It is different. When you instantiate an object, all of these properties are copied to each object and are not shared. Thus, everything that you do on them within the scope of a certain object will not be reflected by others.

If you delete such a property on a specific object, it will still be available with its initial value, as it was when creating the object.

 var C = new function() {}; C.prototype.prop = 1; var a = new C(); var b = new C(); a.prop = 10; // does not change the value of "b.prop" delete a.prop; // "a.prop" is now back to 1 
+8
source

If they are specific to each instance of the lightbox, would it be easier to use this.init?

They should not therefore be that they put everything in a prototype object. When you use prototype , all methods become available only to you, because they do not become members of the instance.

JavaScript works with the prototype chain, when it sees a method, it searches for the prototype chain until it finds the specified method. This process continues to the final Object if it is not found in the middle.

You should only create instance members (via this ) that you think are reasonable or necessary because they add overhead (computational waste) if you add unnecessary methods using the this , such as instance members.

+4
source

Source: https://habr.com/ru/post/917678/


All Articles