JavaScript basics for novice developers

Original author: Cristi Salcescu
  • Transfer
The material, the translation of which we are publishing today, is devoted to the basics of JavaScript and is intended for novice programmers. It can be considered as a small reference book on the basic structures of JS. Here, in particular, we will talk about the data type system, variables, arrays, functions, object prototypes, and some other features of the language.



Primitive data types


JavaScript has the following primitive data types: number, boolean, string, undefined, null. Immediately it should be noted that, when working with primitive data types, for example, with string literals, we, even without carrying out an explicit conversion, will be able to refer to their methods and properties. The point here is that when trying to perform such operations, literals are automatically equipped with the appropriate object wrapper.

▍Number


There is only one type of number in JavaScript — double-precision floating-point numbers. This leads to the fact that the results of the calculation of some expressions are arithmetically incorrect. You may already know that in JS the value of the expression is 0.1 + 0.2not equal 0.3. At the same time, when dealing with integers such problems is not observed, ie 1 + 2 === 3.

JavaScript has an object Numberthat is an object wrapper for numeric values. Objects of a type Numbercan be created either using a view command var a = new Number(10), or you can rely on the automatic behavior of the system described above. This, in particular, allows you to call methods that are stored in Number.prototypein the application to numeric literals:

(123).toString();  //"123"
(1.23).toFixed(1); //"1.2"

There are global functions designed to convert values ​​of other types into a numeric type. This - parseInt(), parseFloat()and construction Number(), which in this case acts as a normal function that performs a type conversion:

parseInt("1")       //1parseInt("text")    //NaNparseFloat("1.234") //1.234Number("1")         //1Number("1.234")     //1.234

If during the operation with numbers you get something that is not a number (during some calculations, or when you try to convert something to a number), JavaScript will not give an error, but will present the result of such an operation as a value NaN(Not-a-Number, not number). In order to check whether a certain value NaN, you can use the function isNaN().

JS arithmetic operations work quite familiarly, but you need to pay attention to the fact that the operator +can perform both the addition of numbers and string concatenation.

1 + 1      //2"1" + "1"  //"11"1 + "1"    //"11"

▍Strings


Strings in JavaScript are sequences of Unicode characters. String literals create, enclosing the text you want to put in them, in double ( "") or single ( '') quotes. As already mentioned, when working with string literals, we can rely on the appropriate object wrapper in which the prototype has many useful methods, among them - substring(), indexOf(), concat().

"text".substring(1,3) //ex
"text".indexOf('x')   //2
"text".concat(" end") //textend

Strings, like other primitive values, are immutable. For example, the method concat()does not modify the existing string, but creates a new one.

▍Logic values


The logical data type in JS is represented by two values ​​- trueand false. The language can automatically convert various values ​​to a logical data type. Thus, false, besides the logical values falseare values of null, undefined, ''(blank), 0and NaN. Everything else, including any objects, represents true values. In the course of performing logical operations, everything that is considered true is converted to true, and everything that is considered false is converted to false. Take a look at the following example. In accordance with the principles outlined above, an empty string will be converted to falseand as a result of the execution of this code, a string will be entered into the console This is false.

let text = '';
if(text) {
  console.log("This is true");
} else {
  console.log("This is false");
}

Objects


Objects are dynamic structures consisting of key-value pairs. Values ​​can have primitive data types, can be objects or functions.

Objects are easiest to create using object literal syntax:

let obj = {
  message : "A message",
  doSomething : function() {}
}

Object properties can, at any time, read, add, edit and delete. Here is how it is done:

  • Reading properties: object.name, object[expression].
  • Writing data to properties (if the property being accessed does not exist, a new property with the specified key is added): object.name = value, object[expression] = value.
  • Removing properties: delete object.name, delete object[expression].

Here are some examples:

let obj = {}; // создание пустого объекта
obj.message = "A message"; // добавление нового свойства
obj.message = "A new message"; // редактирование свойства
delete object.message; // удаление свойства

Objects in the language are implemented as hash tables. A simple hash table can be created using the command Object.create(null):

let french = Object.create(null);
french["yes"] = "oui";
french["no"]  = "non";
french["yes"];//"oui"

If the object needs to be made immutable, you can use the command Object.freeze().

To iterate over all properties of an object, you can use the command Object.keys():

function logProperty(name){
  console.log(name); //имя свойства
  console.log(obj[name]); // значение свойства
}
Object.keys(obj).forEach(logProperty);

▍Comparison of primitive types and objects


In practical work with primitive values, it is possible, as already mentioned, to perceive them as objects that have properties and methods, although they are not objects. Primitive values ​​are immutable, the internal structure of objects can change.

Variables


In JavaScript, variables can be declared using keywords var, letand const.

When using a keyword, varyou can declare a variable, and, if necessary, initialize it with a certain value. If the variable is not initialized, its value is undefined. Variables declared using the keyword varhave a functional scope.

The keyword is letvery similar var, the difference is that variables declared with a keyword lethave a block scope.

Variables declared using the keyword have a block scope.const, which, given that the values ​​of such variables cannot be changed, it would be more correct to call them "constants". A keyword constthat “freezes” the value of a variable declared with its use can be compared with the method Object.freeze()“freezing” objects.

If a variable is declared outside of any function, its scope is global.

Arrays


Arrays in JavaScript are implemented using objects. As a result, speaking of arrays, we are, in fact, discussing objects that are similar to arrays. You can work with array elements using their indices. Numeric indices are converted to strings and used as names to access the values ​​of the elements of the arrays. For example, the design of the form arr[1]is similar to the design of the form arr['1'], and both give access to the same value: arr[1] === arr['1']. In accordance with the above, a simple array declared by a command let arr = ['A', 'B', 'C']is represented as an object of approximately the following form:

{
  '0': 'A',
  '1': 'B',
  '2': 'C'
}

Deleting array elements using the command deleteleaves “holes” in it. In order to avoid this problem, you can use the command splice(), but it works slowly, since, after removing an element, it moves the remaining elements of the array, in fact, shifting them to the beginning of the array, to the left.

let arr = ['A', 'B', 'C'];
delete arr[1];
console.log(arr); // ['A', empty, 'C']console.log(arr.length); // 3

Array methods make it easy to implement data structures such as stacks and queues:

// стек
let stack = [];
stack.push(1);           // [1]stack.push(2);           // [1, 2]
let last = stack.pop();  // [1]
console.log(last);       // 2// очередь
let queue = [];
queue.push(1);           // [1]queue.push(2);           // [1, 2]
let first = queue.shift();//[2]
console.log(first);      // 1

Functions


Functions in JavaScript are objects. Functions can be assigned to variables, stored in objects or arrays, passed as arguments to other functions, and returned from other functions.

There are three ways to declare functions:

  • Classic function declaration (Function Declaration or Function Statement).
  • The use of functional expressions (Function Expression), which are also called functional literals (Function Literal).
  • Using the arrow function syntax (Arrow Function).

▍ Classic function declaration


With this approach to declaring functions, the following rules apply:

  • The first keyword in the function declaration line is function.
  • Functions must be assigned a name.
  • The function can be used in the code that is before its declaration due to the mechanism of lifting the function declaration to the upper part of the scope in which it is declared.

This is what a classic function declaration looks like:

functiondoSomething(){}

▍Functional expressions


When using functional expressions, consider the following:

  • The keyword is functionno longer the first word in the function declaration line.
  • The presence of a function name is optional. It is possible to use both anonymous and named functional expressions.
  • Commands for calling such functions should follow the commands of their declaration.
  • This function can be started immediately after the declaration, using the IIFE syntax (Immediately Invoked Function Expression - immediately called functional expression).

The functional expression looks like this:

let doSomething = function() {}

▍Fireout functions


Arrow functions, in fact, can be considered “syntactic sugar” for creating anonymous functional expressions. It should be noted that such functions do not have their own entities thisand arguments. The declaration of the arrow function looks like this:

let doSomething = () = > {};

▍Ways to call functions


Functions can be called in various ways.

Normal function call


doSomething(arguments)

Function call as object method


theObject.doSomething(arguments)
theObject["doSomething"](arguments)

Function call as constructor


new doSomething(arguments)

Calling a function using the apply () method


doSomething.apply(theObject, [arguments])
doSomething.call(theObject, arguments)

Calling a function using the bind () method


let doSomethingWithObject = doSomething.bind(theObject);
doSomethingWithObject();

Functions can be called with more or fewer arguments than the number of parameters that were specified when they were declared. In the course of the function, the “extra” arguments will be simply ignored (although the function will have access to them), the missing parameters will get the value undefined.

Functions have two pseudo-parameters: thisand arguments.

▍ Keyword this


The keyword thisis the context of the function. The value to which it points depends on how the function was called. Here are the values ​​the keyword takes thisdepending on the way the function is called (they, with code examples, the constructions of which are used here, are described above):

  • The normal function call is window/ undefined.
  • Function call as an object method - theObject.
  • A function call as a constructor is a new object.
  • Function call using the apply()- method theObject.
  • Function call using the bind()- method theObject.

▍ arguments keyword


The keyword argumentsis a pseudo-parameter that gives access to all the arguments used in the function call. It looks like an array, but is not an array. In particular, it has no array methods.

function reduceToSum(total, value){
  return total + value;
}
  
function sum(){
  let args = Array.prototype.slice.call(arguments);
  return args.reduce(reduceToSum, 0);
}
sum(1,2,3);

An alternative to the keyword argumentsis the new syntax of the remaining parameters. In the following example args, this is an array containing everything that was passed to the function when it was called.

functionsum(...args){
  return args.reduce(reduceToSum, 0);
}

ReturnOperator return


A function that does not have an expression returnwill return undefined. Using a keyword return, pay attention to how the automatic semicolon insertion mechanism works. For example, the following function returns not an empty object, but a value undefined:

functiongetObject(){ 
  return 
  {
  }
}
getObject()

In order to avoid such a problem, the opening brace should be placed on the same line as the operator return:

functiongetObject(){ 
  return {
  }
}

Dynamic typing


JavaScript is a language with dynamic typing. This means that specific values ​​are of types, and variables are not. During program execution, values ​​of different types can be written to the same variable. Here is an example of a function that works with values ​​of different types:

function log(value){
  console.log(value);
}
log(1);
log("text");
log({message : "text"});

To determine the type of data stored in a variable, you can use the operator typeof():

let n = 1;
typeof(n);   //numberlet s = "text";
typeof(s);   //stringlet fn = function() {};
typeof(fn);  //function

Single threaded execution model


The JavaScript runtime is single-threaded. This, in particular, is expressed in the impossibility of simultaneously performing two functions (unless we take into account the possibilities of asynchronous code execution, which we do not affect here). In the runtime, there is a so-called Event Queue, which stores a list of tasks that need to be processed. As a result, the problem of interlocking resources is not typical for a single-flow JS execution scheme, so there is no need for a locking mechanism. However, code that enters the event queue must be executed quickly. If you overload with hard work, in the browser application, the main thread, the application page will not react to the user's impact and the browser will offer to close this page.

Exception Handling


JavaScript has a mechanism for handling exceptions. It works according to the principle quite common for such mechanisms: the code that can cause an error is drawn up using the construction try/catch. The code itself is in the block try, errors are processed in the block catch.

It is interesting to note that sometimes JavaScript, in the event of an emergency, does not produce error messages. This is due to the fact that JS did not throw errors before adopting the ECMAScript 3 standard.

For example, in the following code fragment, an attempt to change a “frozen” object will fail, but no exception will be thrown.

let obj = Object.freeze({});
obj.message = "text";

Some of the "silent" errors of JS manifest themselves in strict mode, you can enable it using the design "use strict";.

Prototype system


At the heart of such JS mechanisms as constructor functions, a command Object.create(), a keyword class, is a system of prototypes.
Consider the following example:

let service = {
 doSomething : function() {}
}
let specializedService = Object.create(service);
console.log(specializedService.__proto__ === service); //true

Here, to create an object specializedService, the prototype of which was to make an object service, use the command Object.create(). As a result, it turns out that the method doSomething()can be invoked by referring to the object specializedService. In addition, this means that the property of an __proto__object specializedServicepoints to an object service.

Now create a similar object using the keyword class:

classService{
 doSomething(){}
}
classSpecializedServiceextendsService{
}
let specializedService = newSpecializedService();
console.log(specializedService.__proto__ === SpecializedService.prototype);

Methods declared in the class Servicewill be added to the object Service.prototype. Instances of a class Servicewill have the same prototype ( Service.prototype). All instances will delegate method calls to the object Service.prototype. As a result, it turns out that methods are declared only once, in Service.prototype, after which they are "inherited" by all instances of the class.

ПротA prototype chain


Objects can be "heirs" of other objects. Each object has a prototype whose methods are available to it. If you try to access a property that is not in the object itself, JavaScript will start searching for it in the prototype chain. This process will continue until the property is found, or until the search reaches the end of the chain.

About functional programming in javascript


In JavaScript, functions are first-class objects; the language supports a closure mechanism. This opens the way to the implementation of functional programming techniques in JS. In particular, we are talking about the possibility of using higher-order functions.

A closure is an internal function that has access to variables declared inside the parent function, even after executing the parent function.

A higher order function is a function that can accept other functions as arguments, return functions, or do both.

Functional programming in JS is covered in a variety of publications. If this is interesting to you, here are a few materials on this topic dedicated to first-class functions , composition ,decorators , closures and readability of code written in a functional style.

Results


The power of JavaScript lies in its simplicity. Understanding the basic mechanisms of the language allows a programmer who uses JS to more effectively use these mechanisms and lays the foundation for his professional growth.

Dear readers! What do you think, what features of JavaScript cause the most problems for beginners?


Also popular now: