[{{mminutes}}:{{sseconds}}] X
Пользователь приглашает вас присоединиться к открытой игре игре с друзьями .
Sites: Javascript: Dictionary - 2
(0)       Используют 2 человека

Комментарии

Ни одного комментария.
Написать тут
Описание:
-
Автор:
Folder2009
Создан:
1 января 2022 в 20:05 (текущая версия от 13 января 2022 в 21:49)
Публичный:
Нет
Тип словаря:
Фразы
В этом режиме перемешиваться будут не слова, а целые фразы, разделенные переносом строки.
Информация:
-
Содержание:
1 * Operator precedence
2 ^ Description
3 a) if an expression has more than one operator, the execution order is defined by their precedence
4 b) or, in other words, the default priority order of operators
5 c) from school, we all know that the multiplication in the expression 1 + 2 * 2 should be calculated before the addition
6 `that's exactly the precedence thing
7 d) the multiplication is said to have a higher precedence than the addition
8 e) parentheses override any precedence, so if we aren't satisfied with the default order, we can use them to change it
9 `(1 + 2) * 2
10 f) there are many operators in js
11 g) every operator has a corresponding precedence number
12 h) the one with the larger number executes first
13 ^ Description (part 2)
14 a) if the precedence is the same, the execution order is from left to right
15 b) here's an extract from the precedence table
16 `https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
17 `we don't need to remember this, but note that unary operators are higher than corresponding binary ones
18 c) example
19 `unary plus + and unary negation are 17 precedence
20 `exponentiation ** is 16 precedence
21 `multiplication and division are 15 precedence
22 `addition and subtraction are 13 precedence
23 `assignment is 3 precedence
24 d) as we can see, the 'unary plus' has a priority of 17 which is higher than the 13 of 'addition' (binary plus)
25 e) that's why, in the expression "+apples + +oranges", unary pluses work before the addition
26 * Assignment
27 ^ Introduction
28 a) Let's note that an assignment = is also operator
29 b) it's listed in the precedence table with the very low priority of 3
30 c) that's why, when we assign variable, like x = 2 * 2 + 1, the calculations are done first and then the = is evaluated, storing the result in x
31 `let x = 2 * 2 + 1;
32 `alert(x); // 5
33 ^ Assignment = returns a value
34 a) the fact of = being an operator, not a 'magical' language construct has an interesting implication
35 b) all operators in js return a value
36 c) that's obvious for + and -, but also true for =
37 d) the cal x = value writes the value into x and then returns it
38 e) here's a demo that uses an assignment as part of a more complex expression
39 `let a = 1;
40 `let b = 2;
41 `let c = 3 - (a = b + 1);
42 `alert(a); // 3
43 `alert(c); // 0
44 f) in the example above, the result of expression (a = b + 1) is the value which was assigned to a (that is 3)
45 g) it is then used for further evaluations
46 h) funny code, isn't it?
47 ^ Assignment = returns a value (part 2)
48 a) we should understand how it works, because sometimes we see it in js libraries
49 b) although, please don't write the code like that
50 c) such tricks definitely don't make code clearer or readable
51 ^ Chaining Assignments
52 a) another interesting feature is the ability to chain assignments
53 `let a, b, c;
54 `a = b = c = 2 + 2;
55 `alert(a); // 4
56 `alert(b); // 4
57 `alert(c); // 4
58 b) chained assignments evaluate from right to left
59 c) first, the rightmost expression 2 + 2 is evaluated and then assigned to the variables on the left: c, b and a
60 d) at the end, all the variables share a single value
61 e) once again, for the purposes of readability it's better to split such code into few lines
62 `c = 2 + 2;
63 `b = c;
64 `a = c;
65 f) that's easier to read, especially when eye-scanning the code fast
66 ^ Modify-in-place
67 a) we often need to apply an operator to a variable and store the new result in that same variable
68 b) example
69 `let n = 2;
70 `n = n + 5;
71 `n = n * 2;
72 c) this notation can be shortened using the operators += an *=
73 `let n = 2;
74 `n += 5; // now n = 7 (same as n = n + 5)
75 `n *= 2; // now n = 14 (same as n = n * 2)
76 d) short 'modify-and-assign' operator exist for all arithmetical and bitwise operators
77 `/=
78 `-=
79 e) such operators have the same precedence as a normal assignment, so they run after most other calculations
80 `let n = 2;
81 `n *= 3 + 5;
82 `alert(n); // 16 right part evaluated first, same as n *= 8
83 * Increment/Decrement
84 ^ Introduction
85 a) increasing or decreasing a number by one is among the most common numerical operations
86 b) there are special operators for it
87 c) Increment '++' increases a variable by 1
88 `let counter = 2;
89 `counter++; // works the same as counter = counter + 1, but is shorter
90 `alert(counter); // 3
91 d) Decrement '--' decreases a variable by 1
92 `let counter = 2;
93 `counter--; // works the same as counter = counter - 1, but is shorter
94 `alert(counter); // 1
95 ^ Important
96 a) increment/decrement can only be applied to variables
97 b) trying to use it on values like 5++ will give an error.
98 c) the operators ++ and -- can be placed either before or after a variable
99 `when the operators goes after the variable, it is in 'postfix form'
100 ,counter++
101 `the 'prefix form' is when the operator goes before the variable
102 ,++counter
103 d) both of these statements do the same thing: increase counter by 1
104 e) is there any difference? yes, but we can only see it if we use the returned value of ++/--
105 f) let's clarify. as we know, all operators return a value
106 g) increment/decrement is no exception
107 h) the prefix form returns the new value while the postfix form returns the old value
108 `prior to increment/decrement
109 ^ Important (part 2)
110 a) to see the difference, here's an example
111 `let counter = 1;
112 `let a = ++counter; // (*)
113 `alert(a); // 2
114 b) in the line (*), the prefix form ++counter increments counter and returns the new value, 2.
115 `so, the alert shows 2
116 c) now, let's use the postfix form
117 `let counter = 1;
118 `let a = counter++;
119 `alert(a); // 1
120 d) in the line (*), the postfix form counter++ also increments counter but returns the old value (prior to increment)
121 `so, the alert shows 1
122 ^ Summarize
123 a) if the result of increment/ decrement is not used, there's no difference in which form to use
124 `let counter = 0;
125 `counter++;
126 `++counter;
127 `alert(counter); // 2 the lines above did the same
128 b) if we'd like to increase a value and immediately use the result of the operator, we need the prefix form
129 `let counter = 0;
130 `alert(++counter); // 1
131 c) if we'd like to increment a value but use its previous value, we need the postfix form
132 `let counter = 0;
133 `alert(counter++); // 0
134 ^ Increment/Decrement among other operators
135 a) the operators ++/-- can be used inside expressions as well
136 b) their precedence is higher than most other arithmetical operations
137 `let counter = 1;
138 `alert(2 * ++counter); // 4
139 c) compare with
140 `let counter = 1;
141 `alert(2 * counter++); // 2, because counter++ returns the old value
142 d) though technically okay, such notation usually makes code less readable
143 e) one line does multiple things - not good
144 f) while reading code, a fast 'vertical' eye-scan can easily miss sth like counter++ and it won't be obvious that the variable increased
145 g) we advise a style of 'one line - one action'
146 `let counter = 1;
147 `alert(2 * counter);
148 `counter++;
149 ^ Bitwise operators
150 a) bitwise operators treat arguments as 32-bit integer numbers and work on the level of their binary representation
151 b) these operators are not js-specific
152 c) they're supported in most programme languages
153 d) the list of operators
154 `AND (&)
155 `OR (|)
156 `XOR (^)
157 `NOT (~)
158 `LEFT SHIFT (<<)
159 `RIGHT SHIFT (>>)
160 `ZERO-FILL RIGHT SHIFT (>>>)
161 e) these operators are used very rarely, when we need to fiddle on the very lowest (bitwise) level.
162 f) we won't need these operators any time soon, as web development has little use of them, but in some special areas, such as cryptography, they're useful
163 * Comma
164 ^ Introduction
165 a) the comma operator ',' is one of the rarest and most unusual operators
166 b) sometimes, it's used to write shorter code, so we need to know it in order to understand what's going on
167 `let a = (1 + 2, 3 + 4);
168 `alert(a); // 7 (the result of 3 + 4)
169 c) here the first expression 1 + 2 is evaluated and its result is thrown away
170 d) then, 3 + 4 is evaluated and returned as the result
171 ^ Comma has a very low precedence
172 a) please note that the comma operator has very low precedence
173 `lower than =
174 b) so parentheses are important in the example above
175 c) without them a = 1 + 2, 3 + 4 evaluates + first, summing the numbers into a = 3, 7
176 `then, the assignment operator = assigns a = 3, and the rest is ignored
177 d) it's like (a = 1 + 2), 3 + 4
178 e) why do we need an operator that throws away everything except the last expression?
179 f) sometimes, people use it in more complex constructs to put several actions in one line
180 `// three operations in one line
181 `for (a = 1, b = 3, c = a * b; a < 10; a++) {
182 `...
183 `}
184 g) such tricks are used in many js frameworks
185 h) that's why we're mentioning them
186 `but usually they don't improve code readability so we should think well before using them
187 * Tasks Basic operators, maths
188 ^ The postfix and prefix forms
189 a) what are the final values of all variables a, b, c and d after the code below
190 `let a = 1, b = 1;
191 `let c = ++a; // 2 prefix form returns the new value
192 `let d = b++; // 1 postfix form returns the old value
193 ^ Assignment result
194 a) what are the values of a and x after the code below
195 `let a = 2;
196 `let x = 1 + (a *= 2); // 5 calculated as 1 + 4
197 ^ Type Conversions
198 a) what are results of these expressions?
199 `"" + 1 + 0; // '10' the addition "" + 1 converts to '1', then '1' + 0 = '10'
200 `"" - 1 + 0; // -1 the subtraction (like most math operations) only works with numbers, it converts an empty string "" to 0
201 `true + false; // 1
202 `6 / '3'; // 2
203 `"2" * "3"; // 6
204 `4 + 5 + 'px'; // '9px'
205 `"$" + 4 + 5; // '$45'
206 `"4px" - 2; // NaN
207 `"4" - 2; // 2
208 `" -9 " + 5; // -9 5
209 `" -9 " - 5; // -14 the subtraction always converts to numbers, so it makes ' -9 ' a number -9 (ignoring spaces around it)
210 `null + 1; // 1 null becomes 0 after the numeric conversion
211 `undefined + 1; // NaN (undefined becomes NaN after the numeric conversion
212 `" \t
" - 2; // space characters, are trimmed off string start and end when a string is converted to a number.
213 ,here the whole string consists of space characters, such as \t,
and a 'regular' space between them
214 ,so, similarly to an empty string, it becomes 0
215 ^ Fix the addition
216 a) here's a code that asks the user for two numbers and shows their sum
217 b) it works incorrectly. The output in the example below is 12 (for default prompt values)
218 c) why? Fix it. The result should be 3
219 `let a = prompt('First number?', 1); // fix let a = +prompt...
220 `let b = prompt('Second number?', 2); // fix let b = +prompt...
221 `alert(a + b); // or alert(+a + +b); or alet(Number(a) + Number(b));
222 c) explanation
223 `the reason is that prompt returns user input as a string
224 `so variables have values '1' and '2' respectively
225 `what we should do is to convert strings to numbers before +
226 ,for example, using Number() or prepending them with +
227 * from Comment Basic Operators, maths
228 ^ difference between postfix and prefix
229 a) the difference between ++z and z++ is only when one of these expressions is included in an other expression
230 `z = 0;
231 `z++;
232 `alert(z); // 1 no difference between z++ and ++z
233 b) but if we include now theses expressions in another one (alert for example) then we can see the difference
234 `let z = 0;
235 `alert(z++); // 0 difference as alert(++z) is 1
236 * Comparisons
237 ^ Introduction
238 a) we know many comparisons from maths
239 b) in js they're written like this
240 `greater/less than: a > b, a < b
241 `greater/less than or equals: a >= b, a <= b
242 `equals: a == b
243 ,please note the double equality sign == means the equality test
244 ,while a single one = means an assignment
245 `not equals: in maths the notation is crossed out sign of equality
246 `but in js it's written a != b
247 c) in this article we'll learn more about different types of comparisons, how js makes them, including important
248 d) at the end you'll find a good recipe to avoid 'js quirks' - related issues
249 ^ Boolean is the result
250 a) all comparison operators return a boolean value
251 `true - means 'yes', 'correct' or 'the truth'
252 `false - means 'no', 'wrong' or 'not the truth'
253 b) example
254 `alert(2 > 1); // true (correct)
255 `alert(2 == 1); // false (wrong)
256 `alert(2 != 1); // true (correct)
257 c) a comparison result can be assigned to a variable, just like any value
258 `let result = 5 > 4; // assign the result of the comparison
259 `alert(result); // true
260 ^ String comparison
261 a) to see whether a string is greater than another, js uses the so-called 'dictionary' or 'lexicographical' order
262 `in other words, strings are compared
263 b) example
264 `alert('Z' > 'A'); // true
265 `alert('Glow' > 'Glee'); // true
266 `alert('Bee' > 'Be'); // true
267 c) the algorithm to compare two strings is simple
268 `compare the first character of both strings
269 `if the first character from the first string is greater (or less) than the other string's
270 ,the first string is greater (or less) than the second
271 `otherwise, if both string's first characters are the same, compare the second characters the same way
272 `repeat until the end of either string
273 `if both strings end at the same length, then they're equal
274 ,otherwise, the longer string is greater
275 d) in the first example above, the comparison 'Z' > 'A' gets to a result at the first step
276 e) the second comparison 'Glow' and 'Glee' needs more steps as strings are compared character-by-character
277 `G is the same as G
278 `l is the same as l
279 `o is greater than e.
280 ,stop here, the first string is greater
281 * Not a real dictionary, but Unicode order
282 a) the comparison algorithm given above is roughly equivalent to the one used in dictionaries or phone books, but it's not exactly the same
283 b) for instance, case matters.
284 `a capital letter 'A' is not equal to the lowercase 'a'
285 ,because the lowercase character has a greater index in the internal encoding table js uses (Unicode)
286 * Comparison of different types
287 a) when comparing values of different types, js converts the values to numbers
288 `alert('2' > 1); // true, string '2' becomes a number 2
289 `alert('01' == 1); // true, string '01' becomes a number 1
290 b) for boolean values, true becomes 1 and false becomes 0
291 `alert(true == 1); // true
292 `alert(false == 0); // true
293 ^ A funny consequence
294 a) it's possible that at the same time
295 `two values are equal
296 `one of them is true as a boolean and the other one is false as a boolean
297 b) example
298 `let a = 0;
299 `alert(Boolean(a)); // false
300 `let b = '0';
301 `alert(Boolean(b)); // true
302 `alert(a == b); // true
303 c) from js's standpoint, this result is quite normal
304 d) an equality check converts values using the numeric conversion
305 `hence '0' becomes 0, while the explicit Boolean conversion uses another set of rules
306 * Strict equality
307 a) a regular equality check == has a problem.
308 `it can't differentiate 0 from false
309 b) the same thing happens with an empty string
310 `alert("" == false); // true
311 c) this happens because operands of different types are converted to numbers by the equality operator ==.
312 d) an empty string, just like false, becomes a zero.
313 e) what to do if we'd like to differentiate o from false?
314 f) a strict equality operator === checks the equality without type conversion
315 `in other words, if a and b are of different types, then a === b immediately returns false without an attempt to convert them
316 g) let's try it
317 `alert(0 === false); // false, because the types are different
318 h) there's also a strict non-equality operator !== analogous to !=
319 * Comparison with null and undefined
320 ^ Introduction
321 a) there's a non-intuitive behaviour when null or undefined are compared to other values
322 b) for a strict equality check ===
323 `these values are different, because each of them is a different type
324 ,alert(null === undefined); // false
325 c) for a non-strict check ==
326 `there's a special rule
327 `these two are 'sweet couple', but not any other value
328 ,alert(null == undefined);; // true
329 d) for maths and other comparisons < > <= >=
330 `null/undefined are converted to numbers
331 ,null becomes 0
332 ,undefined becomes NaN
333 * Strange result: Null vs 0
334 a) Let's compare null with a zero
335 `alert(null > 0); // false
336 `alert(null == 0); // false
337 `alert(null >= 0); // true
338 b) Mathematically, that's strange
339 `the last result states 'null is greater than or equal to zero'
340 `so in one of the comparisons above it must be true, but they're both false
341 c) The reason is that an equality check == and comparisons > < >= <= work differently
342 d) Comparisons convert null to a number, treating it as 0
343 e) That's why null >= 0 is true and null > 0 is false
344 f) On the other hand, the equality check == for undefined and null is defined such that, without any conversions
345 `they equal each other and don't equal anything else
346 `that's why null == 0 is false
347 * An incomparable undefined
348 a) The value undefined shouldn't be compared to other values
349 `alert(undefined > 0); // false (1)
350 `alert(undefined < 0); // false (2)
351 `alert(undefined == 0); // false (3)
352 b) Why does it dislike zero so much? Always false!
353 c) We get these results because
354 `Comparisons (1) and (2) return false because undefined gets converted to NaN and NaN is a special numeric value which returns false for all comparisons
355 `The equality check (3) returns false because undefined only equals
356 ,null
357 ,undefined
358 ^ Avoid problems
359 a) Why did we go over these examples?
360 `Should we remember these peculiarities all the time?
361 `Well, not really
362 `Actually, these tricky things will gradually become familiar over time, but there's a solid way to avoid problems with them
363 b) Avoid problems
364 `Treat any comparison with undefined/null except the strict equality === with exceptional care
365 `Don't use comparisons >= > < <= with a variable which may be null/undefined, unless you're really sure of what you're doing
366 ,If a variable can have these values, check for them separately
367 * Summary
368 a) Comparison operators return a boolean value
369 b) Strings are compared letter-by-letter in the 'dictionary' order
370 c) When values of different types are compared, they get converted to numbers
371 `with the exclusion of a strict equality check
372 d) The values null and undefined equal == each other and don't equal any other value
373 e) Be careful when using comparisons like > or < with variables that can occasionally be null/undefined
374 `Checking for null/undefined separately is a good idea
375 * Tasks (Comparisons)
376 a) What will be the result for these expressions?
377 `5 > 4; // true
378 `"apple" > "pineapple"; // false (Dictionary comparison where 'a' is smaller than 'p'
379 `"2" > "12"; // true (Dictionary comparison where '2' is greater than '1')
380 `undefined == null; // true (values null and undefined equal each other)
381 `undefined === null; // false (Strict equality is strict. Different types from both sides lead to false)
382 `null == "
0
"; // false (null only equals to undefined)
383 `null === +"
0
"; // false (strict equality of different types)
384 * Conditional branching: if, '?'
385 ^ Introduction
386 a) Sometimes, we need to perform different actions based on different conditions
387 b) To do that, we can use the 'if' statement and the conditional operator '?', that's also called a 'question mark' operator
388 ^ The 'if' statement
389 a) The if(...) statement evaluates a condition in parentheses and, if the result is true, executes a block of code
390 `let year = prompt('In which year was ECMAScript-2015 specification published?', "");
391 `if (year == 20156) alert('You are right!');
392 b) In the example above, the condition is a simple equality check (year == 2015), but it can be much more complex
393 c) If we want to execute more than one statement, we have to wrap our code block inside curly braces
394 `if (year == 2015) {
395 `alert('That's correct!');
396 `alert('You're so smart!');
397 `}
398 d) We recommend wrapping your code block with curly braces {} every time you use an 'if' statement
399 `even if there's only one statement to execute
400 `doing so improves readability
401 * Boolean conversion
402 ^ Introduction
403 a) The if(...) statement evaluates the expression in its parentheses and converts the result to a boolean
404 b) Let's recall the conversion rules from the chapter Type Conversions
405 `A number 0, an empty string "", null, undefined and NaN all become false
406 ,Because of that they're called 'falsy' values
407 `Other values become true
408 ,so they're called 'truthy'
409 c) So, the code under this condition would never execute
410 `if (0) { // 0 is falsy
411 `...
412 `}
413 d) And inside this condition - it always will
414 `if (1) { // 1 is truthy
415 `...
416 `}
417 e) We can also pass a pre-evaluated boolean value to 'if', like this
418 `let cond = (year == 2015); // equality evaluates to true or false
419 `if (cond) {
420 `...
421 `}
422 * The 'else' clause
423 ^ Introduction
424 a) The if statement may contain optional 'else' block.
425 `it executes when the condition is falsy.
426 b) Example
427 `let year = prompt('In which year was the ECMAScript-2015 specification published?', "");
428 `if (year == 2015) {
429 `alert('You guessed it right!);
430 `} else {
431 `alert('How can you be so wrong?'); // any value except 2015
432 `}
433 * Several conditions: 'else if'
434 ^ Introduction
435 a) Sometimes, we'd like to test several variants of a condition
436 b) The 'else if' clause lets us do that
437 `let year = prompt('In which year was the ECMAScript-2015 published?', "");
438 `if (year < 2015) {
439 `alert('Too early!');
440 `} else if (year > 2015) {
441 `alert('Too late!');
442 `} else {
443 `alert('Exactly!');
444 `}
445 c) In the code above JavaScript first checks year < 2015
446 `If that is falsy, it goes to the next condition year > 2015
447 `If that is also falsy, it shows the last alert
448 d) There can be more else if blocks.
449 `The final else is optional
450 * Conditional operator '?'
451 a) Sometimes, we need to assign a variable depending on a condition
452 `let accessAllowed;
453 `let age = prompt('How old are you, "");
454 `if (age > 18) {
455 `accessAllowed = true;
456 `} else {
457 `accessAllowed =false;
458 `}
459 `alert('accessAllower');
460 b) The so-called 'conditional' or 'question mark' operator lets us do that in a shorter and simpler way
461 c) The operator is represented by a question mark '?'
462 `Sometimes, it's called 'ternary', because the operator has three operands
463 `It's actually the one and only operator in js which has that many
464 d) The syntax is
465 `let result = condition ? value1 : value2;
466 e) The condition is evaluated
467 `If it's truthy then value1 is returned, otherwise - value2
468 f) Example
469 `let accessAllowed = (age > 18) ? true : false;
470 `Technically, we can omit the parentheses around age > 18
471 `The question mark operator has a low precedence
472 ,so it executes after the comparison >
473 ^ Conditional operator '?' (part 2)
474 a) This example will do the same thing as the previous one
475 `// the comparison operator 'age > 18' executes first anyway
476 `// no need to wrap it into parentheses
477 `let accessAllowed = age > 18 ? true : false;
478 b) But parentheses make the code more readable, so we recommend using them
479 ^ Please note
480 a) In the example above, you can avoid using the question mark operator because the comparison itself returns true/false
481 `// the same
482 `let accessAllowed = age > 18;
483 * Multiple '?'
484 a) A sequence of question mark operators '?' can return a value that depends on more than one condition
485 `let age = prompt('age?', 18);
486 `let message = (age < 3) ? 'Hi, baby!' :
487 `(age < 18) ? 'Hello!' :
488 `(age < 100) ? 'Greetings!' :
489 `'What an unusual age!';
490 `alert(message);
491 b) It may be difficult at first to grasp what's going on
492 `but after a closer look, we can see that it's just an ordinary sequence of tests
493 c) Explanation
494 `The first question mark checks whether age < 3
495 `If true - it returns 'Hi, baby!'.
496 ,otherwise, it continues to the expression after the colon ':', checking age < 18
497 `If that's true - it returns 'Hello!'
498 ,otherwise, it continues to the expression after the colon ':', checking age < 18
499 `It that's true - it returns 'Greetings!'
500 ,otherwise, it continues to the expression after the colon ':', returning 'What an unusual age!'
501 d) Here's how this looks using if...else
502 `if (age < 3) {
503 `message = 'Hi, baby!';
504 `} else if (age < 18) {
505 `message = 'Hello!';
506 `} else if (age < 100) {
507 `message = 'Greetings!';
508 `} else {
509 `message = 'What an unusual age!';
510 `}
511 * Non-traditional use of '?'
512 a) Sometimes the question mark '?' is used as a replacement for 'if'
513 `let company = prompt('Which company created js?', "");
514 `(company == 'Netscape') ?
515 `alert('Right!') : alert('Wrong!');
516 b) Depending on the condition company == 'Netscape', either the first or the second expression after the '?' gets executed and shows an alert
517 c) We don't assign a result to a variable here
518 `Instead, we execute different code depending on the condition
519 d) It's not recommended to use the question mark operator in this way
520 e) The notation is shorter than the equivalent 'if' statement, which appeals to some programmers
521 `But it is less readable
522 f) Here's the same code using of comparison
523 `let company = prompt('Which company created js?', "");
524 `if (company == 'Netscape') {
525 `alert('Right');
526 `} else {
527 `alert('Wrong');
528 `}
529 g) Our eyes scan the code vertically
530 `Code blocks which span several lines are easier to understand than a long, horizontal instruction set
531 h) The purpose of the question mark operator '?' is to return one value or another depending on its condition
532 `please use it for exactly that
533 `use 'if' when you need to execute different branches of code
534 * Tasks (Conditional branches 'if', '?')
535 ^ if (a string with zero)
536 a) Will alert be shown?
537 `if ('0') {
538 `alert('Hello');
539 `}
540 b) '0' is not empty, so it will be true
541 ^ The name of js
542 a) Using the if... else construct, write the code which asks
543 `"What is the official name of JavaScript?"
544 `If the visitor enters 'ECMAScript', then output 'Right'
545 ,otherwise - output: "You don't know? ECMAScript!"
546 ^ Show the sign
547 a) Using if...else, write the code which gets a number via prompt and then shows in alert
548 `1, if the value is greater than zero
549 `-1, if less than zero
550 `0, if equals zero
551 b) In this task we assume that the input is always a number
552 ^ Rewrite 'if' into '?'
553 a) Rewrite this 'if' using a conditional operator '?'
554 `let result;
555 `if (a + b < 4) {
556 `result = 'Below';
557 `} else {
558 `result = 'Over';
559 `}
560 ^ Rewrite 'if...else' into '?'
561 a) Rewrite 'if...else' using multiple ternary operators '?'
562 b) For readability, it's recommended to split the code into multiple lines
563 `let message;
564 `if (login == 'Employee') {
565 `message = 'Hello';
566 `} else if (login == 'Director') {
567 `message = 'Greetings';
568 `} else if (login == "") {
569 `message = 'No login';
570 `} else {
571 `message = "";
572 `}
573 * Logical Operators
574 ^ Introduction
575 a) There are four logical operators in JS
576 `|| OR
577 `&& AND
578 `! NOT
579 `?? NULLISH COALESCING
580 b) Here we cover the first three
581 c) Although they're called "logical", they can be applied to values of any type, not only boolean.
582 , Their result can also be of any type.
583 ^ || OR
584 a) the OR operator is represented with two vertical line symbols
585 ,result = a || b;
586 b) In classical programming the logical OR is meant to manipulate boolean values only.
587 c) If any of its arguments are true, it returns true, otherwise false
588 d) In JS, the operator is a little bit trickier and more powerful.
589 `But first, let's see what happens with boolean values.
590 e) There are four possible logical combinations
591 `alert (true || true); // true
592 `alert (true || false); // true
593 `alert (false || true); // true
594 `alert (false || false); // false
595 f) As we can see, the result is always true except for the case when both operands are false
596 g) If an operand is not a boolean, it's converted to a boolean for the evaluation
597 h) For instance, the number 1 is treated as true, the number 0 as false
598 `if (1 || 0) { // works just like if (true || false)
599 `alert ( 'truthy!' );
600 `}
601 ^ || OR (part 2)
602 a) Most of the time, OR || is used in an if statement to test if any of the given conditions is true
603 `let hour = 9;
604 `if (hour < 10 || hour > 18) {
605 `alert ( 'The office is closed.' );
606 `}
607 b) We can pass more conditions
608 `let hour = 12;
609 `let isWeekend = true;
610 `if (hour < 10 || hour > 18 || isWeekend) {
611 `alert ( 'The office is closed.' ); // It is the weekend
612 `}
613 ^ OR || finds the first truthy value
614 a) The logic described above is somewhat classical
615 b) Now, let's bring in the 'extra' features of JS
616 c) The extended algorithm works as follows
617 d) Given multiple OR'ed values
618 `result = value1 || value2 || value3;
619 e) The OR operator does the following
620 `Evaluates operands from left to right
621 `For each operand, converts it to boolean
622 `If the result is true, stops and returns the original value of that operand
623 `If all operands have been evaluated (i.e. all were false), returns the last operand
624 f) A value is returned in its original form, without the conversion
625 `In other words, a chain of OR || returns the first truthy value or the last one if no truthy value is found
626 g) For instance
627 `alert( 1 || 0 ); // 1 is truthy
628 `alert( null || 1 ); // 1 is the first truthy value
629 `alert( null || 0 || 1 ); // 1 is the first truthy value
630 `alert( undefined || null || 0 ); // 0 all falsy, returns the last value
631 ^ OR || Finds the first truthy value (part 2)
632 a) This leads to some interesting usage compared to a 'pure, classical, boolean-only OR'
633 b) Getting the first truthy value from a list of variables or expressions
634 `For instance, we have firstName, lastName and nickName variables, all optional (i.e. can be undefined or have falsy values)
635 `Let's use OR || to choose the one that has the data and show it (or 'Anonymous' if nothing set)
636 ,let firstName = "";
637 ,let lastName = "";
638 ,let nickName = "SuperCoder";
639 ,alert( firstName || lastName || nickName || 'Anonymous'); // SuperCoder
640 `If all variables were falsy, 'Anonymous' would show up
641 c) Short-circuit evaluation
642 `Another feature of OR || operator is the so-called 'short-circuit' evaluation
643 `It means that || processes its arguments until the first truthy value is reached, and then the value is returned immediately, without even touching the other argument
644 `The importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment of a function call
645 `In the example below, only the second message is printed
646 ,true || alert('not printed');
647 ,false || alert('printed');
648 `In the first line, the OR || operator stops the evaluation immediately upon seeing true, so the alert isn't run.
649 `Sometimes, people use this feature to execute commands only if the condition on the left part is falsy
650 ^ && (AND)
651 a) The ANS operator is represented with 2 ampersands &&
652 `result = a && b;
653 b) In classical programming, AND returns true if both operands are truthy and false otherwise
654 c) alert (true && true); // true
655 `alert (true && false); // false
656 `alert (false && true); // false
657 `alert (false && false); // false
658 d) An example with if
659 `let hour = 12;
660 `let minute = 30;
661 `if (hour == 12 && minute == 30) {
662 `alert('The time is 12:30');
663 `}
664 e) Just as with OR, any value is allowed as an operand of AND
665 `if (1 && 0) { // evaluated as true && false
666 `alert('Won't work, because the result is falsy');
667 `}
668 ^ AND '&&' finds the first falsy value
669 a) Given multiple AND'ed values
670 `result = value1 && value2 && value3;
671 b) The AND && operator does the following
672 `Evaluates operands from left to right
673 `For each operand, converts it to a boolean.
674 ,If the result is false, stops and returns the original value of that operand
675 ,If all operands have been evaluated (i.e. all were truthy), returns the last operand
676 `In other words, AND returns the first falsy value or the last value if none were found
677 c) The rules above are similar to OR.
678 `The difference is that AND returns the first falsy value while OR returns the first truthy one.
679 d) Examples
680 `// if the first operand is truthy, AND returns the second operand
681 `alert(1 && 0); // 0
682 `alert(1 && 5); // 5
683 `// if the first operand is falsy, AND returns it
684 `// The second operand is ignored
685 `alert(null && 5); // null
686 `alert(0 && 'no matter what'); // 0
687 e) We can also pass several values in a row.
688 `See how the first falsy one is returned
689 `alert(1 && 2 && null && 3); // null
690 f) When all values are truthy, the last value is returned
691 `alert(1 && 2 && 3); // 3
692 ^ Precedence of AND && is higher than OR ||
693 a) So the code a && b || c && d is essentially the same as if the && expressions were in parentheses
694 `(a && b) || (c && d)
695 ^ Don't replace 'if' with '||' or '&&'
696 a) Sometimes, people use the AND && operator as a 'shorter way to write if'
697 b) For instance
698 `let x = 1;
699 `(x > 0) && alert('Greater than zero');
700 c) The action in the right part of && would execute only if the evaluation reaches it.
701 `That is, only if (x > 0) is true.
702 d) So we basically have an analogue for
703 `let x = 1;
704 `if (x > 0) alert('Greater than zero');
705 e) Although, the variant with && appears shorter, 'if' is more obvious and tends to be a little bit more readable
706 f) So we recommend using every construct for its purpose
707 `use 'if' if we want 'if' and use '&&' if we want AND
708 * ! (NOT)
709 ^
710 a) The boolean NOT operator is represented with an exclamation sign !
711 b) The syntax is pretty simple
712 `result = !value;
713 c) The operator accepts a single argument and does the following
714 `Converts the operand to boolean type: true/false.
715 `Returns the inverse value
716 d) For instance
717 `alert(!true); // false
718 `alert(!0); // true
719 e) A double NOT !! is sometimes used for converting a value to a boolean type
720 `alert(!!'non-empty sting'); // true
721 `alert(!!null); // false
722 f) That is, the first NOT converts the value to boolean and returns the inverse, and the second NOT inverses it again.
723 `In the end, we have a plain value-to-boolean conversion
724 g) There's a little more verbose way to do the same thing -- a built-in boolean function
725 `alert( Boolean('non-empty string')); // true
726 `alert( Boolean(null)); // false
727 h) The precedence of NOT is the highest of all logical operators
728 `so it always executes first, before && or ||
729 * Tasks (Logical operators)
730 ^ What is the code below going to output?
731 a) alert(null || 2 || undefined); // 2 (the first truthy value)
732 ^ What's the result of OR'ed alerts?
733 a) What will the code below output?
734 `alert( alert(1) || 2 || alert (3) ); // first 1, then 2
735 b) The call to alert doesn't return a value
736 `In other words, it returns undefined
737 c) The first OR || evaluates its left operand alert(1)
738 `That shows the first message with 1
739 d) The alert returns undefined
740 `so OR goes on to the second operand searching for a truthy value
741 e) The second operand 2 is truthy
742 `so the execution is halted
743 `2 is returned and then shown by the outer alert
744 f) There will be no 3, because the evaluation doesn't reach alert(3)
745 ^ What is this code going to show?
746 a) alert(1 && null && 2); // null, because it's the first falsy value from the list
747 ^ What is the result of AND'ed alerts?
748 a) alert( alert(1) && alert(2) ); // the answer 1, and then undefined
749 `The call to alert returns undefined
750 ,it just shows a message, so there's no meaningful return
751 `Because of that, && evaluates the left operand (outputs 1), and immediately stops, because undefined is a falsy value
752 `And && looks for a falsy value and returns it, so it's done
753 ^ The result of OR AND OR
754 a) What will the result be?
755 `alert(null || 2 && 3 || 4); // the answer 3
756 b) The precedence of AND && if higher than ||, so it executes first
757 c) The result of 2 && 3 = 3, so the expression becomes
758 null || 3 || 4
759 `Now the result is the first truthy value
760 ^ Check the range between
761 a) Write an 'if' condition to check that 'age' is between 14 and 90 inclusively
762 b) 'Inclusively' means that 'age' can reach the edges 14 or 90
763 c) if (age >= 14 && age <= 90)
764 ^ Check the range outside
765 a) Write an 'if' condition to check that 'age' is NOT between 14 and 90 inclusively
766 b) Create two variants
767 `The first one using NOT '!'
768 `The second one without it
769 c) The first variant
770 `if (age < 14 || age > 90);
771 d) The second variant
772 `if (!(age >= 14 && age <= 90));
773 ^ A question about 'if'
774 a) Which of these alerts are going to execute?
775 b) What will the results of the expressions be inside if(...)?
776 c) Tasks
777 `if (-1 || 0) alert('first');
778 `if (-1 && 0) alert('second');
779 `if (null || -1 && 1) alert('third');
780 d) The answer: the first and the third will execute
781 e) Details
782 `// Runs
783 ,// The result of -1 || 0 = -1, truthy
784 `// Doesn't run
785 ,// -1 && 0 = 0, falsy
786 ,if (-1 && 0) alert('second');
787 `// Executes
788 ,// Operator && has a higher precedence than ||
789 ,// so -1 && 1 executes first, giving us the chain
790 ,// null || -1 && 1 -> null || 1 -> 1
791 ,if (null || -1 && 1) alert('third');
792 ^ Check the login
793 a) Write the code which asks for a login with prompt
794 b) If the visitor enters 'Admin', then prompt for a password, if the input is an empty line or Esc - show 'Canceled', if it's another string -- then show 'I don't know you'
795 c) The password is checked as follows
796 `If it equals 'TheMaster', then show 'Welcome'
797 `Another string -- show 'Wrong password'
798 `For an empty string or cancelled input, show 'Canceled'
799 d) The schema
800 `Begin -> Who's there? -> Cancel || Other || Admin
801 ,Admin -> Password -> (Cancel -> Canceled) || (Other -> Wrong password) || (TheMaster -> Welcome)
802 e) Please, use nested 'if' blocks
803 `Mind the overall readability of the code
804 f) Hint: passing an empty input to a prompt returns an empty string "".
805 `Pressing Esc during a prompt returns null
806 g) Decision
807 `let currentUserName = prompt("Who's there?", '');
808 `if (currentUserName === 'Admin') {
809 `let pass = prompt('Password?', '');
810 `if (pass === 'TheMaster') {
811 `alert('Welcome!');
812 `} else if (pass === null || pass === '') {
813 `alert('Canceled');
814 `} else {
815 `alert('Wrong password');
816 `}
817 `} else if (currentUserName === null || currentUserName === '') {
818 `alert("Canceled");
819 `} else {
820 `alert("I don't know");
821 `}
822 h) Note the vertical indents inside the 'if' blocks.
823 `They're technically nore required, but make the code more readable
824 * Nullish coalescing operator '??'
825 ^ Introduction
826 a) This is a recent addition to the language
827 `Old browsers may need polyfills
828 b) The nullish coalescing operator is written as two question marks '??'
829 c) As it treats treats null and undefined similarly, we'll use a special term here, in this article
830 d) We'll say that an expression is 'defined' when it's neither null nor undefined
831 e) The result of a ?? b is
832 `if 'a' is defined, then 'a'
833 `if 'a' isn't defined, then 'b'
834 f) In other words, ?? returns the first argument if it's not null/undefined.
835 `Otherwise, the second one
836 g) The nullish coalescing operator isn't anything completely new
837 `It's just a nice syntax to get the first 'defined' value of the two
838 ^ Introduction (part 2)
839 a) We can rewrite result = a ?? b using the operators that we already know, like this
840 `result = (a !== null && a !== undefined) ? a : b;
841 b) Now it should be absolutely clear what ?? does
842 `Let's see where it helps
843 c) The common use case for ?? is to provide a default value for a potentially undefined variable
844 d) For example, here we show user if defined, otherwise Anonymous
845 `let user;
846 `alert(user ?? 'Anonymous'); // Anonymous (user not defined)
847 e) We can also use a sequence of ?? to select the first value from a list that isn't null/undefined
848 f) Let's say we have a user's data in variables firstName, lastName or nickName
849 `All of them may be not defined, if the user decided not to enter a value
850 g) We'd like to display the user name using one of these variables, or show 'Anonymous' if all of them aren't defined
851 `Let's use the ?? operator for that
852 ^ Introduction (part 3)
853 a) let firstName = null;
854 `let lastName = null;
855 `let nickName = 'Supercoder';
856 `// Shows the first defined value
857 `alert(firstName ?? lastName ?? nickName ?? 'Anonymous'); // Supercoder
858 ^ Comparison with ||
859 a) The OR || operator can be used in the same way as ??
860 b) For example, in the code above we could replace ?? with || and still get the same result
861 `let firstName = null;
862 `let lastName = null;
863 `let nickName = 'Supercoder';
864 `// Shows the first truthy value
865 `alert(firstName || lastName || nickName || 'Anonymous'); // Supercoder
866 c) Historically, the OR || operator was there first
867 `It exists since the beginning of JS
868 `So developers were using it for such purposes for a long time
869 d) On the other hand, the nullish coalescing operator ?? was added to JS only recently
870 `And the reason for that was that people weren't quite happy with ||
871 e) The important difference between them is that
872 `|| returns the first truthy value
873 `?? returns the first defined value
874 f) In other words, || doesn't distinguish between false, 0, an empty string "" and null/undefined
875 `They're all the same -- falsy values
876 `If any of these is the first argument of ||, then we'll get the second argument as the result
877 g) In practice though, we may want to use default value only when the variable is null/undefined
878 `That is, when the value is really unknown/not set
879 ^ Comparison with || (part 2)
880 a) For example, consider this
881 `let height = 0;
882 `alert(height || 100); // 100
883 `alert(height ?? 100); // 0
884 b) The height || 100 checks height for being a falsy value, and it's 0, falsy indeed
885 `So the result of || is the second argument, 100
886 c) The height ?? 100 checks height for being null/undefined, and it's not
887 `So the result is height 'as is', that is 0
888 d) In practise, the zero height is often a valid value, that shouldn't be replaced with the default
889 `So ?? does just the right thing
890 * Precedence (??)
891 ^ Introduction
892 a) The precedence of the ?? operator is about the same as ||, just a bit lower
893 `5 ?? against 6 ||
894 b) That means that, just like ||, the nullish coalescing operator ?? is evaluated before = and ?, but after most other operations, such as +, *
895 c) So if we'd like to choose a value with ?? in an expression with other operators, consider adding parentheses
896 `let height = null;
897 `let width = null;
898 `// important: use parentheses
899 `let area = (height ?? 100) * (width ?? 50);
900 `alert(area); // 5000
901 d) Otherwise, if we omit parentheses, then as * has the higher precedence than ??, it would execute first, leading to incorrect results
902 `// Without parentheses
903 `let area = height ?? 100 * width ?? 50;
904 `// ... works the same as this (probably not what we want):
905 `let area = height ?? (100 * width) ?? 50;
906 * Using ?? with && or ||
907 ^
908 a) Due to safety reasons, JS forbids using ?? together with && and || operators, unless the precedence is explicitly specified with parentheses
909 b) The code below triggers a syntax error
910 `let x = 1 && 2 ?? 3; // Syntax error
911 c) The limitation is surely debatable, it was added to the language specification with the purpose to avoid programming mistakes,
912 when people start to switch from || to ??
913 d) Use explicit parentheses to work around it
914 `let x = (1 && 2) ?? 3; // works
915 `alert(x); // 2
916 * Summary (??)
917 ^
918 a) The nullish coalescing operator ?? provides a short way to choose the first 'defined value from a list'
919 b) It's used to assign default values to variables
920 `// Set height = 100, if height is null or undefined
921 `height = height ?? 100;
922 c) The operator ?? has a very low precedence, only a bit higher than ? and =
923 `So consider adding parentheses when using it in an expression
924 d) It's forbidden to use it with || or && without explicit parentheses
925 * Loops: while and for
926 ^ Introduction
927 a) We often need to repeat actions
928 b) For example, outputting goods from a list one after another or just running the same code for each number from 1 to 10
929 c) Loops are a way to repeat the same code multiple times
930 ^ The 'while' loop
931 a) while (condition) {
932 `// code
933 `// so-called 'loop body'
934 `}
935 b) While the condition is truthy, the code from the loop body is executed
936 d) For instance, the loop below outputs 'i' while i < 3
937 `let i = 0;
938 `while (i < 3) { // shows 0, then 1, then 2
939 `alert(i);
940 `i++;;
941 `}
942 e) A single execution of the loop body is called an iteration.
943 `The loop in the example above makes three iterations
944 f) If i++ was missing from the example above, the loop would repeat (in theory) forever.
945 g) In practise, the browser provides ways to stop such loops
946 `And in server-side JS, we can kill the process
947 ^ The 'while' loop (part 2)
948 a) Any expression or variable can be a loop condition, not just comparisons
949 `The condition is evaluated and converted to a boolean by while
950 b) For instance, a shorter way to write while (i != 0) is while (i)
951 `let i = 3;
952 `while (i) { // when i becomes 0, the condition becomes falsy, and the loop stops
953 `alert (i);
954 `i--;
955 `}
956 ^ Curly braces are not required for a single-line body
957 a) If the loop body has a single statement, we can omit the curly braces {...}
958 `let i = 3;
959 `while (i) alert(i--);
960 * The 'do...while' loop
961 ^
962 a) The condition check can be moved below the loop body using the do...while syntax
963 `do {
964 `// loop body
965 `} while (condition)
966 b) The loop will first execute the body, then check the condition, and, while it's truthy, execute it again and again
967 c) For example
968 `let i = 0;
969 `do {
970 `alert(i);
971 `i++;
972 `} while (i < 3);
973 d) This form of syntax should only be used when you want the body of the loop to execute at least once regardless of the condition being truthy
974 - Usually, the other form is preferred:
975 `while (...) {...}
976 * The 'for' loop
977 ^
978 a) The 'for' loop is more complex, but it's also the most commonly used loop
979 - It looks like this
980 `for (begin; condition; step) {
981 `// loop body
982 `}
983 b) Let's learn the meaning of these parts by example
984 - The loop below runs alert(i) for i from 0 up to (but not including) 3
985 `for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
986 `alert(i);
987 `}
988 c) Let's examine the 'for' statement part-by-part
989 - part
990 `begin
991 ,let i = 0; // Executes once upon entering the loop
992 `condition
993 ,i < 3; // Checked before every loop iteration. If false, the loop stops
994 `body
995 ,alert(i); // Runs again and again while the condition is truthy
996 `step
997 ,i++; // Executes after the body on each iteration
998 d) The general loop algorithm works like this
999 - Run begin
1000 `-> (if condition -> run body and run step)
1001 `-> (if condition -> run body and run step)
1002 `-> (if condition -> run body and run step)
1003 `-> ...
1004 e) That is, 'begin' executes once, and then it iterates
1005 - after each 'condition' test, 'body' and 'step' are executed
1006 f) If you're a new to loops, it could help to go back to the example
1007 and reproduce how it runs step-by-step on a piece of paper
1008 ^ The 'for' loop (part 2)
1009 a) Here's exactly what happens in our case
1010 - // for (let i = 0; i < 3; i++) alert (i)
1011 - // run begin
1012 `let i = 0;
1013 - // if condition -> run body and run step
1014 `if (i < 3) { alert(i); i++ }
1015 - // if condition -> run body and run step
1016 `if (i < 3) { alert(i); i++ }
1017 - // if condition -> run body and run step
1018 `if (i < 3) { alert(i); i++ }
1019 - // finish, because now i == 3
1020 ^ Inline variable declaration
1021 a) Here, the 'counter' variable i is declared right in the loop
1022 - This is called an 'inline' variable declaration
1023 - Such variables are visible only inside the loop
1024 b) for (let i = 0; i < 3; i++) {
1025 - alert(i); // 0, 1, 2
1026 - }
1027 - alert(i); // error, no such variable
1028 c) Instead of defining a variable, we could use an existing one
1029 - let i = 0;
1030 - for (i = 0; i < 3; i++) {
1031 - alert(i);
1032 - }
1033 - alert(i); // 3, visible, because declared outside of the loop
1034 ^ Skipping parts
1035 a) Any part of 'for' can be skipped
1036 b) For example, we can omit begin if we don't need to do anything at the loop start
1037 c) Like here
1038 - let i = 0; // we have i already declared and assigned
1039 - for (; i < 3; i++) { // no need 'for' begin
1040 - alert(i); // 0, 1, 2
1041 - }
1042 d) We can also remove the 'step' part
1043 - let i = 0;
1044 - for (; i < 3;) {
1045 - alert(i++);
1046 - }
1047 e) This makes the loop identical to while (i < 3)
1048 f) We can actually remove everything, creating an infinite loop
1049 - for (;;) {
1050 - // repeats without limits
1051 - }
1052 g) Please note that the two 'for' semicolons ';' must be present
1053 - Otherwise, there would be a syntax error
1054 ^ Breaking the loop
1055 a) Normally, a loop exits when its condition becomes falsy
1056 b) But we can force exits at any time using the special 'break' directive
1057 c) For example, the loop below asks the user for a series of numbers, 'breaking' when no number is entered
1058 - let sum = 0;
1059 - while (true) {
1060 - let value = +prompt('Enter a number', "");
1061 - if (!value) break; // (*)
1062 - sum += value;
1063 - }
1064 - alert('Sum: ' + sum);
1065 d) The 'break' directive is activated at the line (*) if the user enters an empty line or cancels the input.
1066 e) It stops the loop immediately, passing control to the first line after the loop.
1067 - Namely, 'alert'
1068 e) The combination 'infinite loop + 'break' as needed' is great for situations when a loop's condition must be checked not in the beginning or end of the loop, but in the middle or even in several places of its body
1069 ^ Continue to the next iteration
1070 a) The 'continue' directive is a 'lighter version' of 'break'
1071 b) It doesn't stop the whole loop
1072 c) Instead, it stops the current iteration and forces the loop to start a new one (if the condition allows)
1073 d) We can use it if we're done with the current iteration and would like to move on to the next one
1074 e) The loop below uses 'continue' to output only odd values
1075 - for (let i = 0; i < 10; i++) {
1076 - // if true, skip the remaining part of the body
1077 - if (i % 2 == 0) continue;
1078 - alert(i); // 1, then 3, 5, 7, 9
1079 - }
1080 f) For even values of 'i', the 'continue' directive stops executing the body and passes control to the next iteration of 'for' (with the next number)
1081 g) So the alert is only called for odd values
1082 ^ The 'continue' directive helps decrease nesting
1083 a) A loop that shows odd values could look like this
1084 - for (let i = 0; i < 10; i++) {
1085 - if (i % 2) {
1086 - alert(i);
1087 -}
1088 -}
1089 b) From a technical point of view, this is identical to the example above
1090 c) Surely, we can just wrap the code in an 'if' block instead of using 'continue'
1091 d) But as a side-effect, this created one more level of nesting (the alert call inside the curly braces)
1092 e) If the code inside of 'if' no longer than a few lines, that may decrease the overall readability
1093 ^ No 'break/continue' to the right side of '?'
1094 a) Please note that syntax constructs that are not expressions can't be used with the ternary operator '?'
1095 b) In particular, directives such an 'break/continue' aren't allowed there
1096 c) For example, if we take this code
1097 - if (i > 5) {
1098 - alert(i);
1099 - } else {
1100 - continue;
1101 - }
1102 d) And rewrite it using a question mark '?'
1103 - (i > 5) ? alert(i) : continue; // continue isn't allowed here
1104 e) It stops working
1105 - there's a syntax error
1106 f) This is just another reason not to use the question mark operator ? instead of if
1107 * Labels for break/continue
1108 ^ Part 1
1109 a) Sometimes we need to break out from multiple nested loops at once
1110 b) For example, in the code below we loop over 'i' and 'j', prompting for the coordinates (i, j) from (0, 0) to (2, 2)
1111 - for (let i = 0; i < 3; i++) {
1112 - for (let j = 0; j < 3; j++) {
1113 - let input = prompt(`Value at coords (${1}, ${j}`, "");
1114 - // what if we want to exit from here to Done (below)?
1115 - }
1116 - }
1117 - alert('Done');
1118 c) We need a way to stop the process if the user cancels the input
1119 d) The ordinary 'break' after 'input' would only break the inner loop
1120 e) That's not sufficient - labels, come to the rescue
1121 f) A label is an identifier with a colon before a loop
1122 - labelName: for (...) {
1123 - ...
1124 - }
1125 ^ Labels for break/continue (Part 2)
1126 a) The 'break <labelName> statement in the loop below breaks out to the label
1127 - outer: for (let i = 0; i < 3; i++) {
1128 - for (let j = 0; j < 3; J++) {
1129 - let input = prompt(`Value at coords (${i}, ${j})`, "");
1130 - // if an empty string or canceled, then break out of both loops
1131 - if (!input) break outer; // (*)
1132 - // do something with the value
1133 - }
1134 - }
1135 - alert('Done');
1136 b) In the code above, break outer looks upwards for the label named 'outer' and breaks out of that loop
1137 c) So the control goes straight from (*) to alert('Done')
1138 d) We can also move the label onto a separate line
1139 - outer:
1140 - for (let i = 0; i < 3; i++) {...}
1141 e) The 'continue' directive can also be used with a label.
1142 f) In this case, code execution jumps to the next iteration of the labeled loop.
1143 ^ Labels do not allow to 'jump' anywhere
1144 a) Labels don't allow us to jump into an arbitrary place in the code
1145 b) For example, it's impossible to do this
1146 - break label; // jump to the label below (doesn't work)
1147 - label: for (...)
1148 c) A break directive must be inside a code block
1149 d) Technically, any labelled code block will do, e.g.:
1150 - label: {
1151 - // ...
1152 - break label; // works
1153 - // ...
1154 - }
1155 e) Although, 99,9% of the time 'break' is used inside loops, as we've seen in the examples above
1156 f) A 'continue' is only possible from inside a loop
1157 ^ Summary
1158 a) We covered 3 types of loops
1159 - while -- The condition is checked before each iteration
1160 - do..while -- The condition is checked after each iteration
1161 - for (;;) -- The condition is checked before each iteration, additional settings available
1162 b) To make an 'infinite' loop, usually the 'while(true)' construct is used.
1163 - Such a loop, just like any other, can be stopped with the 'brea' directive
1164 c) If we don't want to do anything in the current iteration and would like to forward to the next one, we can use the 'continue' directive
1165 d) 'break/continue' support labels before the loop
1166 - A label is the only way for 'break/continue' to escape a nested loop to go to an outer one.
1167 * Tasks (Loops)
1168 ^ Last loop value
1169 a) What is the last value alerted by this code? Why?
1170 - let i = 3;
1171 - while (i) {
1172 - alert(i--);
1173 - }
1174 b) Answer
1175 - Every loop iteration decreases 'i' by 1
1176 - The check while(i) stops the loop when i = 0
1177 - Hence, the steps of the loop form the following sequence ('loop unrolled')
1178 c) Answer (continue)
1179 - let i = 3;
1180 - alert(i--); // shows 3, decreases i to 2
1181 - alert(i--); // shows 2, decreases i to 1
1182 - alert(i--); // shows 1, decreases i to 0
1183 - // done, while(i) check stops the loop
1184 ^ Which values does the while loop show?
1185 a) For every loop iteration, write down which value it outputs and then compare it with the solution
1186 b) Both loops 'alert' the same values, or not?
1187 - The prefix form ++1
1188 `let i = 0;
1189 `while (++i < 5) alert (i);
1190 - The postfix form 1++
1191 `let i = 0;
1192 `while (i++ < 5) alert (i);
1193 c) Answer. The task demonstrates how postfix/prefix forms can lead to different results when used in comparisons
1194 - From 1 to 4
1195 `The first value is i = 1, because ++i first increments i and then returns the new value
1196 `So the first comparison is 1 < 5 and then 'alert' shows '1'
1197 `Then follow 2, 3, 4 -- the values show up one after another
1198 `The comparison always uses the incremented value, because ++ is before the variable
1199 `Finally, i = 4 is incremented to 5, the comparison while(5 < 5) fails, and the loop stops
1200 `So 5 is not shown
1201 - From 1 to 5
1202 `The first value is again i = 1.
1203 `The postfix form of i++ increments 'i' and then returns the old value, so the comparison i++ < 5 will use i = 0 (contrary to i++ < 5)
1204 `But the alert calls is separate
1205 `It's another statement which executes after the increment and the comparison
1206 `So it gets the current i = 1
1207 `Then follow 2, 3, 4
1208 `Let's stop on i = 4
1209 `The prefix form ++i would increment it and use 5 in the comparison
1210 `But here we have the postfix form i++
1211 `So it increments 'i' to 5, but returns the old value
1212 `Hence the comparison is actually while(4 < 5) - true, and the control goes on to alert
1213 `The value i = 5 is the last one, because on the next step while(5 < 5) is false
1214 ^ Which values get shown by the 'for' loop
1215 a) For each loop write down which values it is going to show. Then compare with the answer
1216 b) Both loops alert same values or not?
1217 - The postfix form
1218 `for (let i = 0; i < 5; i++) alert(i);
1219 - The prefix form
1220 `for (let i = 0; i < 5; ++i) alert(i);
1221 c) The answer: from 0 to 4 in both cases
1222 - That can be easily deducted from the algorithm of 'for'
1223 `Execute once i = 0 before every thing (begin)
1224 `Check the condition i < 5
1225 `If 'true' -- executes the loop body alert(i), and then i++
1226 - The increment i++ is separated from the condition i < 5
1227 `That's just another statement
1228 - The value returned by the increment is not used here, so there's no difference between ++i and i++

Связаться
Выделить
Выделите фрагменты страницы, относящиеся к вашему сообщению
Скрыть сведения
Скрыть всю личную информацию
Отмена