Someday, every JavaScript programmer will realize that JS is an object-oriented language. And here he faces some dangers arising from a lack of understanding of the fact that JS is not a language of classes (like Pascal or Tse-two-crosses), but of prototypes.
So, much has already been written about the problem of inheritance (which is not in JS). I will try to tell about a less illuminated, but perhaps more important, pitfall: the competent implementation of the methods.
Programmers are trying to declare classes in their usual form, because of which there are memory leaks and other unpleasant things. In fact, you just need to learn how to use prototypes.
This article is intended primarily for beginners JS-programmers.
Below I will use the concept of "class" in the sense in which it is understood in Pascal or Tse-two-crosses; at least in JS there are no such classes, generally speaking, but something is very similar in form and meaning.
From the very beginning, two basic things become known to everyone:
- class is described by a constructor function;
- methods are properties-functions.
Therefore, programmers begin to write quite naturally:
function Test(){
After that, it seems to be what we wanted: we get the Test class with two properties x (initially 5) and y (initially 3) and the sum method, which calculates the sum of x and y. When constructing, a cell is displayed with an X, a player, and a sum.
But what
really happens? When constructing a Test object, the Test function is called each time. And each time it creates a new anonymous function and assigns it to the sum property! As a result
, each object creates its own, separate method sum . If we create a hundred Test objects, we get somewhere in the memory a hundred sum functions.
Obviously, this can not be done. And it is important to realize this as soon as possible.
After understanding this fact, novice programmers often do the following: create the sum function separately, and assign it to the property in the constructor:
function Test(){
As a result, indeed, the Test_sum function is created only once, and each time a new Test object is constructed, only the sum reference is created.
At the same time, this is an illiterate option. Everything can be done much more beautifully and more correctly using the very basis of JavaScript: prototypes:
function Test(){
We create the sum property not of the Test class, but of its prototype. Therefore, each Test object will have a sum function. Actually, then he and the prototype to describe the things that each object has. Moreover, the usual, non-functional properties would also be logical to drive into the prototype:
function Test(){
The bad thing here is that the declarations of properties and methods go after their use in the constructor. But this will have to accept ...
More here is the unpleasant repetition of Test.prototype. From some point of view, it would be nice to remember that JS is not Ce-two-cross, and we have a proposal with. On the other hand,
many reputable people do not recommend using with at all. Therefore, the
following options should not be used .
Literally immediately, an unpleasant surprise awaits us: this code does not work.
function Test(){
Why does not work - in some way a mystery. Anyway, and the word
prototype will have to be repeated:
function Test(){
The advantage here is in grouping the ads of the entire Test class stuffing into one block - with the exception of the remaining constructor. But even with this you can cope if you remember that a function can be declared in at least three syntaxes:
with(Test=function(){
The result is almost the natural record with which we started, except that the word
this was replaced by
prototype ; Well, and moved to the beginning of "other constructive actions" - as I said, with this, unfortunately, will have to accept.
However, if nothing is needed from the constructor except for creating properties and methods, it turns out that beauty is completely:
with(Test=new Function){
However, let's not forget that the with clause is not recommended. Therefore, in the end we will focus on the
third option ads .