Typical error with variable of the cycle
The example shows: first key variable is defined and assigned some value. Then in the cycle variable with the same name is defined, but the cycle doesn’t define its scope of variables and overlaps defined earlier key variable, and when developer will decide to use key value after the cycle, he will receive a name of the last property of obj object.
How to avoid global variables? The answer is simple, you should put your module into the function, for which there is a known approach – using of “Immediate Function”.
Using of Immediate Function
Undeclared and Undefined
Difference between Undeclared and Undefined
Hoisting or variable raising effect is one of the most unobvious features of the language, it works the following way: no matter where you defined a variable inside the function, even before return, it will be defined as if you have done this at the very beginning of the function, however, first it will have undefined value until later in the code it won’t be assigned a value. The example shows a typical error caused by hoisting effect.
Error is caused by variable raising effect
There is a practice that helps to avoid such problems – to define variables at the beginning of the function independently that hoisting will become obvious that shows an example below. However, it is believed that this is contrary to the rule which states that variables should be defined as close as possible to their point of using. Here you will have to decide by yourself what you think is more important in this situation.
Example for avoiding problems with Hoisting
Insidious “this” link
Problem with “this” in callback
To solve this problem there are two common approaches. The first one works even in the oldest browsers without additional means – this is saving of “this” value in variable and using of this variable in callback via closure as shows an example below.
Solution using “this” saving
Using of bind()
Asynchronous calls in cycles
Example of error with asynchronous call in cycle
If you have a compelling need to use a value of cycle variable asynchronously, you can solve this task using Immediate Function, as shown in the example below.
How you can use cycle variable asynchronously
Planning of iterations
Using of such approach means that the next cycle iteration is put to the common queue of functions for execution and gives an opportunity to execute another functions also put in this queue, including callbacks and event handlers. This begs the question, why not just use setInterval, why such difficulties? Unfortunately setInterval function doesn’t wait for the completion of its callback and puts it in the queue of functions execution after certain interval again, which can obviously lead to the queue overflow in case of long work of code in callback.
There is one common misconception that array elements can be deleted by “delete” operator, this is absolutely wrong. When using this operator an array element is not deleted, but its value just becomes “undefined” that forms a kind of “holes” in the arrays and may cause some errors in the array processing.
Prototype and inheritance model
Diagram of prototype inheritance
Except the prototypes there is also a concept of constructor, this is a function, which creates a new object specifying for it a prototype, constructor, from which the object was created and if necessary initializes object properties, and the first two actions are done automatically at the language level using “new” operator. Below there is an example of defining constructor and prototype, which it will assign to its objects.
Example of constructor
Usually in the prototype values by default are specified for object properties, but here you should be careful too, because if you will specify as value objects or arrays, then their changes in one object, created with this prototype, will be affected on all the rest of objects, created with this prototype. If you want to avoid this, initialize objects and arrays in the constructor itself, not in the prototype.
Of course if you will assign to the object a value by property with the name, which is similar with the name in prototype, then this won’t change a prototype and just will create the same property in the object itself that is like it will override the prototype value in the object itself. In the example below is represented an object, created with this constructor.
Structure of the object created by constructor
Also there is a way of creating a chain of prototypes or multilevel prototype inheritance, for this there is a known realization of inheritance function, shown below.
Function of building a chain of prototypes
It is worth noting that you should use this function before defining of ctor.prototype properties, otherwise this function will clear them. This way of building a chain of prototypes is absolutely correct and allows using instanceof operator with created objects. Here is a short example of function and object using, which was obtained when using resulting constructor.
Using of inherits function
Received object using received constructor
Example of error when not using Egyptian brackets
Useful literature and materials
- David Flanagan “The Definitive Guide”
- Mozilla Developer Network
- Google Closure Compiler