JavaScript Guide, Part 3: Variables, Data Types, Expressions, Objects
- Transfer
- Tutorial
Today, in the third part of the translation of the JavaScript guide, we will talk about different ways of declaring variables, data types, expressions, and features of working with objects.
→ Part 1: first program, language features, standards
→ Part 2: code style and program structure
→ Part 3: variables, data types, expressions, objects
→ Part 4: functions
→ Part 5: arrays and cycles
→ Part 6: exceptions, semicolon, template literals
→ Part 7: strict mode, this keyword, events, modules, mathematical calculations
→ Part 8: an overview of the features of the ES6 standard
→Part 9: ES7, ES8 and ES9 features overview
A variable is an identifier that has been assigned a value. The variable can be accessed in the program, working in this way with the value assigned to it.
By itself, a variable in JavaScript does not contain information about the type of values that will be stored in it. This means that by writing a variable, for example, a string, you can later write a number into it. Such an operation will not cause an error in the program. That is why JavaScript is sometimes called "untyped" language.
Before using a variable, it must be declared using the keyword
Prior to the ES2015 standard, using a keyword
If this construction is omitted
So, if the so-called strict mode (strict mode) is included, the similar will cause an error. If strict mode is not enabled, an implicit variable declaration will occur and it will be assigned to the global object. In particular, this means that a variable implicitly declared in this way in a certain function will be available after the function completes. Usually, it is expected that variables declared in functions do not “go beyond” their limits. It looks like this:
It will get into the console
Look it, for example, can be as follows:
If, when a variable is declared, it is not initialized, it is not assigned any value to it, the value will automatically be assigned to it
Variables declared using a keyword
You can declare several variables in one expression:
The scope of a variable (scope) is the area of the program in which this variable is available (visible).
A variable initialized with a keyword
If a
It is important to understand that blocks (code areas enclosed in braces) do not create new scopes. A new scope is created when the function is called. The keyword
If a variable is declared in the function code, it is visible to the entire function code. Even if a variable is declared using a
The let keyword appeared in ES2015, which, simply, can be called a “block” version
If the word “let” itself does not seem very clear, one can imagine that the word “let” is used instead. Then the expression
When using a keyword,
For example, this code will cause an error:
If, on initialization of the cycle, the counter
Nowadays, when developing JS-programs based on modern standards, it is quite possible to completely abandon
Values of variables declared using the keywords
In this example, the constant
When they say that an object is written to a variable, they actually mean that an object reference is stored in the variable. This link cannot be changed, and the object to which the link leads can be changed.
The keyword
In a constant
A keyword is
In modern conditions it is quite acceptable to use for the declaration of all entities whose values are not planned to change, the keyword
JavaScript is sometimes called "untyped" language, but this does not correspond to the real state of affairs. True, you can write values of different types to variables, but there are data types in JavaScript, after all. In particular, we are talking about primitive and object data types.
In order to determine the data type of a certain value, you can use the operator
Here is a list of primitive JavaScript data types:
Here, the data type names are given in the form in which the operator returns them
Let's talk about the most commonly used data types from this list.
Type values
In the code, numeric literals are represented as integers and fractional numbers in the decimal number system. To write numbers you can use other methods. For example, if at the beginning of a numeric literal there is a prefix
Here are examples of writing integers:
Here are fractional numbers.
Numeric literals (this behavior is also characteristic of some other primitive types), when attempting to refer to them as objects, automatically, for the duration of the operation, are transformed into corresponding objects, which are called “object wrappers”. In this case, we are talking about the object wrapper
Here, for example, looks like an attempt to access a variable
Object wrapper hint Number
If, for example, you use the method of an
Notice the double brackets after the method name. If you do not put them, the system will not give an error, but instead of the expected output, the console will have something completely different from the string representation of the number 5. The
global object
Type values
String values can be broken down into multiple parts using the backslash (backslash) character.
A string can contain so-called escape sequences interpreted when a string is output to the console. For example, a sequence
Strings can be concatenated using an operator
In ES2015, the so-called patterned literals, or patterned strings, appeared. They are strings enclosed in backquotes (
For example, you can substitute certain values in template literals that are the result of evaluating JavaScript expressions.
Using back quotes simplifies multi-line writing of string literals:
In JavaScript, there are a couple of reserved words used when working with logical values — this is
Logical expressions are used in constructions like
It should be noted that where the expected value
In particular, the false values are the following:
The remaining values are true.
JavaScript has a special value
A value
This value is automatically returned from functions whose result is not explicitly returned, using a keyword
In order to check the value on
All values that are not primitive have an object type. We are talking about functions, arrays, what we call "objects", and many other entities. The basis of all these types of data is the type
Expressions are fragments of code that can be processed and obtained on the basis of the performed calculations a certain value. There are several categories of expressions in JavaScript.
Expressions fall into this category, the result of which are the numbers.
The result of evaluating such expressions is strings.
Literals, constants, references to identifiers fall into this category.
This also includes some key words and JavaScript constructs.
In logical expressions, logical operators are used, the result of their calculation is logical values.
These expressions allow you to access the properties and methods of objects.
Such expressions are used to call functions or methods of objects.
Above, we have already encountered objects, talking about object literals, calling their methods, accessing their properties. Here we will talk about objects in more detail, in particular, we will consider the mechanism of prototype inheritance and the use of a keyword
JavaScript stands out among modern programming languages in that it supports prototype inheritance. Most object-oriented languages use a class-based inheritance model.
Each JavaScript object has a special property (
Suppose we have an object created using an object literal.
Or we created an object using a constructor
In any of these cases, the prototype of the object
If you create an array, which is also an object, its prototype will be an object
You can check this as follows.
Here we used the property
All properties and methods of the prototype are available to the object that has this prototype. Here, for example, how their list for an array looks.
Array Hint
The basic prototype for all objects is
The
What we saw above is an example of a chain of prototypes.
When trying to access a property or a method of an object, if there is no such property or method of the object itself, they are searched in its prototype, then in the prototype prototype, and so on until the required one is found, or until the prototype chain is not over.
In addition to creating objects using the operator
You can check if a certain object is in the prototype chain of another object using the method
Above, we created new objects using the constructor functions already existing in the language (when they are called, the keyword is used
Here we create a constructor function. When it is called, a new object is created, to which the keyword points
After creating the constructor, we add a function to its prototype, which will output to the console the value of the property of an
In the ES6 standard in JavaScript came such a thing as "class".
Prior to that, JavaScript could only use the above-described prototype inheritance mechanism. This mechanism looked unusual for programmers who came to JS from other languages. Therefore, classes appeared in the language, which, in essence, are “syntactic sugar” for the prototype mechanism of inheritance. That is, objects created in the traditional way, and objects created using classes, have prototypes.
This is what the class declaration looks like.
The class has an identifier that can be used to create new objects using the construct
When creating a new object, a method is called
In a class, you can declare methods. In our case
Classes can extend other classes. Objects created on the basis of such classes will inherit both the methods of the original class and the methods defined in the extended class.
If a class that extends another class (the successor of this class) has a method whose name matches that of the parent class, this method takes precedence over the original one.
When calling a method
The classes do not provide for the presence of variables (properties), the properties created using the classes of objects must be configured in the constructor.
Inside a class, you can access the parent class using a keyword
The methods described in the class can be invoked by referring to objects created on the basis of this class, but not to the class itself. Static (
There is no built-in mechanism in JavaScript that allows declaring private (private, private) methods. This limitation can be circumvented, for example, by using closures.
In a class, you can describe methods by prefixing them with keywords
In this article we talked about variables, data types, expressions, and working with objects in JavaScript. The topic of our next material will be features.
Dear readers! If you have been writing to JS for a long time, please tell us how you feel about the appearance of the keyword class in the language.
→ Part 1: first program, language features, standards
→ Part 2: code style and program structure
→ Part 3: variables, data types, expressions, objects
→ Part 4: functions
→ Part 5: arrays and cycles
→ Part 6: exceptions, semicolon, template literals
→ Part 7: strict mode, this keyword, events, modules, mathematical calculations
→ Part 8: an overview of the features of the ES6 standard
→Part 9: ES7, ES8 and ES9 features overview
Variables
A variable is an identifier that has been assigned a value. The variable can be accessed in the program, working in this way with the value assigned to it.
By itself, a variable in JavaScript does not contain information about the type of values that will be stored in it. This means that by writing a variable, for example, a string, you can later write a number into it. Such an operation will not cause an error in the program. That is why JavaScript is sometimes called "untyped" language.
Before using a variable, it must be declared using the keyword
var
or let
. If we are talking about a constant, a keyword is used const
. It is possible to declare a variable and assign it some value without using these keywords, but this is not recommended.Var var keyword
Prior to the ES2015 standard, using a keyword
var
was the only way to declare variables.var a = 0
If this construction is omitted
var
, the value will be assigned to the undeclared variable. The result of this operation depends on the mode in which the program runs. So, if the so-called strict mode (strict mode) is included, the similar will cause an error. If strict mode is not enabled, an implicit variable declaration will occur and it will be assigned to the global object. In particular, this means that a variable implicitly declared in this way in a certain function will be available after the function completes. Usually, it is expected that variables declared in functions do not “go beyond” their limits. It looks like this:
function notVar() {
bNotVar = 1 //лучше так не делать
}
notVar()
console.log(bNotVar)
It will get into the console
1
, usually no one expects such behavior from the program, the expression bNotVar = 1
does not look like an attempt to declare and initialize a variable, but as an attempt to access a variable that is external to the function of the scope (this is quite normal). As a result, the implicit declaration of variables confuses those who read the code and can lead to unexpected program behavior. Later we will talk about functions and areas of visibility, but in the meantime try to always, when the meaning of a certain expression is to declare a variable, to use specialized keywords. If in this example the body of the function is rewritten as var bNotVar = 1
, then an attempt to start the above code snippet will result in an error message (you can see it in the browser console).Look it, for example, can be as follows:
Uncaught ReferenceError: bNotVar is not defined
. Its meaning is that the program cannot work with a non-existent variable. It is much better, when you first start the program, to see such an error message than to write incomprehensible code that is able to behave unexpectedly. If, when a variable is declared, it is not initialized, it is not assigned any value to it, the value will automatically be assigned to it
undefined
.var a //typeof a === 'undefined'
Variables declared using a keyword
var
can be repeatedly declared again by assigning new values to them (but this can confuse the person who is reading the code).var a = 1
var a = 2
You can declare several variables in one expression:
var a = 1, b = 2
The scope of a variable (scope) is the area of the program in which this variable is available (visible).
A variable initialized with a keyword
var
outside of a function is assigned to a global object. It has a global scope and is accessible from anywhere in the program. If a variable is declared using a keyword var
inside a function, then it is visible only inside this function, being a local variable for it. If a
var
variable is declared in the function, using , the name of which coincides with the name of some variable from the global scope, it will “override” the global variable. That is, when accessing such a variable inside a function, its local variant will be used.It is important to understand that blocks (code areas enclosed in braces) do not create new scopes. A new scope is created when the function is called. The keyword
var
has a so-called functional scope, and not block. If a variable is declared in the function code, it is visible to the entire function code. Even if a variable is declared using a
var
function at the end of a code, it can also be accessed at the beginning of the code, since the JavaScript variable lifting mechanism (hoisting) works. This mechanism "raises" the declaration of variables, but not the operation of their initialization. This can be a source of confusion, so make it a rule to declare variables at the beginning of a function.Let Keyword let
The let keyword appeared in ES2015, which, simply, can be called a “block” version
var
. The scope of variables declared using a keyword let
is limited to the block, operator or expression in which it is declared, as well as nested blocks. If the word “let” itself does not seem very clear, one can imagine that the word “let” is used instead. Then the expression
let color = 'red'
can be translated into English like this: “let the color be red”, and into Russian - like this: “let the color be red”. When using a keyword,
let
you can get rid of the ambiguities that accompany the keyword var
(for example, you will not be able to double, using let
, declare the same variable). Usinglet
outside the function, say, when initializing cycles, does not lead to the creation of global variables. For example, this code will cause an error:
for (let i = 0; i < 5; i++) {
console.log(i)
}
console.log(i)
If, on initialization of the cycle, the counter
i
is announced using the keyword var
, it i
will be available outside the cycle, after it completes the work. Nowadays, when developing JS-programs based on modern standards, it is quite possible to completely abandon
var
and use only keywords let
and const
.▍ Keyword const
Values of variables declared using the keywords
var
or let
can be overwritten. If instead of these keywords is used const
, then a new value cannot be assigned to a constant declared and initialized with its help.const a = 'test'
In this example, the constant
a
cannot be assigned a new value. But it should be noted that if a
is not a primitive value, like a number, but an object, the use of a keyword const
does not protect this object from changes. When they say that an object is written to a variable, they actually mean that an object reference is stored in the variable. This link cannot be changed, and the object to which the link leads can be changed.
The keyword
const
does not make objects immutable. It simply protects against changes references to them, written in the corresponding constants. Here's what it looks like:const obj = {}
console.log(obj.a)
obj.a = 1 //работает
console.log(obj.a)
//obj = 5 //вызывает ошибку
In a constant
obj
, during initialization, a new empty object is written. Attempting to access its property a
, which does not exist, does not cause an error. In the console falls undefined
. After that, we add a new property to the object and try to access it again. This time the value of this property gets to the console 1
. If you uncomment the last line of the example, an attempt to execute this code will result in an error. A keyword is
const
very similar to let
, in particular, it has a block scope. In modern conditions it is quite acceptable to use for the declaration of all entities whose values are not planned to change, the keyword
const
, resorting tolet
only in special cases. Why? The thing is that it is best to strive to use the simplest available designs as possible in order not to complicate the program and avoid mistakes.Data types
JavaScript is sometimes called "untyped" language, but this does not correspond to the real state of affairs. True, you can write values of different types to variables, but there are data types in JavaScript, after all. In particular, we are talking about primitive and object data types.
In order to determine the data type of a certain value, you can use the operator
typeof
. It returns a string indicating the type of the operand.Ри Primitive data types
Here is a list of primitive JavaScript data types:
number
(number)string
(line)boolean
(logical value)null
(special valuenull
)undefined
(special valueundefined
)symbol
(symbol, used in special cases, appeared in ES6)
Here, the data type names are given in the form in which the operator returns them
typeof
. Let's talk about the most commonly used data types from this list.
Type number
Type values
number
in JavaScript are represented as 64-bit double-precision floating-point numbers. In the code, numeric literals are represented as integers and fractional numbers in the decimal number system. To write numbers you can use other methods. For example, if at the beginning of a numeric literal there is a prefix
0x
- it is perceived as a number written in hexadecimal notation. Numbers can also be written in the exponential representation (you can find a letter in such numbers e
). Here are examples of writing integers:
10
5354576767321
0xCC // шестнадцатеричное число
Here are fractional numbers.
3.14
.1234
5.2e4 //5.2 * 10^4
Numeric literals (this behavior is also characteristic of some other primitive types), when attempting to refer to them as objects, automatically, for the duration of the operation, are transformed into corresponding objects, which are called “object wrappers”. In this case, we are talking about the object wrapper
Number
. Here, for example, looks like an attempt to access a variable
a
that contains a numeric literal as an object in the Google Chrome console.Object wrapper hint Number
If, for example, you use the method of an
toString()
object of a typeNumber
, it will return a string representation of the number. The corresponding command that can be executed in the browser console (and in the usual code) looks like this:a.toString()
Notice the double brackets after the method name. If you do not put them, the system will not give an error, but instead of the expected output, the console will have something completely different from the string representation of the number 5. The
global object
Number
can be used as a constructor, creating new numbers with it (though in this form it is almost never used), it can be used as an independent entity, without creating instances of it (that is, some numbers represented with its help). For example, its property Number.MAX_VALUE
contains the maximum numeric value that can be represented in JavaScript.Type string
Type values
string
are sequences of characters. Such values are specified as string literals enclosed in single or double quotes.'A string'
"Another string"
String values can be broken down into multiple parts using the backslash (backslash) character.
"A \
string"
A string can contain so-called escape sequences interpreted when a string is output to the console. For example, a sequence
\n
means a newline character. The backslash character can also be used to add quotes to strings enclosed in the same quotes. Escaping the quotation character with the help of the system \
leads to the fact that the system does not perceive it as a special character.'I\'m a developer'
Strings can be concatenated using an operator
+
."A " + "string"
Pattern Literals
In ES2015, the so-called patterned literals, or patterned strings, appeared. They are strings enclosed in backquotes (
`
) and have some interesting properties.`a string`
For example, you can substitute certain values in template literals that are the result of evaluating JavaScript expressions.
`a string with ${something}`
`a string with ${something+somethingElse}`
`a string with ${obj.something()}`
Using back quotes simplifies multi-line writing of string literals:
`a string
with
${something}`
Type boolean
In JavaScript, there are a couple of reserved words used when working with logical values — this is
true
(true) and false
(false). Comparison operations, such as ==
, ===
, <
, >
, recycled true
or false
. Logical expressions are used in constructions like
if
and while
by helping to control the course of program execution. It should be noted that where the expected value
true
or false
, you can use other values that are automatically regarded by the language as true (truthy) or false (falsy). In particular, the false values are the following:
0
-0
NaN
undefined
null
'' //пустая строка
The remaining values are true.
Type null
JavaScript has a special value
null
that indicates the absence of a value. Similar values are used in other languages.Type undefined
A value
undefined
written to a variable indicates that the variable is not initialized and has no value for it. This value is automatically returned from functions whose result is not explicitly returned, using a keyword
return
. If the function accepts a parameter, which, when called, is not specified, it is also set to undefined
. In order to check the value on
undefined
, you can use the following construction.typeof variable === 'undefined'
▍Objects
All values that are not primitive have an object type. We are talking about functions, arrays, what we call "objects", and many other entities. The basis of all these types of data is the type
object
, and they, although in many ways different from each other, have much in common.Expressions
Expressions are fragments of code that can be processed and obtained on the basis of the performed calculations a certain value. There are several categories of expressions in JavaScript.
Arithmetic expressions
Expressions fall into this category, the result of which are the numbers.
1 / 2
i++
i -= 2
i * 2
String expressions
The result of evaluating such expressions is strings.
'A ' + 'string'
'A ' += 'string'
Primary expressions
Literals, constants, references to identifiers fall into this category.
2
0.02
'something'
true
false
this //контекст выполнения, ссылка на текущий объект
undefined
i //где i является переменной или константой
This also includes some key words and JavaScript constructs.
function
class
function* //генератор
yield //команда приостановки/возобновления работы генератора
yield* //делегирование другому итератору или генератору
async function* //асинхронное функциональное выражение
await //организация ожидания выполнения асинхронной функции
/pattern/i //регулярное выражение
() //группировка
Array and Object Initialization Expressions
[] //литерал массива
{} //объектный литерал
[1,2,3]
{a: 1, b: 2}
{a: {b: 1}}
Boolean expressions
In logical expressions, logical operators are used, the result of their calculation is logical values.
a && b
a || b
!a
Property Access Expressions
These expressions allow you to access the properties and methods of objects.
object.property //обращение к свойству (или методу) объекта
object[property]
object['property']
Object creation expressions
new object()
new a(1)
new MyRectangle('name', 2, {a: 4})
Function Declaration Expressions
function() {}
function(a, b) { return a * b }
(a, b) => a * b
a => a * 2
() => { return 2 }
Call expressions
Such expressions are used to call functions or methods of objects.
a.x(2)
window.resize()
Work with objects
Above, we have already encountered objects, talking about object literals, calling their methods, accessing their properties. Here we will talk about objects in more detail, in particular, we will consider the mechanism of prototype inheritance and the use of a keyword
class
.Рот Prototype inheritance
JavaScript stands out among modern programming languages in that it supports prototype inheritance. Most object-oriented languages use a class-based inheritance model.
Each JavaScript object has a special property (
__proto__
) that points to another object that is its prototype. The object inherits the properties and methods of the prototype. Suppose we have an object created using an object literal.
const car = {}
Or we created an object using a constructor
Object
.const car = new Object()
In any of these cases, the prototype of the object
car
will be Object.prototype
. If you create an array, which is also an object, its prototype will be an object
Array.prototype
.const list = []
//или так
const list = new Array()
You can check this as follows.
car.__proto__ == Object.prototype //true
car.__proto__ == new Object().__proto__ //true
list.__proto__ == Object.prototype //false
list.__proto__ == Array.prototype //true
list.__proto__ == new Array().__proto__ //true
Here we used the property
__proto__
, it does not have to be available to the developer, but you can usually access it. It should be noted that a more reliable way to obtain a prototype of an object is to use the method of a getPrototypeOf()
global object Object
.Object.getPrototypeOf(new Object())
All properties and methods of the prototype are available to the object that has this prototype. Here, for example, how their list for an array looks.
Array Hint
The basic prototype for all objects is
Object.prototype
.Array.prototype.__proto__ == Object.prototype
The
Object.prototype
prototype does not. What we saw above is an example of a chain of prototypes.
When trying to access a property or a method of an object, if there is no such property or method of the object itself, they are searched in its prototype, then in the prototype prototype, and so on until the required one is found, or until the prototype chain is not over.
In addition to creating objects using the operator
new
and applying object literals or array literals, you can create an instance of an object using a method Object.create()
. The first argument passed to this method is the object that will become the prototype of the object created with it.const car = Object.create(Object.prototype)
You can check if a certain object is in the prototype chain of another object using the method
isPrototypeOf()
.const list = []
Array.prototype.isPrototypeOf(list)
Constructor functions
Above, we created new objects using the constructor functions already existing in the language (when they are called, the keyword is used
new
). Such functions can be created independently. Consider an example.function Person(name) {
this.name = name
}
Person.prototype.hello = function() {
console.log(this.name)
}
let person = new Person('Flavio')
person.hello()
console.log(Person.prototype.isPrototypeOf(person))
Here we create a constructor function. When it is called, a new object is created, to which the keyword points
this
in the body of the constructor. We add a property to this object name
and write into it what is passed to the constructor. This object is returned from the constructor automatically. With the help of the constructor function, you can create a set of objects, the properties of name
which will contain what is passed when they are created to the constructor. After creating the constructor, we add a function to its prototype, which will output to the console the value of the property of an
name
object created using this function. All objects created using this constructor will have the same prototype, and therefore use the same function.hello()
. It is easy to check this by creating another object of the type Person
and comparing its function hello()
with the function of the object already in the example (the name of the function in this case is written without brackets).▍Classes
In the ES6 standard in JavaScript came such a thing as "class".
Prior to that, JavaScript could only use the above-described prototype inheritance mechanism. This mechanism looked unusual for programmers who came to JS from other languages. Therefore, classes appeared in the language, which, in essence, are “syntactic sugar” for the prototype mechanism of inheritance. That is, objects created in the traditional way, and objects created using classes, have prototypes.
Class declaration
This is what the class declaration looks like.
class Person {
constructor(name) {
this.name = name
}
hello() {
return 'Hello, I am ' + this.name + '.'
}
}
The class has an identifier that can be used to create new objects using the construct
new ClassIdentifier()
. When creating a new object, a method is called
constructor
and parameters are passed to it. In a class, you can declare methods. In our case
hello()
, this is the method that all objects created on the basis of the class can call. This is how a new object is created using a class Person
.const flavio = new Person('Flavio')
flavio.hello()
Class Based Inheritance
Classes can extend other classes. Objects created on the basis of such classes will inherit both the methods of the original class and the methods defined in the extended class.
If a class that extends another class (the successor of this class) has a method whose name matches that of the parent class, this method takes precedence over the original one.
class Programmer extends Person {
hello() {
return super.hello() + ' I am a programmer.'
}
}
const flavio = new Programmer('Flavio')
flavio.hello()
When calling a method
hello()
in the above example, the string will be returned Hello, I am Flavio. I am a programmer
. The classes do not provide for the presence of variables (properties), the properties created using the classes of objects must be configured in the constructor.
Inside a class, you can access the parent class using a keyword
super
.Static methods
The methods described in the class can be invoked by referring to objects created on the basis of this class, but not to the class itself. Static (
static
) methods can be called by referring directly to the class.Private methods
There is no built-in mechanism in JavaScript that allows declaring private (private, private) methods. This limitation can be circumvented, for example, by using closures.
Getters and Setters
In a class, you can describe methods by prefixing them with keywords
get
or set
. This allows you to create so-called getters and setters - functions that are used to control access to the properties of objects created on the basis of the class. The getter is called when trying to read the value of a pseudo-property, and the setter is called when trying to write a new value to it.class Person {
constructor(name) {
this.userName = name
}
set name(value) {
this.userName = value
}
get name() {
return this.userName
}
}
Results
In this article we talked about variables, data types, expressions, and working with objects in JavaScript. The topic of our next material will be features.
Dear readers! If you have been writing to JS for a long time, please tell us how you feel about the appearance of the keyword class in the language.