Loops and iterations in JavaScript

Standard loops

loop

There is often a need to execute some lines of code multiple times within a program. This mode of execution is achieved by means of appropriate management structures. Loops and iterations are the basic building block of any program. Standard loops occur in more or less the same form in almost all programming languages. The most used is “for loop”. Special attention should be paid to while loops because there is a possibility that the loop may become infinite due to a bad choice of conditions.

“while” loop

The while statement is executed as long as the condition is TRUE, and if it is not then the loop is exited. This type of loop is most often used when the exact number of elevations of the loop is not known. In case the condition is not met at the very beginning, the loop is not executed once. Before entering the loop, variables are initialized that will be used either in the condition or in the body of the loop. The body of the loop contains the code that forms the condition for remaining in the loop.

This type is called a “pre-test loop” because the condition is executed before the expression block.

Read more

What are JavaScript closures?

Definition and characteristics

closure in debugger

It is a known fact that when a function ends, all its local variables are picked up by the garbage collector and they cease to exist in memory. However, this is not the case for a function that contains a closure function.

Closures are functions that have access to variables that are in the domain of another function. This is most often achieved by embedding the function inside another function (thus defining the “scope chain”), after which the closure gains the ability to remember the reference to variables from the parent domain.

It should be noted that mutable external functions are not deleted upon execution of the function itself, but are kept in memory to be available to the closure function. After the execution of the closure function, the external function is also closed (hence the name “closure“). Until the closures are executed, JavaScript will also store the necessary variables from the domain of other functions, therefore they take up more memory than regular functions. Excessive use of closure can lead to increased memory consumption. The latest JavaScript engines manage to partially free the trapped memory, but it is still recommended to be careful when using closure.

As part of the debugger built into the browser, you can see the closure expression and which value of the variable is “remembered” (see picture).

An example of a standard closure f is

The function b() is nested inside the function a() and along the “scope chain” looks for a variable from the function a(), therefore it is a classic example of a closure function.

Not every nested function is a closure

If the inner function does not use a variable from the outer functions in which it is located (along the “scope chain”), then it is not a closure. See the following example:

Closure remembers variables from outer function even though the outer function has been executed

It is known that after using the return command, the execution of the function and the existence of its variables in the temporary memory are interrupted. However, “Closure” remembers the variables from the outer function even if it returned a value with return.

Closure “remembers” the reference pointed to by the variable

When it is said that the “closure function” has access to a variable, it means that it has access to a certain place in the memory pointed to by that variable, ie. to its reference at the time of calling “closure function“. If at that place in the memory, i.e. reference changes value, closure will always take the latest current value. The following example shows how the internal function “remembers” the reference and uses the current value in memory.

Redeclaring a variable

If, after defining clousure, we assign some other reference (place in memory that stores some value) to the variable that needs closure, clousure will use the reference that was in circulation at the time of defining clousure. In the following example, the function sayHello() at the moment of definition “remembers” a reference to the global variable “myName” (“Dragoljub”). So even though “myName” changes the reference which now contains the value “Marko”, the closure still uses the value “Dargoljub”.

However, this does not mean that the closure remembers the first defined value of a variable, but remembers the defined value of the variable at the time of definitionclosure. So in the following example the function returns “Marko”

NOTE:
When the “new” keyword is used to create an object inside an outer function, IT DOES NOT CREATE A CLOSURE and the new function does not have a reference to the outer function’s local variable as a closure.

Read more

Modular programming with ES6

Features of ES6 modules

es6 module

With the new version of JavaScript ES6 comes integrated support for modular programming.

  • Supports modules placed in files – one module per file
  • Modules are unique instances, each module is executed only once (singleton model).
  • ES6 modules can work both synchronously and asynchronously.
  • Supports “cyclic dependencies”.
  • The syntax is even more compact than CommonJS
  • ES modules have a static structure. Since the module structure is immutable, it is often enough to look at the code and figure out what is being imported where. This is not the case with a dynamic structure, where the code often needs to be executed to see what is being imported. Possible errors can also be found at the time of compilation (with the module bundler), because all actions related to the import and export of modules are determined at that moment.
  • All imported elements are immutable from the importing module. Any operation to assign a value to an imported element would cause an error (TypeError).
  • ES6 does not make a copy of a property but shares a link to that property. This is true even for sharing primitive properties (“number” or “string”). In the following example, we see that if the parent module changes the value of the shared property (the change was made by a method from the parent module!), the module that imported that property “sees” that change.
    EXAMPLE
    budget.js

    main.js

    We import all the elements that were exported from the module “proracun.js”

    If the variable “counter” was used now in some “third” module, it would have the value 2.

Read more

Modular Programming – External Syntax (AMD & CommonJS)

Introduction

External syntaxes are not JavaScript libraries, but appropriate specifications and conventions for defining modules. External syntax can only be used with the help of module loaders that “breathe life” into it. If the loader module supports the syntax, it means that it contains built-in methods that are previously intended to be used through a certain syntax.
The advantage of using these external syntaxes compared to the native ES5 module pattern is that it does not pollute the global domain with module names and that dependencies manager work is enabled.

  • Asynchronous Module Definition (AMD) as its name suggests, supports asynchronous loading of modules, which is convenient for working with modules in the browser.
  • CommonJS loads modules synchronously and is therefore most commonly used to work with server-side modules in a node.js environment. Although it is not planned to work in the browser, with the help of the “module bundler” it is possible to adapt CommonJS to work in the browser.
  • Universal module definition (UMD) is compatible with both AMD and CommonJS definitions and is used mainly if there is a need to load the same module on the server and in the browser.

Explanation:
CommonJS, AMD, or UMD are not JavaScript libraries. These are standardization organizations, such as ECMA (defines the language specification for JavaScript) or W3C (defines JavaScript web APIs, such as DOM or DOM events). The goal of CommonJS or AMD syntax is to define an API for working with modules.

Read more

Modular programming with ES5

Introduction

es5

The ES5 version of JavaScript does not support modules, but regardless of that it is possible to create applications in the manner of modular programming by following certain principles. Modules with their encapsulated code are created using “Immediately-Invoked Function Expressions” or with the constructor function. We simply return the API of the module that should be public inside a function with the reserved word return. This is a simple template and can be deployed anywhere without additional libraries. It is possible to define several modules within one file.

In addition to the above advantages, this approach has its disadvantages:

  • “pollution” of the global domain with module names, although the body of the module is hidden using functions (IIFE) in the local domain.
  • “manually” determining the loading order of modules and the loading order of modules can be quite complicated in large and complex applications.
  • no asynchronous loading possible

These templates are not perfect and have their flaws, but regardless of the flaws, the code is more understandable because it is better organized.

Read more

Introduction to modular programming

Features of modular programming

modular programming cube

The modular programming concept is currently one of the most prevalent concepts in modern Javascript programming. It is based on breaking a large application into smaller, encapsulated, independent pieces of code – modules. The goal of modularity is to reduce complexity according to the “divide and rule” principle. The most significant advantages of modular programming are:

  • a clearer and more understandable application
  • easier control of mutable domains
  • prevented “global domain pollution”
  • code reusability
  • possibility of working on the same project by several different teams or developers doing separate smaller tasks.
  • easier debugging

Read more

What is hoisting?

Introduction

js this

It is often mistakenly thought that JavaScript is an interpreted programming language that is interpreted, i.e. directly executes line by line without prior compiling (translation of the language into machine language). However, JavaScript is a programming language that is compiled when the code is executed (“on the fly“). JavaScript code is compiled every time the code is executed, so the quality and responsiveness of JavaScript as a language mostly depends on the efficiency of the JavaScript engine that compiles it.

Hoisting variables

Declaring and defining a variable are two different processes. “Declaration of a variable” is the process of creating a variable, then defining the name of the variable and providing space for its storage, while “defining a variable” is the process when a variable is assigned a value that is placed in the storage space.

Hoisting declared variables

Variable declaration is executed when the code is compiled, which means that before the execution of even one line of code, the variables are first declared. Within JavaScript, there is a special reserved word “var” that is used to declare a variable. Since the declaration of a variable occurs before the execution of any part of the code, it follows that it is the same as if the variables were declared at the beginning of the code, this principle is called “hoisting” (Sr. lifting).

Read more

Scope

Definition

js this

The term “scope” (variable definition area) is related to the term variable and represents a part of the program code in which a variable is available. The basic characteristic of the definition area is the border of that area. The variable can be accessed only if it is requested within its area of ​​definition, i.e. the variable cannot be accessed if we are outside the scope.

It should be noted that “scope” is not the same as “context”. These two terms are often confused because they have some similarities, but you should know that the term “scope” is a property of a variable, while “context” is a property of program code. During execution, the program passes (enters and exits) through different areas of variable definition (scope), and the variables are then either in “context” or not. “Contex” is similar to the area of ​​definition because it also depends on the position in the program (“lexical context”) or the time of code execution (“execution context”).

Read more

1001 ways to create objects in JavaScript

new Object()

One of the most basic ways is to create an empty object with the new keyword based on the Object() built-in constructor function, and then add properties individually.

Read more

Properties and methods of the Object() constructor

Introduction

Object() is a function that can be considered the “mother” of all objects. All objects in JavaScript are derived from this function. Creating objects is possible in several ways, but the following way best explains the connection between the constructor function and the object:

A constructor function has a number of methods and two properties: “Object.length” (a very strange property that always returns 1) and “Object.prototype”

EXPLANATION:
Functions in javascript are “First class citizen”, therefore they support all operations available to other types. Among other types of functions, they also support the characteristics of objects, so functions and objects have their own properties and methods. One of the most important features of the constructor function is the Object.prototype property, through which the constructor function passes basic properties and methods to all objects in JavaScript.

Read more