Expressive JavaScript: Program Structure

Original author: Marijn Haverbeke
  • Transfer


My heart shines with a bright red light under my thin, transparent skin, and they have to inject me ten JavaScript blocks to bring me back to life (I respond well to toxins in the blood). From this garbage, your gills will turn pale at once!

_why, Why's (Poignant) Guide to Ruby

In this chapter, we will begin to deal with what can already be called programming. We will expand the use of JavaScript beyond nouns and sentence fragments to more or less meaningful prose.

Expressions and instructions

In the first chapter, we created quantities and applied operators to them, obtaining new quantities. This is an important part of every program, but only a part.

A piece of code, the result of which is a certain quantity, is called an expression. Each value written literally (for example, 22 or “psychoanalysis”) is also an expression. An expression written in parentheses is also an expression, like a binary operator applied to two expressions or a unary operator to one.

This is part of the beauty of the language interface. Expressions may include other expressions in the same way that a complex sentence consists of simple ones. This allows us to combine expressions to create calculations of any complexity.

If an expression is a fragment of a sentence, then an instruction is a complete sentence. A program is just a list of instructions.

The simplest statement is an expression with a semicolon after it. This program:


True, this is a useless program. An expression can only be used to obtain a value that can be used in another expression that encompasses this. The instruction stands by itself and its application changes something in the world of the program. It can display something on the screen (a change in the world), or change the internal state of the machine in such a way that it will affect the instructions that follow it. These changes are called side effects. The instructions in the previous example simply give values ​​1 and true, and immediately throw them away. They have no effect on the world of the program. When the program is running, nothing noticeable happens.

In some cases, JavaScript allows you to omit the semicolon at the end of the statement. In other cases, it is mandatory, or the next line will be regarded as part of the same instruction. The rules according to which you can or cannot omit the semicolon are quite complex and increase the likelihood of mistakes. In this book, we will not omit the semicolon, and I recommend doing the same in our programs until you gain experience.


How does the program store the internal state? How does she remember him? We received new quantities from the old ones, but this did not change the old quantities, and the new ones had to be used immediately, or they disappeared. To capture and store them, JavaScript offers something called a "variable."

var caught = 5 * 5;

And that gives us a second kind of instruction. A special keyword (keyword) varshows that in this statement we declare a variable. It is followed by the name of the variable, and if we immediately want to assign a value to it - the = operator and expression.

The example creates a variable called caught and uses it to capture a number, which is obtained by multiplying 5 and 5.

After the variable is defined, its name can be used in expressions. The value of the variable will be what it currently contains. Example:

var ten = 10;
console.log(ten * ten);
// → 100

Variables can be called any word that is not a key word (such as var). You cannot use spaces. Numbers can also be used, but not the first character in the name. You cannot use punctuation except for the characters $ and _.

A variable is not assigned a value forever. The operator = can be used on existing variables at any time to assign them a new value.

var mood = "лёгкое";
// → лёгкое
mood = "тяжёлое";
// → тяжёлое

Imagine variables not in the form of boxes, but in the form of tentacles. They do not contain meaning - they grab them. Two variables can refer to the same value. The program has access only to the values ​​that they contain. When you need to remember something, you grow a tentacle and hold on to it, or you use an existing tentacle to hold it.

Variables like tentacles

Example. To memorize the amount of money that Vasily owes you, you create a variable. Then, when he pays part of the debt, you give her a new meaning.

var vasyaDebt = 140;
vasyaDebt = vasyaDebt  - 35;
// → 105

When you define a variable without assigning it a value, the tentacle has nothing to hold on to; it hangs in the air. If you request the value of an empty variable, you will get undefined.

A single var statement can contain multiple variables. Definitions must be separated by commas.

var one = 1, two = 2;
console.log(one + two);
// → 3

Key words and reserved words

Words with a special meaning, such as var, are key words. They cannot be used as variable names. There are also a few words “reserved for use” in future versions of JavaScript. They also cannot be used, although in some runtime environments this is possible. Their complete list is quite large.

break case catch continue debugger default delete do else false finally for function if implements in instanceof interface let new null package private protected public return static switch throw true try typeof var void while with yield this

You don’t need to remember them, but keep in mind that an error may lie here if your variable definitions do not work as they should.


The collection of variables and their values, which exists at a particular moment, is called the environment. When the program starts, the environment is not empty. There are always variables that are part of the software standard, and most of the time there are variables that help interact with the surrounding system. For example, the browser has variables and functions for examining the state of a loaded web page and its effect, for reading input from the mouse and keyboard.


Many values ​​from the standard environment have a type function(function). Function - a separate piece of the program that can be used together with other quantities. For example, in the browser, the alert variable contains a function that displays a small window with a message. Use it like this:

alert("С добрым утром!");

Alert dialog

The execution of a function is called a call. You can call a function by writing brackets after an expression that returns the value of the function. Usually you directly use the function name as an expression. Values ​​that can be written inside the brackets are passed to the program code inside the function. In the example, the alert function uses the string given to it to display in the dialog box. Values ​​passed to functions are called function arguments. The alert function requires one argument, but others may require a different number of arguments of different types.

Console.log function

The alert function can be used as a means of output during experiments, but you will soon get tired of closing this window every time. In past examples, we used the console.log function to output values. Most JavaScript systems (including all modern browsers and Node.js) provide a console.log function that outputs values ​​to some output device. In browsers, this is the JavaScript console. This part of the browser is usually hidden - most browsers show it by pressing F12, or Command-Option-I on the Mac. If this does not work, look in the “web console” or “developer tools” menu.

In the examples in this book, the output results are shown in the comments:

var x = 30;
console.log("the value of x is", x);
// → the value of x is 30

Although a dot cannot be used in variable names, it is obviously contained in the name console.log. This is because console.log is not a simple variable. This is an expression that returns the log property of the console variable. We will talk about this in chapter 4.

Return values

Displaying a dialog box or displaying text is a side effect. Many functions are useful because they produce these effects. Functions can also produce values, in which case they don't need a side effect in order to be useful. For example, the Math.max function takes any number of variables and returns the largest value:

console.log(Math.max(2, 4));
// → 4

When a function produces a value, they say that it returns a value. All that produces value is an expression, that is, function calls can be used inside complex expressions. For example, the value returned by the Math.min function (the opposite of Math.max) is used as one of the arguments of the addition operator:

console.log(Math.min(2, 4) + 100);
// → 102

The next chapter describes how to write your own functions.

prompt and confirm

The browser environment contains other functions besides alert, which show pop-ups. You can call up a window with a question and OK / Cancel buttons using the function confirm. It returns a Boolean value - true if OK is clicked, and false if Cancel is clicked.

confirm("Ну что, поехали?");

The function promptcan be used to ask an open question. The first argument is the question, the second is the text the user starts with. You can enter a string of text in the dialog box, and the function will return it as a string.

prompt("Расскажи мне всё, что знаешь.", "...");

These functions are rarely used, because you cannot change the appearance of these windows - but they can be useful for experimental programs.

Managing program execution order

When a program has more than one instruction, they are executed from top to bottom. In this example, the program has two instructions. The first asks for a number, the second, executed by the next, shows its square.

var theNumber = Number(prompt("Выбери число", ""));
alert("Твоё число – квадратный корень из " +  theNumber * theNumber);

The Number function converts a value to a number. We need this because prompt returns a string. There are similar String and Boolean functions that convert values ​​to the corresponding types.

A simple diagram of the direct order of program execution:

Conditional execution

To follow instructions in order is not the only possibility. Alternatively, there is conditional execution, where we choose from two possible paths, based on the Boolean value:

Conditional execution is written using the if keyword. In the simple case, we need some code to be executed only if a certain condition is met. For example, in the previous program, we can count a square only if it was a number that was entered.

var theNumber = prompt("Выбери число ", "");
if (!isNaN(theNumber))
  alert("Твоё число – квадратный корень из " +  theNumber * theNumber);

Now, entering “cheese”, you will not get a conclusion.

The if keyword executes or skips an instruction, depending on the value of the boolean expression. This expression is written after if in brackets, and the necessary instruction follows it.

A function isNaNis a standard JavaScript function that returns true only if its argument is NaN (not a number). The Number function returns NaN if you give it a string that is not a valid number. As a result, the condition is: “fulfill, unless theNumber is a non-number.”

Often you need to write code not only for the case when the expression is true, but also for the case when it is false. The options path is the second arrow of the chart. The else keyword is used with if to create two separate execution paths.

var theNumber = Number(prompt("Выбери число", ""));
if (!isNaN(theNumber))
  alert("Твоё число – квадратный корень из " + theNumber * theNumber);
  alert("Ну ты что число-то не ввёл?");

If you need more different paths, you can use several if / else pairs along the chain.

var num = Number(prompt("Выбери число", "0"));
if (num < 10)
else if (num < 100)

The program checks if num is really less than 10. If yes, selects this branch and displays “Not Enough.” If not, selects another - on which is another if. If the following condition is met, then the number will be between 10 and 100, and “Normal” will be displayed. If not, then the last branch is executed.

The sequence of execution is approximately the following:

While and do loops

Imagine a program that displays all even numbers from 0 to 12. You can write it like this:


It works - but the point of programming is to work less than a computer, and not vice versa. If we needed all the numbers up to 1000, this solution would be unacceptable. We need the possibility of repetition. This type of order control is called a loop.

The loop allows you to go back to some instructions and repeat everything again with the new state of the program. If you combine this with a variable for counting, you can do the following:

var number = 0;
while (number <= 12) {
  number = number + 2;
// → 0
// → 2
//   … и т.д.

An instruction starting with a keyword whileis a loop. The while is followed by an expression in parentheses, and then the statement (the body of the loop) is the same as if. The loop executes the instruction until the expression produces a true result.

In the loop we need to display the value and add to it. If we need to execute several instructions in a loop, we enclose it in braces {}. Curly brackets for instructions are like parentheses for expressions. They group them and turn them into one. A sequence of instructions enclosed in braces is called a block.

Many programmers enclose any loop body in parentheses. They do this for uniformity, and so that you do not need to add and remove brackets if you have to change the number of instructions in the loop. In the book I will not write brackets around single instructions in a loop, because I like brevity. You can do as you please.

The variable number shows how the variable can track program progress. Each time the cycle is repeated, number is increased by 2. Before each cycle, it is compared with 12 to see if the program did everything that was required.

For an example of more useful work, we can write a program for computing 2 to a power of 10. We use two variables: one to track the result, and the second to calculate the number of multiplications. The loop checks to see if the second variable has reached 10, and then updates both.

var result = 1;
var counter = 0;
while (counter < 10) {
  result = result * 2;
  counter = counter + 1;
// → 1024

You can start counter with 1 and check it at <= 10, but for reasons that will become clear later, it is always better to start counters with 0.

The do loop is like a while loop. It differs only in one: the do loop always executes the body at least once, and checks the condition after the first execution. Therefore, the test expression is written after the body of the cycle:

do {
  var name = prompt("Who are you?");
} while (!name);

This program forces you to enter a name. She asks him again and again until she receives something other than an empty string. Adding a "!" turns the value into Boolean and then applies logical negation, and all lines except the empty one are converted to Boolean true.

You probably noticed spaces before some instructions. In JavaScript, this is not necessary - the program will work without them. Even line feeds are not necessary. You can write the program in one line. The role of spaces in blocks is to separate them from the rest of the program. In complex code, where other blocks are found in blocks, it can be difficult to see where one ends and the other begins. Correctly separating them with spaces, you bring the appearance of the code and its blocks into correspondence. I like to separate each block with two spaces, but the tastes differ - some use four, some use tabulation. The more spaces to use, the more noticeable the indent, but the faster the nested blocks run off the right edge of the screen.

For loops

Many cycles are built according to such a pattern as in the example. A counter variable is created, then there is a while loop, where the check expression usually checks to see if we have reached any boundary. At the end of the loop body, the counter is updated.

Since this is such a frequent case, JavaScript has a shorter option, a loop for.

for (var number = 0; number <= 12; number = number + 2)
// → 0
// → 2
//   … и т.д.

This program is equivalent to the previous one. Only now all the instructions related to monitoring the state of the cycle are grouped.

The brackets after for contain two semicolons, dividing the statement into three parts. The first initializes the loop, usually setting the initial value of the variable. The second is an expression of checking whether the cycle should continue. Third - updates the state after each pass. In most cases, this entry is shorter and more understandable than while.

Evaluate 2 ^ 10 with for:

var result = 1;
for (var counter = 0; counter < 10; counter = counter + 1)
  result = result * 2;
// → 1024

Although I did not write curly braces, I separate the body of the loop with spaces.

Loop exit

Waiting until the loop condition becomes false is not the only way to end the loop. A special instruction breakleads to an immediate exit from the cycle.

In the following example, we leave the loop when we find a number greater than 20 and divisible by 7 without a remainder.

for (var current = 20; ; current++) {
  if (current % 7 == 0)
// → 21

The for construct does not have a check part - so the loop will not stop until the break statement fires.

If you do not specify this instruction, or accidentally write a condition that is always fulfilled, the program will freeze in an infinite loop and will never finish the work - usually this is bad.

If you make an endless loop, usually after a few seconds the runtime prompts you to interrupt it. If not, you will have to close the bookmark, or even the entire browser.

The keyword continuealso affects the execution of the loop. When this word occurs in a loop, it immediately proceeds to the next iteration.

Short update of variables

Especially often in cycles, a program needs to update a variable based on its previous state.

counter = counter + 1;

JavaScript has a short entry for this:

counter += 1;

Similar records work for many other operators, for example, result * = 2 for doubling, or counter - = 1 for the countdown.

This allows us to reduce the even number output program:

for (var number = 0; number <= 12; number += 2)

There are even shorter entries for counter + = 1 and counter - = 1: counter ++ and counter--.

Working with variables with switch

Often the code looks like this:

if (variable == "value1") action1();
else if (variable == "value2") action2();
else if (variable == "value3") action3();
else defaultAction();

There is a construct called switchthat simplifies this notation. Unfortunately, the JavaScript syntax in this case is rather strange - often the if / else chain looks better. Example:

switch (prompt("Как погодка?")) {
  case "дождь":
    console.log("Не забудь зонт.");
  case "снег":
    console.log("Блин, мы в России!");
  case "солнечно":
    console.log("Оденься полегче.");
  case "облачно":
    console.log("Иди гуляй.");
    console.log("Непонятная погода!");

You can place any number of labels in a switch block case. The program jumps to the label corresponding to the value of the variable in switch, or to the label defaultif no suitable labels are found. After this, the instructions are executed until the first instruction break- even if we have already passed another mark. Sometimes it can be used to execute the same code in different cases (in both cases the program will recommend a “sunny" and "cloudy" walk). However, it is very easy to forget the break entry, which will lead to the execution of an undesired piece of code.

Name register

Variable names cannot contain spaces, but it is often convenient to use a few words to clearly describe the variable. You can choose from several options:


The first is pretty hard to read. I like the underlines, although they are not very convenient to type. The standard JavaScript functions and most programmers use the latter option - each word with a capital letter, except for the first.

In some cases, for example, in the case of the Number function, the first letter is also capitalized - when you need to select the function as a constructor. We'll talk about designers in chapter 6. Now, just ignore it.


Often the code does not contain all the information that I would like to convey to human readers, or conveys it in an incomprehensible form. Sometimes you feel poetic inspiration, or just want to share thoughts in your program. Comments are used for this.

A comment is text that is written in a program but ignored by a computer. There are two ways to write comments in JavaScript. For a single line comment, you can use two slashes:

var accountBalance = calculateBalance(account);
// Издалека долго
// Течёт река Волга
var report = new Report();
// Течёт река Волга
addToReport(accountBalance, report);
// Конца и края нет

The comment continues only to the end of the line. Code between the characters / * and * / will be ignored along with possible line breaks. This is suitable for including entire information blocks in a program:

Этот город – самый лучший
Город на Земле.
Он как будто нарисован
Мелом на стене.
var myCity = ‘Челябинск’;


Now you know that a program consists of instructions, which themselves may contain instructions. The instructions contain expressions, which may consist of expressions.

Writing down instructions in a row, we get a program that runs from top to bottom. You can modify this thread of execution using conditional (if, else, and switch) statements and loop statements (while, do, and for).

Variables can be used to store pieces of data under a specific name and to track program status. An environment is a set of defined variables. JavaScript systems always add a few standard variables to your environment.

Functions are special variables that include parts of a program. They can be called with the functionName command (argument1, argument2). Such a call is an expression, and can produce a value.


Each exercise begins with a description of the task. Read and try to complete. In difficult situations, refer to the tips. Ready-made solutions to problems can be found on the website of the book . For training to be effective, do not look in the answers until you solve the problem yourself, or at least try to solve it long enough so that you have a slightly headache. There you can write code directly in the browser and execute it.

Triangle in loop

Write a loop that in 7 calls to console.log prints such a triangle:


It will be useful to know that the length of the string can be found by assigning to the variable .length.

var abc = "abc";
// → 3


Write a program that outputs through console.log all digits from 1 to 100, with two exceptions. For numbers divisible by 3, it should output 'Fizz', and for numbers divisible by 5 (but not 3) - 'Buzz'.

When you can, correct it so that it displays "FizzBuzz" for all numbers that are divisible by 3 and 5.

(Actually, this question is suitable for interviews, and they say it allows you to filter out a fairly large number of candidates. Therefore, when you solve this problem, you can praise yourself)

Chess board

Write a program that creates a line containing an 8x8 grid, in which the lines are separated by newline characters. At each position, either a space or #. The result should be a chessboard.

# # # #
 # # # #
# # # #
 # # # #
# # # #
 # # # #
# # # #
 # # # #

When you're done, make the board size variable so that you can create boards of any size.

Also popular now: