JavaScript basics for novice developers
- 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.
JavaScript has the following primitive data types:
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
JavaScript has an object
There are global functions designed to convert values of other types into a numeric type. This -
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
JS arithmetic operations work quite familiarly, but you need to pay attention to the fact that the operator
Strings in JavaScript are sequences of Unicode characters. String literals create, enclosing the text you want to put in them, in double (
Strings, like other primitive values, are immutable. For example, the method
The logical data type in JS is represented by two values -
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:
Object properties can, at any time, read, add, edit and delete. Here is how it is done:
Here are some examples:
Objects in the language are implemented as hash tables. A simple hash table can be created using the command
If the object needs to be made immutable, you can use the command
To iterate over all properties of an object, you can use the command
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.
In JavaScript, variables can be declared using keywords
When using a keyword,
The keyword is
Variables declared using the keyword have a block scope.
If a variable is declared outside of any function, its scope is global.
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
Deleting array elements using the command
Array methods make it easy to implement data structures such as stacks and queues:
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:
With this approach to declaring functions, the following rules apply:
This is what a classic function declaration looks like:
When using functional expressions, consider the following:
The functional expression looks like this:
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
Functions can be called in various ways.
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
Functions have two pseudo-parameters:
The keyword
The keyword
An alternative to the keyword
A function that does not have an expression
In order to avoid such a problem, the opening brace should be placed on the same line as the operator
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:
To determine the type of data stored in a variable, you can use the operator
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.
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
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.
Some of the "silent" errors of JS manifest themselves in strict mode, you can enable it using the design
At the heart of such JS mechanisms as constructor functions, a command
Consider the following example:
Here, to create an object
Now create a similar object using the keyword
Methods declared in the class
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.
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.
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?
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.2
not equal 0.3
. At the same time, when dealing with integers such problems is not observed, ie 1 + 2 === 3
. JavaScript has an object
Number
that is an object wrapper for numeric values. Objects of a type Number
can 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.prototype
in 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 -
true
and false
. The language can automatically convert various values to a logical data type. Thus, false, besides the logical values false
are values of null
, undefined
, ''
(blank), 0
and 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 false
and 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
, let
and const
. When using a keyword,
var
you 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 var
have a functional scope. The keyword is
let
very similar var
, the difference is that variables declared with a keyword let
have 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 const
that “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
delete
leaves “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
function
no 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
this
and 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:
this
and arguments
.▍ Keyword this
The keyword
this
is 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 this
depending 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()
- methodtheObject
. - Function call using the
bind()
- methodtheObject
.
▍ arguments keyword
The keyword
arguments
is 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
arguments
is 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
return
will 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 specializedService
points 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
Service
will be added to the object Service.prototype
. Instances of a class Service
will 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?