From a668310ee337bd9d604926ad81cb4139a1aeb29c Mon Sep 17 00:00:00 2001 From: fsdude Date: Sun, 24 May 2020 07:54:00 -0300 Subject: [PATCH 01/32] Translation to portuguese done. Source file can be found: https://github.com/javascript-tutorial/en.javascript.info/blob/master/9-regular-expressions/17-regexp-methods/article.md --- .../02-regexp-methods/article.md | 482 +++++++----------- 1 file changed, 184 insertions(+), 298 deletions(-) diff --git a/9-regular-expressions/02-regexp-methods/article.md b/9-regular-expressions/02-regexp-methods/article.md index f66a9c794..6a2ef809e 100644 --- a/9-regular-expressions/02-regexp-methods/article.md +++ b/9-regular-expressions/02-regexp-methods/article.md @@ -1,458 +1,344 @@ -# Methods of RegExp and String +# Métodos de RegExp e String -There are two sets of methods to deal with regular expressions. +Neste artigo, abordaremos vários métodos que funcionam com regexps em profundidade. -1. First, regular expressions are objects of the built-in [RegExp](mdn:js/RegExp) class, it provides many methods. -2. Besides that, there are methods in regular strings can work with regexps. +## str.match(regexp) +O método `str.macth(regexp)` pesquisa correspondências para `regexp` na string `str`. -## Recipes +Possui 3 modos: -Which method to use depends on what we'd like to do. +1. Se a `regexp` não tiver a flag `padrão:g`, ela retornará a primeira correspondências como uma matriz com a captura de grupos e propriedades `index` (posição da correspondência), `input` (string de entrada, igual a `str`): -Methods become much easier to understand if we separate them by their use in real-life tasks. + ```js run + let str = "Eu amo JavaScript"; -So, here are general recipes, the details to follow: + let result = str.match(/Java(Script)/); -**To search for all matches:** + alert( result[0] ); // JavaScript (correspondência completa) + alert( result[1] ); // Script (primeira captura de grupo) + alert( result.length ); // 2 -Use regexp `g` flag and: -- Get a flat array of matches -- `str.match(reg)` -- Get an array or matches with details -- `str.matchAll(reg)`. + // Informação adicional: + alert( result.index ); // 0 (posição da correspondÊncia) + alert( result.input ); // Eu amo JavaScript (string original) + ``` -**To search for the first match only:** -- Get the full first match -- `str.match(reg)` (without `g` flag). -- Get the string position of the first match -- `str.search(reg)`. -- Check if there's a match -- `regexp.test(str)`. -- Find the match from the given position -- `regexp.exec(str)` (set `regexp.lastIndex` to position). +2. Se a `regexp` tiver a flag `padrão:g`, ela retornará uma matriz de todas as correspondências como strings, sem capturar grupos e outros detalhes. + ```js run + let str = "Eu amo JavaScript"; -**To replace all matches:** -- Replace with another string or a function result -- `str.replace(reg, str|func)` + let result = str.match(/Java(Script)/g); -**To split the string by a separator:** -- `str.split(str|reg)` + alert( result[0] ); // JavaScript + alert( result.length ); // 1 + ``` -Now you can continue reading this chapter to get the details about every method... But if you're reading for the first time, then you probably want to know more about regexps. So you can move to the next chapter, and then return here if something about a method is unclear. +3. Se não houver correspondências, não importa se há flag `padrão:g` ou não, `null` é retornado. -## str.search(reg) + Essa é uma nuance importante. Se não há correspondências, não teremos uma matriz vazia, mas `null`. É fácil de cometer um erro esquecendo disso, por exemplo: -We've seen this method already. It returns the position of the first match or `-1` if none found: + ```js run + let str = "Eu amo JavaScript"; -```js run -let str = "A drop of ink may make a million think"; - -alert( str.search( *!*/a/i*/!* ) ); // 0 (first match at zero position) -``` - -**The important limitation: `search` only finds the first match.** - -We can't find next matches using `search`, there's just no syntax for that. But there are other methods that can. - -## str.match(reg), no "g" flag + let result = str.match(/HTML/); -The behavior of `str.match` varies depending on whether `reg` has `g` flag or not. + alert(result); // null + alert(result.length); // Error: Cannot read property 'length' of null + ``` -First, if there's no `g` flag, then `str.match(reg)` looks for the first match only. + Se desejamos que o resultado seja uma matriz, podemos escrever assim: -The result is an array with that match and additional properties: + ```js + let result = str.match(regexp) || []; + ``` -- `index` -- the position of the match inside the string, -- `input` -- the subject string. - -For instance: - -```js run -let str = "Fame is the thirst of youth"; +## str.matchAll(regexp) -let result = str.match( *!*/fame/i*/!* ); +[navegador recente="new"] -alert( result[0] ); // Fame (the match) -alert( result.index ); // 0 (at the zero position) -alert( result.input ); // "Fame is the thirst of youth" (the string) -``` +O método `str.matchAll(regexp)` é uma "nova, melhorada" variante do `str.match`. -A match result may have more than one element. +É usada principalmente para buscar todas as correspondências com todos os grupos. -**If a part of the pattern is delimited by parentheses `(...)`, then it becomes a separate element in the array.** +Existem 3 diferenças em relação ao `match`: -If parentheses have a name, designated by `(?...)` at their start, then `result.groups[name]` has the content. We'll see that later in the chapter [about groups](info:regexp-groups). +1. Ela retorna um objeto iterável com correspondências em vez de uma matriz. Podemos fazer uma matriz regular usando `Array.from`. +2. Cada correspondência é retornada como uma matriz com grupos de captura (o mesmo formate que `str.match` sem a flag `padrão:g`). +3. Se não houver resultados, não retornará `null`, mas um objeto iterável vazio. -For instance: +Exemplo de uso: ```js run -let str = "JavaScript is a programming language"; +let str = '

Olá, mundo!

'; +let regexp = /<(.*?)>/g; -let result = str.match( *!*/JAVA(SCRIPT)/i*/!* ); +let matchAll = str.matchAll(regexp); -alert( result[0] ); // JavaScript (the whole match) -alert( result[1] ); // script (the part of the match that corresponds to the parentheses) -alert( result.index ); // 0 -alert( result.input ); // JavaScript is a programming language -``` +alert(matchAll); // [object RegExp String Iterator], não é matriz, mas é iterável -Due to the `i` flag the search is case-insensitive, so it finds `match:JavaScript`. The part of the match that corresponds to `pattern:SCRIPT` becomes a separate array item. +matchAll = Array.from(matchAll); // matriz agora -So, this method is used to find one full match with all details. +let firstMatch = matchAll[0]; +alert( firstMatch[0] ); //

+alert( firstMatch[1] ); // h1 +alert( firstMatch.index ); // 0 +alert( firstMatch.input ); //

Olá, mundo!

+``` +Se usarmos `for..of` para repetir as correspondências do `matchAll`, então não precisaremos mais do `Array.from`. -## str.match(reg) with "g" flag +## str.split(regexp|substr, limit) -When there's a `"g"` flag, then `str.match` returns an array of all matches. There are no additional properties in that array, and parentheses do not create any elements. +Divide a string usando regexp (ou uma substring) como um delimitador. -For instance: +Podemos usar `split` com strings, desse jeito: ```js run -let str = "HO-Ho-ho!"; - -let result = str.match( *!*/ho/ig*/!* ); - -alert( result ); // HO, Ho, ho (array of 3 matches, case-insensitive) +alert('12-34-56'.split('-')) // matriz de [12, 34, 56] ``` -Parentheses do not change anything, here we go: +Mas podemos dividir por uma expressão regular, do mesmo modo: ```js run -let str = "HO-Ho-ho!"; - -let result = str.match( *!*/h(o)/ig*/!* ); - -alert( result ); // HO, Ho, ho +alert('12, 34, 56'.split(/,\s*/)) // matriz de [12, 34, 56] ``` -**So, with `g` flag `str.match` returns a simple array of all matches, without details.** +## str.search(regexp) -If we want to get information about match positions and contents of parentheses then we should use `matchAll` method that we'll cover below. - -````warn header="If there are no matches, `str.match` returns `null`" -Please note, that's important. If there are no matches, the result is not an empty array, but `null`. - -Keep that in mind to evade pitfalls like this: +O método `str.search(regexp)` retorna a posição da primeira correspondência ou `-1` se nada for encontrado: ```js run -let str = "Hey-hey-hey!"; +let str = "Uma gota de tinta pode fazer um milhão pensar"; -alert( str.match(/Z/g).length ); // Error: Cannot read property 'length' of null +alert( str.search( /tinta/i ) ); // 12 (posição da primeira correspondência) ``` -Here `str.match(/Z/g)` is `null`, it has no `length` property. -```` - -## str.matchAll(regexp) - -The method `str.matchAll(regexp)` is used to find all matches with all details. +**A importante limitação: `search` apenas encontra a primeira correspondência.** -For instance: +Se precisarmos de posições de correspondências mais distantes, devemos usar outros meios, como encontrar todos eles com `str.matchAll(regexp)`. -```js run -let str = "Javascript or JavaScript? Should we uppercase 'S'?"; +## str.replace(str|regexp, str|func) -let result = str.matchAll( *!*/java(script)/ig*/!* ); +Esse é um método genério para buscar e substituir, um dos mais úteis. O canivete suíço para procurar e substituir. -let [match1, match2] = result; - -alert( match1[0] ); // Javascript (the whole match) -alert( match1[1] ); // script (the part of the match that corresponds to the parentheses) -alert( match1.index ); // 0 -alert( match1.input ); // = str (the whole original string) - -alert( match2[0] ); // JavaScript (the whole match) -alert( match2[1] ); // Script (the part of the match that corresponds to the parentheses) -alert( match2.index ); // 14 -alert( match2.input ); // = str (the whole original string) -``` - -````warn header="`matchAll` returns an iterable, not array" -For instance, if we try to get the first match by index, it won't work: +Podemos usá-lo sem regexps, para buscar e substituir uma substring: ```js run -let str = "Javascript or JavaScript??"; - -let result = str.matchAll( /javascript/ig ); - -*!* -alert(result[0]); // undefined (?! there must be a match) -*/!* +// substitui um hífen por dois-pontos +alert('12-34-56'.replace("-", ":")) // 12:34-56 ``` -The reason is that the iterator is not an array. We need to run `Array.from(result)` on it, or use `for..of` loop to get matches. - -In practice, if we need all matches, then `for..of` works, so it's not a problem. - -And, to get only few matches, we can use destructuring: +No entanto há uma armadilha. -```js run -let str = "Javascript or JavaScript??"; - -*!* -let [firstMatch] = str.matchAll( /javascript/ig ); -*/!* +**Quando o primeiro argumento do `replace` é uma string, ele apenas substitui a primeira correspondência** -alert(firstMatch); // Javascript -``` -```` +Você pode ver isso no exemplo acima: apenas o primeiro `"-"` é substituído por `":"`. -```warn header="`matchAll` is supernew, may need a polyfill" -The method may not work in old browsers. A polyfill might be needed (this site uses core-js). +Para encontrar todos os hífens, não precisamos usar a string `"-"`, mas a regexp `padrão:/-/g`, com a flag obrigatória `padrão:g`: -Or you could make a loop with `regexp.exec`, explained below. +```js run +// substitui todos os hífens por um dois-pontos +alert( '12-34-56'.replace( /-/g, ":" ) ) // 12:34:56 ``` -## str.split(regexp|substr, limit) +O segundo argumento é uma string substituta. Podemos usar caracteres especiais: -Splits the string using the regexp (or a substring) as a delimiter. +| Símbolos | Ação na string substituta | +|--------|--------| +|`$&`|insere a correspondência toda| +|$`|insere uma parte da string antes da correspondência| +|`$'`|insere uma parte da string depois da correspondência| +|`$n`|se `n` for um número de 1-2 dígitos, insere o conteúdo do n-ésimo grupo de captura, para detalhes, consulte [](info:regexp-groups)| +|`$`|insere o conteúdo dos parênteses com `name` fornecido, para detalhes, consulte [](info:regexp-groups)| +|`$$`|insere o caractere `$` | -We already used `split` with strings, like this: +Por exemplo: ```js run -alert('12-34-56'.split('-')) // array of [12, 34, 56] -``` - -But we can split by a regular expression, the same way: +let str = "John Smith"; -```js run -alert('12-34-56'.split(/-/)) // array of [12, 34, 56] +// troca nome e sobrenome +alert(str.replace(/(john) (smith)/i, '$2, $1')) // Smith, John ``` -## str.replace(str|reg, str|func) - -This is a generic method for searching and replacing, one of most useful ones. The swiss army knife for searching and replacing. +**Para situações que exigem "inteligentes" substituições, o segundo argumento pode ser uma função** -We can use it without regexps, to search and replace a substring: - -```js run -// replace a dash by a colon -alert('12-34-56'.replace("-", ":")) // 12:34-56 -``` +Isso será chamado para cada correspondência e o valor retornado será inserido como uma substituição. -There's a pitfall though. +A função é chamada com argumentos `func(match, p1, p2, ..., pn, offset, input, groups)`: -**When the first argument of `replace` is a string, it only looks for the first match.** +1. `match` -- a correspondência, +2. `p1, p2, ..., pn` -- conteúdo dos grupos de captura (se existir algum), +3. `offset` -- posição da correspondência, +4. `input` -- a string original, +5. `groups` -- um objeto com grupos nomeados. -You can see that in the example above: only the first `"-"` is replaced by `":"`. +Se não existem parênteses na regexp, terá apenas 3 argumentos: `func(str, offset, input)`. -To find all dashes, we need to use not the string `"-"`, but a regexp `pattern:/-/g`, with an obligatory `g` flag: +Por exemplo, vamos colocar todas as correspondências em maiúsculas: ```js run -// replace all dashes by a colon -alert( '12-34-56'.replace( *!*/-/g*/!*, ":" ) ) // 12:34:56 -``` - -The second argument is a replacement string. We can use special characters in it: - -| Symbol | Inserts | -|--------|--------| -|`$$`|`"$"` | -|`$&`|the whole match| -|$`|a part of the string before the match| -|`$'`|a part of the string after the match| -|`$n`|if `n` is a 1-2 digit number, then it means the contents of n-th parentheses counting from left to right, otherwise it means a parentheses with the given name | +let str = "html e css"; +let result = str.replace(/html|css/gi, str => str.toUpperCase()); -For instance if we use `$&` in the replacement string, that means "put the whole match here". +alert(result); // HTML e CSS +``` -Let's use it to prepend all entries of `"John"` with `"Mr."`: +Substituir cada correspondência pela sua posição na string: ```js run -let str = "John Doe, John Smith and John Bull"; - -// for each John - replace it with Mr. and then John -alert(str.replace(/John/g, 'Mr.$&')); // Mr.John Doe, Mr.John Smith and Mr.John Bull +alert("Ho-Ho-ho".replace(/ho/gi, (match, offset) => offset)); // 0-3-6 ``` -Quite often we'd like to reuse parts of the source string, recombine them in the replacement or wrap into something. - -To do so, we should: -1. First, mark the parts by parentheses in regexp. -2. Use `$1`, `$2` (and so on) in the replacement string to get the content matched by 1st, 2nd and so on parentheses. - -For instance: +No exemplo abaixo, existem dois parênteses, então a função de substituição é chamada com 5 argumentos: o primeiro é a correspondência completa, em seguida, 2 parênteses, e depois dele (não usado no exemplo) a posição da correspondência e a string original: ```js run let str = "John Smith"; -// swap first and last name -alert(str.replace(/(john) (smith)/i, '$2, $1')) // Smith, John -``` - -**For situations that require "smart" replacements, the second argument can be a function.** - -It will be called for each match, and its result will be inserted as a replacement. - -For instance: +let result = str.replace(/(\w+) (\w+)/, (match, name, surname) => `${surname}, ${name}`); -```js run -let i = 0; - -// replace each "ho" by the result of the function -alert("HO-Ho-ho".replace(/ho/gi, function() { - return ++i; -})); // 1-2-3 +alert(result); // Smith, John ``` -In the example above the function just returns the next number every time, but usually the result is based on the match. - -The function is called with arguments `func(str, p1, p2, ..., pn, offset, input, groups)`: - -1. `str` -- the match, -2. `p1, p2, ..., pn` -- contents of parentheses (if there are any), -3. `offset` -- position of the match, -4. `input` -- the source string, -5. `groups` -- an object with named groups (see chapter [](info:regexp-groups)). - -If there are no parentheses in the regexp, then there are only 3 arguments: `func(str, offset, input)`. - -Let's use it to show full information about matches: +Se existirem muitos grupos, é conveniente usar os parâmetros de descanso para acessá-los: ```js run -// show and replace all matches -function replacer(str, offset, input) { - alert(`Found ${str} at position ${offset} in string ${input}`); - return str.toLowerCase(); -} +let str = "John Smith"; -let result = "HO-Ho-ho".replace(/ho/gi, replacer); -alert( 'Result: ' + result ); // Result: ho-ho-ho +let result = str.replace(/(\w+) (\w+)/, (...match) => `${match[2]}, ${match[1]}`); -// shows each match: -// Found HO at position 0 in string HO-Ho-ho -// Found Ho at position 3 in string HO-Ho-ho -// Found ho at position 6 in string HO-Ho-ho +alert(result); // Smith, John ``` -In the example below there are two parentheses, so `replacer` is called with 5 arguments: `str` is the full match, then parentheses, and then `offset` and `input`: +Ou, se usarmos grupos nomeados, o objeto `groups` com eles é sempre o último, para que possamos obtê-los assim: ```js run -function replacer(str, name, surname, offset, input) { - // name is the first parentheses, surname is the second one - return surname + ", " + name; -} - let str = "John Smith"; -alert(str.replace(/(John) (Smith)/, replacer)) // Smith, John +let result = str.replace(/(?\w+) (?\w+)/, (...match) => { + let groups = match.pop(); + + return `${groups.surname}, ${groups.name}`; +}); + +alert(result); // Smith, John ``` -Using a function gives us the ultimate replacement power, because it gets all the information about the match, has access to outer variables and can do everything. +O uso de uma função nos dá o poder de substituição definitivo, porque obtém todas as informações sobre a correspondência, tem a variáveis externas e pode fazer tudo. ## regexp.exec(str) -We've already seen these searching methods: +O método `regexp.exec(str)` retorna uma correspondência para `regexp` na string `str`. Diferentes dos métodos anteriores, é chamado numa regexp, não em uma string. -- `search` -- looks for the position of the match, -- `match` -- if there's no `g` flag, returns the first match with parentheses and all details, -- `match` -- if there's a `g` flag -- returns all matches, without details parentheses, -- `matchAll` -- returns all matches with details. +Se comporta de modo diferente dependendo se a regexp possui a flag `padrão:g`. -The `regexp.exec` method is the most flexible searching method of all. Unlike previous methods, `exec` should be called on a regexp, rather than on a string. +Se não houver `padrão:g`, a `regexp.exec(str)` retorna a primeira correspondência exatamente como `str.match(regexp)`. Esse comportamento não traz nada de novo. -It behaves differently depending on whether the regexp has the `g` flag. +Mas se houver a flag `padrão:g`, então: +- A chamada para `regexp.exec(str)` retorna a primeira correspondência e salva a posição imediatamente após ela na propriedade `regexp.lastIndex`. +- A próxima chamada inicia a pesquisa na posição `regexp.lastIndex`, retorna a próxima correspondência e salva a posição após elas em `regexp.lastIndex`. +- ...e assim por diante. +- Se não houver correspondências, `regexp.exec` retorna `null` e reinicia `regexp.lastIndex` para `0`. -If there's no `g`, then `regexp.exec(str)` returns the first match, exactly as `str.match(reg)`. Such behavior does not give us anything new. +Portanto, repetidas chamadas retornam todas as correspondências uma após outra, usando a propriedade `regexp.lastIndex` para manter o controle da atual posição de busca. -But if there's `g`, then: -- `regexp.exec(str)` returns the first match and *remembers* the position after it in `regexp.lastIndex` property. -- The next call starts to search from `regexp.lastIndex` and returns the next match. -- If there are no more matches then `regexp.exec` returns `null` and `regexp.lastIndex` is set to `0`. - -We could use it to get all matches with their positions and parentheses groups in a loop, instead of `matchAll`: +No passado, antes do método `str.matchAll` ser adicionado ao JavaScript, as chamadas de `regexp.exec` eram usadas em repetição para obter todas as correspondências com grupos: ```js run -let str = 'A lot about JavaScript at https://javascript.info'; - +let str = 'Mais sobre JavaScript em https://javascript.info'; let regexp = /javascript/ig; let result; while (result = regexp.exec(str)) { - alert( `Found ${result[0]} at ${result.index}` ); - // shows: Found JavaScript at 12, then: - // shows: Found javascript at 34 + alert( `Encontrado ${result[0]} na posição ${result.index}` ); + // Encontrado JavaScript na posição 11, depois + // Encontrado javascript na posição 33 } ``` -Surely, `matchAll` does the same, at least for modern browsers. But what `matchAll` can't do -- is to search from a given position. +Isso funciona bem agora, no entanto para navegadores novos `str.matchAll` é usualmente mais conveniente. -Let's search from position `13`. What we need is to assign `regexp.lastIndex=13` and call `regexp.exec`: +**Podemos usar `regexp.exec` para buscar de uma posição dada, configurando manualmente `lastIndex`.** -```js run -let str = "A lot about JavaScript at https://javascript.info"; +Por exemplo: -let regexp = /javascript/ig; -*!* -regexp.lastIndex = 13; -*/!* +```js run +let str = 'Olá, mundo!'; -let result; +let regexp = /\w+/g; // sem a flag "g", propriedade lastIndex é ignorada +regexp.lastIndex = 3; // pesquisa a partir da 5º posição (a partir da vírgula) -while (result = regexp.exec(str)) { - alert( `Found ${result[0]} at ${result.index}` ); - // shows: Found javascript at 34 -} +alert( regexp.exec(str) ); // mundo ``` -Now, starting from the given position `13`, there's only one match. +Se o regexp tiver flag `padrão:y`, então a pesquisa será realizada exatamente na posição `regexp.lastIndex`, nada mais. +Vamos substituir a flag `padrão:g` pela `padrão:y` no exemplo acima. Não haverá correspondências, como não haverá palavra na posição `3`: + +```js run +let str = 'Olá, mundo!'; + +let regexp = /\w+/y; +regexp.lastIndex = 3; // pesquisa exatamente na posição 5 + +alert( regexp.exec(str) ); // null +``` + +Isso é conveniente para situações em que precisamos "ler" algo da string por uma regexp nessa posição exata, não em outro lugar. ## regexp.test(str) -The method `regexp.test(str)` looks for a match and returns `true/false` whether it finds it. +O método `regex.test(str)` procura por uma correspondência e retorna `true/false` se existe. -For instance: +Por exemplo: ```js run -let str = "I love JavaScript"; +let str = "Eu amo JavaScript"; -// these two tests do the same -alert( *!*/love/i*/!*.test(str) ); // true -alert( str.search(*!*/love/i*/!*) != -1 ); // true +// esses dois testes fazem o mesmo +alert( /amo/i.test(str) ); // true +alert( str.search(/amo/i) != -1 ); // true ``` -An example with the negative answer: +Um exemplo com a resposta negativa: ```js run let str = "Bla-bla-bla"; -alert( *!*/love/i*/!*.test(str) ); // false -alert( str.search(*!*/love/i*/!*) != -1 ); // false +alert( /amo/i.test(str) ); // false +alert( str.search(/love/i) != -1 ); // false ``` -If the regexp has `'g'` flag, then `regexp.test` advances `regexp.lastIndex` property, just like `regexp.exec`. +Se a regexp tiver a flag `padrão:g`, o `regexp.test` procura na propriedade `regexp.lastIndex` e atualiza-a, assim como `regexp.exec` -So we can use it to search from a given position: +Então podemos usar isso para buscar a partir de uma posição fornecida: ```js run -let regexp = /love/gi; +let regexp = /amo/gi; -let str = "I love JavaScript"; +let str = "Eu amo JavaScript"; -// start the search from position 10: -regexp.lastIndex = 10 -alert( regexp.test(str) ); // false (no match) +// inicia a pesquisa da posição 10: +regexp.lastIndex = 10; +alert( regexp.test(str) ); // false (sem correspondência) ``` +````warn header="A mesma regexp global testada repetidamente em diferentes fontes pode falhar" +Se aplicarmos a mesma regexp global em diferentes entradas, isso poderá levar a resultados incorreto, porque a chamada `regexp.test` avança a propriedade `regexp.lastIndex`, portanto a pesquisa em outra string pode ter um início numa posição diferente de zero. - -````warn header="Same global regexp tested repeatedly may fail to match" -If we apply the same global regexp to different inputs, it may lead to wrong result, because `regexp.test` call advances `regexp.lastIndex` property, so the search in another string may start from non-zero position. - -For instance, here we call `regexp.test` twice on the same text, and the second time fails: +Por exemplo, aqui chamamos `regexp.test` duas vezes no mesmo texto e a segunda vez falha: ```js run -let regexp = /javascript/g; // (regexp just created: regexp.lastIndex=0) +let regexp = /javascript/g; // (regexp recém criada: regexp.lastIndex=0) -alert( regexp.test("javascript") ); // true (regexp.lastIndex=10 now) +alert( regexp.test("javascript") ); // true (regexp.lastIndex=10 agora) alert( regexp.test("javascript") ); // false ``` -That's exactly because `regexp.lastIndex` is non-zero on the second test. - -To work around that, one could use non-global regexps or re-adjust `regexp.lastIndex=0` before a new search. -```` - -## Summary - -There's a variety of many methods on both regexps and strings. - -Their abilities and methods overlap quite a bit, we can do the same by different calls. Sometimes that may cause confusion when starting to learn the language. +Isso é exatamente porque `regexp.lastIndex` é diferente de zero no segundo teste. -Then please refer to the recipes at the beginning of this chapter, as they provide solutions for the majority of regexp-related tasks. +Para contornar isso, podemos definir `regexp.lastIndex = 0` antes de cada busca. Ou, em vez de chamar métodos no regexp, usar métodos de string `str.match/search/...`, eles não usam `lastIndex`. +```` \ No newline at end of file From f7e7f38fe05efa10add229b110f701e38ce0333a Mon Sep 17 00:00:00 2001 From: fsdude Date: Mon, 25 May 2020 19:17:50 -0300 Subject: [PATCH 02/32] Removed files that aren't used anymore on english version --- .../1-find-time-hh-mm/solution.md | 6 ----- .../1-find-time-hh-mm/task.md | 8 ------- .../hello-java-boundaries.svg | 22 ------------------- 3 files changed, 36 deletions(-) delete mode 100644 9-regular-expressions/03-regexp-character-classes/1-find-time-hh-mm/solution.md delete mode 100644 9-regular-expressions/03-regexp-character-classes/1-find-time-hh-mm/task.md delete mode 100644 9-regular-expressions/03-regexp-character-classes/hello-java-boundaries.svg diff --git a/9-regular-expressions/03-regexp-character-classes/1-find-time-hh-mm/solution.md b/9-regular-expressions/03-regexp-character-classes/1-find-time-hh-mm/solution.md deleted file mode 100644 index 829eda13e..000000000 --- a/9-regular-expressions/03-regexp-character-classes/1-find-time-hh-mm/solution.md +++ /dev/null @@ -1,6 +0,0 @@ - -The answer: `pattern:\b\d\d:\d\d\b`. - -```js run -alert( "Breakfast at 09:00 in the room 123:456.".match( /\b\d\d:\d\d\b/ ) ); // 09:00 -``` diff --git a/9-regular-expressions/03-regexp-character-classes/1-find-time-hh-mm/task.md b/9-regular-expressions/03-regexp-character-classes/1-find-time-hh-mm/task.md deleted file mode 100644 index 5e32b9c48..000000000 --- a/9-regular-expressions/03-regexp-character-classes/1-find-time-hh-mm/task.md +++ /dev/null @@ -1,8 +0,0 @@ -# Find the time - -The time has a format: `hours:minutes`. Both hours and minutes has two digits, like `09:00`. - -Make a regexp to find time in the string: `subject:Breakfast at 09:00 in the room 123:456.` - -P.S. In this task there's no need to check time correctness yet, so `25:99` can also be a valid result. -P.P.S. The regexp shouldn't match `123:456`. diff --git a/9-regular-expressions/03-regexp-character-classes/hello-java-boundaries.svg b/9-regular-expressions/03-regexp-character-classes/hello-java-boundaries.svg deleted file mode 100644 index ccdc1a670..000000000 --- a/9-regular-expressions/03-regexp-character-classes/hello-java-boundaries.svg +++ /dev/null @@ -1,22 +0,0 @@ -<<<<<<< HEAD - - - - hello-java-boundaries.svg - Created with sketchtool. - - - - Hello, Java - ! - - - - - - - - -======= - ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 From a906139f8f0145b5864e3d30fe9fe11204ca49e0 Mon Sep 17 00:00:00 2001 From: fsdude Date: Mon, 25 May 2020 19:18:51 -0300 Subject: [PATCH 03/32] Translated english article to portuguese following the english version --- .../03-regexp-character-classes/article.md | 258 +++++++----------- 1 file changed, 98 insertions(+), 160 deletions(-) diff --git a/9-regular-expressions/03-regexp-character-classes/article.md b/9-regular-expressions/03-regexp-character-classes/article.md index a2f9869fb..1a45309a0 100644 --- a/9-regular-expressions/03-regexp-character-classes/article.md +++ b/9-regular-expressions/03-regexp-character-classes/article.md @@ -1,154 +1,90 @@ -# Character classes +# Classes de caracteres -Consider a practical task -- we have a phone number `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79035419441`. +Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. -To do so, we can find and remove anything that's not a number. Character classes can help with that. +Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. -A character class is a special notation that matches any symbol from a certain set. +Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. -For the start, let's explore a "digit" class. It's written as `\d`. We put it in the pattern, that means "any single digit". +Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". -For instance, the let's find the first digit in the phone number: +Por exemplo, vamos encontrar o primeiro dígito no número de telefone: ```js run let str = "+7(903)-123-45-67"; -let reg = /\d/; +let regexp = /\d/; -alert( str.match(reg) ); // 7 +alert( str.match(regexp) ); // 7 ``` -Without the flag `g`, the regular expression only looks for the first match, that is the first digit `\d`. +Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. -Let's add the `g` flag to find all digits: +Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: ```js run let str = "+7(903)-123-45-67"; -let reg = /\d/g; +let regexp = /\d/g; -alert( str.match(reg) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 +alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 -alert( str.match(reg).join('') ); // 79035419441 +// vamos criar o número de telefone apenas com dígitos: +alert( str.match(regexp).join('') ); // 79031234567 ``` -That was a character class for digits. There are other character classes as well. +Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. -Most used are: +As mais usadas são: -`\d` ("d" is from "digit") -: A digit: a character from `0` to `9`. +`padrão:\d` ("d" é de "digit") +: Um dígito: um caractere de `0` a `9`. -`\s` ("s" is from "space") -: A space symbol: that includes spaces, tabs, newlines. +`padrão:\s` ("s" é de "space") +: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. -`\w` ("w" is from "word") -: A "wordly" character: either a letter of English alphabet or a digit or an underscore. Non-english letters (like cyrillic or hindi) do not belong to `\w`. +`padrão:\w` ("w" é de "word") +: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. -For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", like `"1 a"`. +Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. -**A regexp may contain both regular symbols and character classes.** +**Uma regexp pode conter símbolos regulares e classes de caracteres.** -For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: +Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: ```js run -let str = "CSS4 is cool"; -let reg = /CSS\d/ +let str = "Existe CSS4?"; +let regexp = /CSS\d/ -alert( str.match(reg) ); // CSS4 +alert( str.match(regexp) ); // CSS4 ``` -Also we can use many character classes: +Também podemos usar muitas classes de caracteres: ```js run -alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // 'HTML5' +alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' ``` -The match (each character class corresponds to one result character): +A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): ![](love-html5-classes.svg) -## Word boundary: \b +## Classes inversas -A word boundary `pattern:\b` -- is a special character class. +Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. -It does not denote a character, but rather a boundary between characters. +O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: -For instance, `pattern:\bJava\b` matches `match:Java` in the string `subject:Hello, Java!`, but not in the script `subject:Hello, JavaScript!`. +`padrão:\D` +: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. -```js run -alert( "Hello, Java!".match(/\bJava\b/) ); // Java -alert( "Hello, JavaScript!".match(/\bJava\b/) ); // null -``` - -The boundary has "zero width" in a sense that usually a character class means a character in the result (like a wordly character or a digit), but not in this case. - -The boundary is a test. - -When regular expression engine is doing the search, it's moving along the string in an attempt to find the match. At each string position it tries to find the pattern. - -When the pattern contains `pattern:\b`, it tests that the position in string is a word boundary, that is one of three variants: - -- Immediately before is `\w`, and immediately after -- not `\w`, or vise versa. -- At string start, and the first string character is `\w`. -- At string end, and the last string character is `\w`. - -For instance, in the string `subject:Hello, Java!` the following positions match `\b`: - -![](hello-java-boundaries.svg) - -So it matches `pattern:\bHello\b`, because: - -1. At the beginning of the string the first `\b` test matches. -2. Then the word `Hello` matches. -3. Then `\b` matches, as we're between `o` and a space. - -Pattern `pattern:\bJava\b` also matches. But not `pattern:\bHell\b` (because there's no word boundary after `l`) and not `Java!\b` (because the exclamation sign is not a wordly character, so there's no word boundary after it). +`padrão:\S` +: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. +`padrão:\W` +: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. -```js run -alert( "Hello, Java!".match(/\bHello\b/) ); // Hello -alert( "Hello, Java!".match(/\bJava\b/) ); // Java -alert( "Hello, Java!".match(/\bHell\b/) ); // null (no match) -alert( "Hello, Java!".match(/\bJava!\b/) ); // null (no match) -``` - -Once again let's note that `pattern:\b` makes the searching engine to test for the boundary, so that `pattern:Java\b` finds `match:Java` only when followed by a word boundary, but it does not add a letter to the result. - -Usually we use `\b` to find standalone English words. So that if we want `"Java"` language then `pattern:\bJava\b` finds exactly a standalone word and ignores it when it's a part of `"JavaScript"`. - -Another example: a regexp `pattern:\b\d\d\b` looks for standalone two-digit numbers. In other words, it requires that before and after `pattern:\d\d` must be a symbol different from `\w` (or beginning/end of the string). - -```js run -alert( "1 23 456 78".match(/\b\d\d\b/g) ); // 23,78 -``` - -```warn header="Word boundary doesn't work for non-English alphabets" -The word boundary check `\b` tests for a boundary between `\w` and something else. But `\w` means an English letter (or a digit or an underscore), so the test won't work for other characters (like cyrillic or hieroglyphs). -``` - - -## Inverse classes - -For every character class there exists an "inverse class", denoted with the same letter, but uppercased. - -The "reverse" means that it matches all other characters, for instance: - -`\D` -: Non-digit: any character except `\d`, for instance a letter. - -`\S` -: Non-space: any character except `\s`, for instance a letter. - -`\W` -: Non-wordly character: anything but `\w`. - -`\B` -: Non-boundary: a test reverse to `\b`. - -In the beginning of the chapter we saw how to get all digits from the phone `subject:+7(903)-123-45-67`. - -One way was to match all digits and join them: +No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. ```js run let str = "+7(903)-123-45-67"; @@ -156,8 +92,7 @@ let str = "+7(903)-123-45-67"; alert( str.match(/\d/g).join('') ); // 79031234567 ``` -An alternative, shorter way is to find non-digits `\D` and remove them from the string: - +Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: ```js run let str = "+7(903)-123-45-67"; @@ -165,101 +100,104 @@ let str = "+7(903)-123-45-67"; alert( str.replace(/\D/g, "") ); // 79031234567 ``` -## Spaces are regular characters +## Um ponto é "qualquer caractere" -Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. +Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". -But if a regexp doesn't take spaces into account, it may fail to work. - -Let's try to find digits separated by a dash: +Por exemplo: ```js run -alert( "1 - 5".match(/\d-\d/) ); // null, no match! +alert( "Z".match(/./) ); // Z ``` -Here we fix it by adding spaces into the regexp `pattern:\d - \d`: +Ou no meio de uma regexp: ```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works -``` +let regexp = /CS.4/; -**A space is a character. Equal in importance with any other character.** +alert( "CSS4".match(regexp) ); // CSS4 +alert( "CS-4".match(regexp) ); // CS-4 +alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) +``` -Of course, spaces in a regexp are needed only if we look for them. Extra spaces (just like any other extra characters) may prevent a match: +Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: ```js run -alert( "1-5".match(/\d - \d/) ); // null, because the string 1-5 has no spaces +alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto ``` -In other words, in a regular expression all characters matter, spaces too. - -## A dot is any character +### Ponto como literalmente qualquer caractere com a flag "s" -The dot `"."` is a special character class that matches "any character except a newline". +Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. -For instance: +Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: ```js run -alert( "Z".match(/./) ); // Z +alert( "A\nB".match(/A.B/) ); // null (sem correspondência) ``` -Or in the middle of a regexp: +Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. -```js run -let reg = /CS.4/; +É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: -alert( "CSS4".match(reg) ); // CSS4 -alert( "CS-4".match(reg) ); // CS-4 -alert( "CS 4".match(reg) ); // CS 4 (space is also a character) +```js run +alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) ``` -Please note that the dot means "any character", but not the "absense of a character". There must be a character to match it: +````warn header="Não suportado no Firefox, IE, Edge" +Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. + +Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". ```js run -alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot +alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) ``` -### The dotall "s" flag +O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. -Usually a dot doesn't match a newline character. +Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. +```` -For instance, this doesn't match: +````warn header="Preste atenção nos espaços" +Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. -```js run -alert( "A\nB".match(/A.B/) ); // null (no match) +Mas se uma regexp não leva em consideração os espaços, ela pode falhar. -// a space character would match -// or a letter, but not \n -``` +Vamos tentar encontrar dígitos separados por um hífen: -Sometimes it's inconvenient, we really want "any character", newline included. +```js run +alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! +``` -That's what `s` flag does. If a regexp has it, then the dot `"."` match literally any character: +Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: ```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (match!) +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona +// ou podemos usar a classe \s: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona ``` +**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** + +Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. -## Summary +Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. +```` -There exist following character classes: +## Resumo -- `pattern:\d` -- digits. -- `pattern:\D` -- non-digits. -- `pattern:\s` -- space symbols, tabs, newlines. -- `pattern:\S` -- all but `pattern:\s`. -- `pattern:\w` -- English letters, digits, underscore `'_'`. -- `pattern:\W` -- all but `pattern:\w`. -- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline. +Existem as seguintes classes de caracteres: -...But that's not all! +- `padrão:\d` - dígitos. +- `padrão:\D` - sem dígitos. +- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. +- `padrão:\S` - todos, exceto `padrão:\s`. +- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. +- `padrão:\W` - todos, exceto `padrão:\w`. +- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. -Modern JavaScript also allows to look for characters by their Unicode properties, for instance: +...Mas isso não é tudo! -- A cyrillic letter is: `pattern:\p{Script=Cyrillic}` or `pattern:\p{sc=Cyrillic}`. -- A dash (be it a small hyphen `-` or a long dash `—`): `pattern:\p{Dash_Punctuation}` or `pattern:\p{pd}`. -- A currency symbol: `pattern:\p{Currency_Symbol}` or `pattern:\p{sc}`. -- ...And much more. Unicode has a lot of character categories that we can select from. +A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. -These patterns require `'u'` regexp flag to work. More about that in the chapter [](info:regexp-unicode). +Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. \ No newline at end of file From 60a9345a54e8ada55f97e9d6374bdfa475a6fbf8 Mon Sep 17 00:00:00 2001 From: fsdude Date: Mon, 25 May 2020 19:20:31 -0300 Subject: [PATCH 04/32] reuploaded the svg file quoted on article (other one was broken) --- .../love-html5-classes.svg | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg b/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg index 49347b493..9c88cc088 100644 --- a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg +++ b/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg @@ -1,22 +1 @@ -<<<<<<< HEAD - - - - love-html5-classes.svg - Created with sketchtool. - - - - I love HTML - 5 - - - \s \w \w \w \w \ - d - - - - -======= - ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 + \ No newline at end of file From 93a763d3ed087463994ba35b899293f1eb18c267 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Thu, 24 Dec 2020 23:53:54 +0100 Subject: [PATCH 05/32] Resolve conflicts. --- .../02-regexp-character-classes/article.md | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/9-regular-expressions/02-regexp-character-classes/article.md b/9-regular-expressions/02-regexp-character-classes/article.md index 201c78a05..94c875955 100644 --- a/9-regular-expressions/02-regexp-character-classes/article.md +++ b/9-regular-expressions/02-regexp-character-classes/article.md @@ -1,14 +1,14 @@ -# Character classes +# Classes de caracteres -Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79031234567`. +Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. -To do so, we can find and remove anything that's not a number. Character classes can help with that. +Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. -A *character class* is a special notation that matches any symbol from a certain set. +Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. -For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit". +Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". -For instance, let's find the first digit in the phone number: +Por exemplo, vamos encontrar o primeiro dígito no número de telefone: ```js run let str = "+7(903)-123-45-67"; @@ -18,73 +18,73 @@ let regexp = /\d/; alert( str.match(regexp) ); // 7 ``` -Without the flag `pattern:g`, the regular expression only looks for the first match, that is the first digit `pattern:\d`. +Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. -Let's add the `pattern:g` flag to find all digits: +Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: ```js run let str = "+7(903)-123-45-67"; let regexp = /\d/g; -alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 +alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 -// let's make the digits-only phone number of them: +// vamos criar o número de telefone apenas com dígitos: alert( str.match(regexp).join('') ); // 79031234567 ``` -That was a character class for digits. There are other character classes as well. +Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. -Most used are: +As mais usadas são: -`pattern:\d` ("d" is from "digit") -: A digit: a character from `0` to `9`. +`padrão:\d` ("d" é de "digit") +: Um dígito: um caractere de `0` a `9`. -`pattern:\s` ("s" is from "space") -: A space symbol: includes spaces, tabs `\t`, newlines `\n` and few other rare characters, such as `\v`, `\f` and `\r`. +`padrão:\s` ("s" é de "space") +: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. -`pattern:\w` ("w" is from "word") -: A "wordly" character: either a letter of Latin alphabet or a digit or an underscore `_`. Non-Latin letters (like cyrillic or hindi) do not belong to `pattern:\w`. +`padrão:\w` ("w" é de "word") +: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. -For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", such as `match:1 a`. +Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. -**A regexp may contain both regular symbols and character classes.** +**Uma regexp pode conter símbolos regulares e classes de caracteres.** -For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: +Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: ```js run -let str = "Is there CSS4?"; +let str = "Existe CSS4?"; let regexp = /CSS\d/ alert( str.match(regexp) ); // CSS4 ``` -Also we can use many character classes: +Também podemos usar muitas classes de caracteres: ```js run -alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' ``` -The match (each regexp character class has the corresponding result character): +A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): ![](love-html5-classes.svg) -## Inverse classes +## Classes inversas -For every character class there exists an "inverse class", denoted with the same letter, but uppercased. +Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. -The "inverse" means that it matches all other characters, for instance: +O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: -`pattern:\D` -: Non-digit: any character except `pattern:\d`, for instance a letter. +`padrão:\D` +: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. -`pattern:\S` -: Non-space: any character except `pattern:\s`, for instance a letter. +`padrão:\S` +: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. -`pattern:\W` -: Non-wordly character: anything but `pattern:\w`, e.g a non-latin letter or a space. +`padrão:\W` +: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. -In the beginning of the chapter we saw how to make a number-only phone number from a string like `subject:+7(903)-123-45-67`: find all digits and join them. +No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. ```js run let str = "+7(903)-123-45-67"; @@ -92,7 +92,7 @@ let str = "+7(903)-123-45-67"; alert( str.match(/\d/g).join('') ); // 79031234567 ``` -An alternative, shorter way is to find non-digits `pattern:\D` and remove them from the string: +Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: ```js run let str = "+7(903)-123-45-67"; @@ -100,104 +100,104 @@ let str = "+7(903)-123-45-67"; alert( str.replace(/\D/g, "") ); // 79031234567 ``` -## A dot is "any character" +## Um ponto é "qualquer caractere" -A dot `pattern:.` is a special character class that matches "any character except a newline". +Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". -For instance: +Por exemplo: ```js run alert( "Z".match(/./) ); // Z ``` -Or in the middle of a regexp: +Ou no meio de uma regexp: ```js run let regexp = /CS.4/; alert( "CSS4".match(regexp) ); // CSS4 alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (space is also a character) +alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) ``` -Please note that a dot means "any character", but not the "absence of a character". There must be a character to match it: +Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: ```js run -alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot +alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto ``` -### Dot as literally any character with "s" flag +### Ponto como literalmente qualquer caractere com a flag "s" -By default, a dot doesn't match the newline character `\n`. +Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. -For instance, the regexp `pattern:A.B` matches `match:A`, and then `match:B` with any character between them, except a newline `\n`: +Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: ```js run -alert( "A\nB".match(/A.B/) ); // null (no match) +alert( "A\nB".match(/A.B/) ); // null (sem correspondência) ``` -There are many situations when we'd like a dot to mean literally "any character", newline included. +Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. -That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` matches literally any character: +É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: ```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (match!) +alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) ``` -````warn header="Not supported in IE" -The `pattern:s` flag is not supported in IE. +````warn header="Não suportado no Firefox, IE, Edge" +Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. -Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character" (this pattern will be covered in the article ). +Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". ```js run alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) ``` -The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter. Or even the `pattern:[^]` -- as it means match any character except nothing. +O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. -Also we can use this trick if we want both kind of "dots" in the same pattern: the actual dot `pattern:.` behaving the regular way ("not including a newline"), and also a way to match "any character" with `pattern:[\s\S]` or alike. +Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. ```` -````warn header="Pay attention to spaces" -Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. +````warn header="Preste atenção nos espaços" +Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. -But if a regexp doesn't take spaces into account, it may fail to work. +Mas se uma regexp não leva em consideração os espaços, ela pode falhar. -Let's try to find digits separated by a hyphen: +Vamos tentar encontrar dígitos separados por um hífen: ```js run -alert( "1 - 5".match(/\d-\d/) ); // null, no match! +alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! ``` -Let's fix it adding spaces into the regexp `pattern:\d - \d`: +Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: ```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works -// or we can use \s class: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona +// ou podemos usar a classe \s: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona ``` -**A space is a character. Equal in importance with any other character.** +**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** -We can't add or remove spaces from a regular expression and expect it to work the same. +Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. -In other words, in a regular expression all characters matter, spaces too. +Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. ```` -## Summary +## Resumo -There exist following character classes: +Existem as seguintes classes de caracteres: -- `pattern:\d` -- digits. -- `pattern:\D` -- non-digits. -- `pattern:\s` -- space symbols, tabs, newlines. -- `pattern:\S` -- all but `pattern:\s`. -- `pattern:\w` -- Latin letters, digits, underscore `'_'`. -- `pattern:\W` -- all but `pattern:\w`. -- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline `\n`. +- `padrão:\d` - dígitos. +- `padrão:\D` - sem dígitos. +- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. +- `padrão:\S` - todos, exceto `padrão:\s`. +- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. +- `padrão:\W` - todos, exceto `padrão:\w`. +- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. -...But that's not all! +...Mas isso não é tudo! -Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter), is it a punctuation sign, etc. +A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. -We can search by these properties as well. That requires flag `pattern:u`, covered in the next article. +Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. From 0faf9bee67c0c62da7c0bbf926354170c73767b1 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 00:21:54 +0100 Subject: [PATCH 06/32] Delete old directory. --- .../03-regexp-character-classes/article.md | 203 ------------------ .../love-html5-classes.svg | 1 - 2 files changed, 204 deletions(-) delete mode 100644 9-regular-expressions/03-regexp-character-classes/article.md delete mode 100644 9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg diff --git a/9-regular-expressions/03-regexp-character-classes/article.md b/9-regular-expressions/03-regexp-character-classes/article.md deleted file mode 100644 index 1a45309a0..000000000 --- a/9-regular-expressions/03-regexp-character-classes/article.md +++ /dev/null @@ -1,203 +0,0 @@ -# Classes de caracteres - -Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. - -Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. - -Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. - -Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". - -Por exemplo, vamos encontrar o primeiro dígito no número de telefone: - -```js run -let str = "+7(903)-123-45-67"; - -let regexp = /\d/; - -alert( str.match(regexp) ); // 7 -``` - -Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. - -Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: - -```js run -let str = "+7(903)-123-45-67"; - -let regexp = /\d/g; - -alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 - -// vamos criar o número de telefone apenas com dígitos: -alert( str.match(regexp).join('') ); // 79031234567 -``` - -Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. - -As mais usadas são: - -`padrão:\d` ("d" é de "digit") -: Um dígito: um caractere de `0` a `9`. - -`padrão:\s` ("s" é de "space") -: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. - -`padrão:\w` ("w" é de "word") -: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. - -Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. - -**Uma regexp pode conter símbolos regulares e classes de caracteres.** - -Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: - -```js run -let str = "Existe CSS4?"; -let regexp = /CSS\d/ - -alert( str.match(regexp) ); // CSS4 -``` - -Também podemos usar muitas classes de caracteres: - -```js run -alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' -``` - -A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): - -![](love-html5-classes.svg) - -## Classes inversas - -Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. - -O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: - -`padrão:\D` -: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. - -`padrão:\S` -: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. - -`padrão:\W` -: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. - -No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. - -```js run -let str = "+7(903)-123-45-67"; - -alert( str.match(/\d/g).join('') ); // 79031234567 -``` - -Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: - -```js run -let str = "+7(903)-123-45-67"; - -alert( str.replace(/\D/g, "") ); // 79031234567 -``` - -## Um ponto é "qualquer caractere" - -Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". - -Por exemplo: - -```js run -alert( "Z".match(/./) ); // Z -``` - -Ou no meio de uma regexp: - -```js run -let regexp = /CS.4/; - -alert( "CSS4".match(regexp) ); // CSS4 -alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) -``` - -Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: - -```js run -alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto -``` - -### Ponto como literalmente qualquer caractere com a flag "s" - -Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. - -Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: - -```js run -alert( "A\nB".match(/A.B/) ); // null (sem correspondência) -``` - -Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. - -É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: - -```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) -``` - -````warn header="Não suportado no Firefox, IE, Edge" -Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. - -Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". - -```js run -alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) -``` - -O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. - -Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. -```` - -````warn header="Preste atenção nos espaços" -Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. - -Mas se uma regexp não leva em consideração os espaços, ela pode falhar. - -Vamos tentar encontrar dígitos separados por um hífen: - -```js run -alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! -``` - -Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: - -```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona -// ou podemos usar a classe \s: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona -``` - -**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** - -Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. - -Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. -```` - -## Resumo - -Existem as seguintes classes de caracteres: - -- `padrão:\d` - dígitos. -- `padrão:\D` - sem dígitos. -- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. -- `padrão:\S` - todos, exceto `padrão:\s`. -- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. -- `padrão:\W` - todos, exceto `padrão:\w`. -- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. - -...Mas isso não é tudo! - -A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. - -Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. \ No newline at end of file diff --git a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg b/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg deleted file mode 100644 index 9c88cc088..000000000 --- a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 0661b81af69b5a11274e0c646deda52fc4b7a95d Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:41:07 +0100 Subject: [PATCH 07/32] Revert "Merge branch 'fsdude-02-regexp-character-classes' into master" This reverts commit df62d2ca2dc707248253bd2dc4046afffc8fdf86, reversing changes made to e9c30cea82bafd76c254b5704c005c00e06b2ee0. --- .../03-regexp-character-classes/article.md | 203 ++++++++++++++++++ .../love-html5-classes.svg | 1 + 2 files changed, 204 insertions(+) create mode 100644 9-regular-expressions/03-regexp-character-classes/article.md create mode 100644 9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg diff --git a/9-regular-expressions/03-regexp-character-classes/article.md b/9-regular-expressions/03-regexp-character-classes/article.md new file mode 100644 index 000000000..1a45309a0 --- /dev/null +++ b/9-regular-expressions/03-regexp-character-classes/article.md @@ -0,0 +1,203 @@ +# Classes de caracteres + +Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. + +Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. + +Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. + +Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". + +Por exemplo, vamos encontrar o primeiro dígito no número de telefone: + +```js run +let str = "+7(903)-123-45-67"; + +let regexp = /\d/; + +alert( str.match(regexp) ); // 7 +``` + +Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. + +Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: + +```js run +let str = "+7(903)-123-45-67"; + +let regexp = /\d/g; + +alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 + +// vamos criar o número de telefone apenas com dígitos: +alert( str.match(regexp).join('') ); // 79031234567 +``` + +Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. + +As mais usadas são: + +`padrão:\d` ("d" é de "digit") +: Um dígito: um caractere de `0` a `9`. + +`padrão:\s` ("s" é de "space") +: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. + +`padrão:\w` ("w" é de "word") +: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. + +Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. + +**Uma regexp pode conter símbolos regulares e classes de caracteres.** + +Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: + +```js run +let str = "Existe CSS4?"; +let regexp = /CSS\d/ + +alert( str.match(regexp) ); // CSS4 +``` + +Também podemos usar muitas classes de caracteres: + +```js run +alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +``` + +A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): + +![](love-html5-classes.svg) + +## Classes inversas + +Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. + +O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: + +`padrão:\D` +: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. + +`padrão:\S` +: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. + +`padrão:\W` +: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. + +No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. + +```js run +let str = "+7(903)-123-45-67"; + +alert( str.match(/\d/g).join('') ); // 79031234567 +``` + +Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: + +```js run +let str = "+7(903)-123-45-67"; + +alert( str.replace(/\D/g, "") ); // 79031234567 +``` + +## Um ponto é "qualquer caractere" + +Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". + +Por exemplo: + +```js run +alert( "Z".match(/./) ); // Z +``` + +Ou no meio de uma regexp: + +```js run +let regexp = /CS.4/; + +alert( "CSS4".match(regexp) ); // CSS4 +alert( "CS-4".match(regexp) ); // CS-4 +alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) +``` + +Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: + +```js run +alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto +``` + +### Ponto como literalmente qualquer caractere com a flag "s" + +Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. + +Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: + +```js run +alert( "A\nB".match(/A.B/) ); // null (sem correspondência) +``` + +Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. + +É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: + +```js run +alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) +``` + +````warn header="Não suportado no Firefox, IE, Edge" +Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. + +Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". + +```js run +alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) +``` + +O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. + +Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. +```` + +````warn header="Preste atenção nos espaços" +Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. + +Mas se uma regexp não leva em consideração os espaços, ela pode falhar. + +Vamos tentar encontrar dígitos separados por um hífen: + +```js run +alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! +``` + +Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: + +```js run +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona +// ou podemos usar a classe \s: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona +``` + +**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** + +Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. + +Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. +```` + +## Resumo + +Existem as seguintes classes de caracteres: + +- `padrão:\d` - dígitos. +- `padrão:\D` - sem dígitos. +- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. +- `padrão:\S` - todos, exceto `padrão:\s`. +- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. +- `padrão:\W` - todos, exceto `padrão:\w`. +- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. + +...Mas isso não é tudo! + +A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. + +Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. \ No newline at end of file diff --git a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg b/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg new file mode 100644 index 000000000..9c88cc088 --- /dev/null +++ b/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg @@ -0,0 +1 @@ + \ No newline at end of file From bfab762334140f36ea51eec69522f9f72f764c99 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:41:29 +0100 Subject: [PATCH 08/32] Revert "Merge branch 'fsdude-02-regexp-character-classes' into master" This reverts commit e9c30cea82bafd76c254b5704c005c00e06b2ee0, reversing changes made to 41188c4f41719a8e9b4b21eeeda5d43071914fe8. --- .../03-regexp-character-classes/article.md | 203 ------------------ .../love-html5-classes.svg | 1 - 2 files changed, 204 deletions(-) delete mode 100644 9-regular-expressions/03-regexp-character-classes/article.md delete mode 100644 9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg diff --git a/9-regular-expressions/03-regexp-character-classes/article.md b/9-regular-expressions/03-regexp-character-classes/article.md deleted file mode 100644 index 1a45309a0..000000000 --- a/9-regular-expressions/03-regexp-character-classes/article.md +++ /dev/null @@ -1,203 +0,0 @@ -# Classes de caracteres - -Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. - -Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. - -Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. - -Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". - -Por exemplo, vamos encontrar o primeiro dígito no número de telefone: - -```js run -let str = "+7(903)-123-45-67"; - -let regexp = /\d/; - -alert( str.match(regexp) ); // 7 -``` - -Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. - -Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: - -```js run -let str = "+7(903)-123-45-67"; - -let regexp = /\d/g; - -alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 - -// vamos criar o número de telefone apenas com dígitos: -alert( str.match(regexp).join('') ); // 79031234567 -``` - -Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. - -As mais usadas são: - -`padrão:\d` ("d" é de "digit") -: Um dígito: um caractere de `0` a `9`. - -`padrão:\s` ("s" é de "space") -: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. - -`padrão:\w` ("w" é de "word") -: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. - -Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. - -**Uma regexp pode conter símbolos regulares e classes de caracteres.** - -Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: - -```js run -let str = "Existe CSS4?"; -let regexp = /CSS\d/ - -alert( str.match(regexp) ); // CSS4 -``` - -Também podemos usar muitas classes de caracteres: - -```js run -alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' -``` - -A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): - -![](love-html5-classes.svg) - -## Classes inversas - -Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. - -O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: - -`padrão:\D` -: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. - -`padrão:\S` -: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. - -`padrão:\W` -: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. - -No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. - -```js run -let str = "+7(903)-123-45-67"; - -alert( str.match(/\d/g).join('') ); // 79031234567 -``` - -Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: - -```js run -let str = "+7(903)-123-45-67"; - -alert( str.replace(/\D/g, "") ); // 79031234567 -``` - -## Um ponto é "qualquer caractere" - -Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". - -Por exemplo: - -```js run -alert( "Z".match(/./) ); // Z -``` - -Ou no meio de uma regexp: - -```js run -let regexp = /CS.4/; - -alert( "CSS4".match(regexp) ); // CSS4 -alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) -``` - -Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: - -```js run -alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto -``` - -### Ponto como literalmente qualquer caractere com a flag "s" - -Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. - -Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: - -```js run -alert( "A\nB".match(/A.B/) ); // null (sem correspondência) -``` - -Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. - -É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: - -```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) -``` - -````warn header="Não suportado no Firefox, IE, Edge" -Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. - -Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". - -```js run -alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) -``` - -O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. - -Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. -```` - -````warn header="Preste atenção nos espaços" -Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. - -Mas se uma regexp não leva em consideração os espaços, ela pode falhar. - -Vamos tentar encontrar dígitos separados por um hífen: - -```js run -alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! -``` - -Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: - -```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona -// ou podemos usar a classe \s: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona -``` - -**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** - -Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. - -Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. -```` - -## Resumo - -Existem as seguintes classes de caracteres: - -- `padrão:\d` - dígitos. -- `padrão:\D` - sem dígitos. -- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. -- `padrão:\S` - todos, exceto `padrão:\s`. -- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. -- `padrão:\W` - todos, exceto `padrão:\w`. -- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. - -...Mas isso não é tudo! - -A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. - -Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. \ No newline at end of file diff --git a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg b/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg deleted file mode 100644 index 9c88cc088..000000000 --- a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 38aa681926db834443bbc5ade69f5553a13a6d5d Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:41:52 +0100 Subject: [PATCH 09/32] Revert "Merge branch 'fsdude-02-regexp-character-classes' into master" This reverts commit 41188c4f41719a8e9b4b21eeeda5d43071914fe8, reversing changes made to 0c959f95af58cd8700054fd32d63fcb669025019. --- .../02-regexp-character-classes/article.md | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/9-regular-expressions/02-regexp-character-classes/article.md b/9-regular-expressions/02-regexp-character-classes/article.md index 94c875955..201c78a05 100644 --- a/9-regular-expressions/02-regexp-character-classes/article.md +++ b/9-regular-expressions/02-regexp-character-classes/article.md @@ -1,14 +1,14 @@ -# Classes de caracteres +# Character classes -Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. +Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79031234567`. -Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. +To do so, we can find and remove anything that's not a number. Character classes can help with that. -Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. +A *character class* is a special notation that matches any symbol from a certain set. -Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". +For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit". -Por exemplo, vamos encontrar o primeiro dígito no número de telefone: +For instance, let's find the first digit in the phone number: ```js run let str = "+7(903)-123-45-67"; @@ -18,73 +18,73 @@ let regexp = /\d/; alert( str.match(regexp) ); // 7 ``` -Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. +Without the flag `pattern:g`, the regular expression only looks for the first match, that is the first digit `pattern:\d`. -Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: +Let's add the `pattern:g` flag to find all digits: ```js run let str = "+7(903)-123-45-67"; let regexp = /\d/g; -alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 +alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 -// vamos criar o número de telefone apenas com dígitos: +// let's make the digits-only phone number of them: alert( str.match(regexp).join('') ); // 79031234567 ``` -Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. +That was a character class for digits. There are other character classes as well. -As mais usadas são: +Most used are: -`padrão:\d` ("d" é de "digit") -: Um dígito: um caractere de `0` a `9`. +`pattern:\d` ("d" is from "digit") +: A digit: a character from `0` to `9`. -`padrão:\s` ("s" é de "space") -: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. +`pattern:\s` ("s" is from "space") +: A space symbol: includes spaces, tabs `\t`, newlines `\n` and few other rare characters, such as `\v`, `\f` and `\r`. -`padrão:\w` ("w" é de "word") -: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. +`pattern:\w` ("w" is from "word") +: A "wordly" character: either a letter of Latin alphabet or a digit or an underscore `_`. Non-Latin letters (like cyrillic or hindi) do not belong to `pattern:\w`. -Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. +For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", such as `match:1 a`. -**Uma regexp pode conter símbolos regulares e classes de caracteres.** +**A regexp may contain both regular symbols and character classes.** -Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: +For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: ```js run -let str = "Existe CSS4?"; +let str = "Is there CSS4?"; let regexp = /CSS\d/ alert( str.match(regexp) ); // CSS4 ``` -Também podemos usar muitas classes de caracteres: +Also we can use many character classes: ```js run -alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' ``` -A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): +The match (each regexp character class has the corresponding result character): ![](love-html5-classes.svg) -## Classes inversas +## Inverse classes -Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. +For every character class there exists an "inverse class", denoted with the same letter, but uppercased. -O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: +The "inverse" means that it matches all other characters, for instance: -`padrão:\D` -: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. +`pattern:\D` +: Non-digit: any character except `pattern:\d`, for instance a letter. -`padrão:\S` -: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. +`pattern:\S` +: Non-space: any character except `pattern:\s`, for instance a letter. -`padrão:\W` -: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. +`pattern:\W` +: Non-wordly character: anything but `pattern:\w`, e.g a non-latin letter or a space. -No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. +In the beginning of the chapter we saw how to make a number-only phone number from a string like `subject:+7(903)-123-45-67`: find all digits and join them. ```js run let str = "+7(903)-123-45-67"; @@ -92,7 +92,7 @@ let str = "+7(903)-123-45-67"; alert( str.match(/\d/g).join('') ); // 79031234567 ``` -Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: +An alternative, shorter way is to find non-digits `pattern:\D` and remove them from the string: ```js run let str = "+7(903)-123-45-67"; @@ -100,104 +100,104 @@ let str = "+7(903)-123-45-67"; alert( str.replace(/\D/g, "") ); // 79031234567 ``` -## Um ponto é "qualquer caractere" +## A dot is "any character" -Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". +A dot `pattern:.` is a special character class that matches "any character except a newline". -Por exemplo: +For instance: ```js run alert( "Z".match(/./) ); // Z ``` -Ou no meio de uma regexp: +Or in the middle of a regexp: ```js run let regexp = /CS.4/; alert( "CSS4".match(regexp) ); // CSS4 alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) +alert( "CS 4".match(regexp) ); // CS 4 (space is also a character) ``` -Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: +Please note that a dot means "any character", but not the "absence of a character". There must be a character to match it: ```js run -alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto +alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot ``` -### Ponto como literalmente qualquer caractere com a flag "s" +### Dot as literally any character with "s" flag -Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. +By default, a dot doesn't match the newline character `\n`. -Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: +For instance, the regexp `pattern:A.B` matches `match:A`, and then `match:B` with any character between them, except a newline `\n`: ```js run -alert( "A\nB".match(/A.B/) ); // null (sem correspondência) +alert( "A\nB".match(/A.B/) ); // null (no match) ``` -Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. +There are many situations when we'd like a dot to mean literally "any character", newline included. -É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: +That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` matches literally any character: ```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) +alert( "A\nB".match(/A.B/s) ); // A\nB (match!) ``` -````warn header="Não suportado no Firefox, IE, Edge" -Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. +````warn header="Not supported in IE" +The `pattern:s` flag is not supported in IE. -Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". +Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character" (this pattern will be covered in the article ). ```js run alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) ``` -O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. +The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter. Or even the `pattern:[^]` -- as it means match any character except nothing. -Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. +Also we can use this trick if we want both kind of "dots" in the same pattern: the actual dot `pattern:.` behaving the regular way ("not including a newline"), and also a way to match "any character" with `pattern:[\s\S]` or alike. ```` -````warn header="Preste atenção nos espaços" -Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. +````warn header="Pay attention to spaces" +Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. -Mas se uma regexp não leva em consideração os espaços, ela pode falhar. +But if a regexp doesn't take spaces into account, it may fail to work. -Vamos tentar encontrar dígitos separados por um hífen: +Let's try to find digits separated by a hyphen: ```js run -alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! +alert( "1 - 5".match(/\d-\d/) ); // null, no match! ``` -Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: +Let's fix it adding spaces into the regexp `pattern:\d - \d`: ```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona -// ou podemos usar a classe \s: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works +// or we can use \s class: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works ``` -**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** +**A space is a character. Equal in importance with any other character.** -Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. +We can't add or remove spaces from a regular expression and expect it to work the same. -Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. +In other words, in a regular expression all characters matter, spaces too. ```` -## Resumo +## Summary -Existem as seguintes classes de caracteres: +There exist following character classes: -- `padrão:\d` - dígitos. -- `padrão:\D` - sem dígitos. -- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. -- `padrão:\S` - todos, exceto `padrão:\s`. -- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. -- `padrão:\W` - todos, exceto `padrão:\w`. -- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. +- `pattern:\d` -- digits. +- `pattern:\D` -- non-digits. +- `pattern:\s` -- space symbols, tabs, newlines. +- `pattern:\S` -- all but `pattern:\s`. +- `pattern:\w` -- Latin letters, digits, underscore `'_'`. +- `pattern:\W` -- all but `pattern:\w`. +- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline `\n`. -...Mas isso não é tudo! +...But that's not all! -A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. +Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter), is it a punctuation sign, etc. -Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. +We can search by these properties as well. That requires flag `pattern:u`, covered in the next article. From cdade39bdce19a3fe5bd8d861f44cd46436b54c9 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:42:21 +0100 Subject: [PATCH 10/32] Revert "Revert "Merge branch 'fsdude-02-regexp-character-classes' into master"" This reverts commit 38aa681926db834443bbc5ade69f5553a13a6d5d. --- .../02-regexp-character-classes/article.md | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/9-regular-expressions/02-regexp-character-classes/article.md b/9-regular-expressions/02-regexp-character-classes/article.md index 201c78a05..94c875955 100644 --- a/9-regular-expressions/02-regexp-character-classes/article.md +++ b/9-regular-expressions/02-regexp-character-classes/article.md @@ -1,14 +1,14 @@ -# Character classes +# Classes de caracteres -Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79031234567`. +Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. -To do so, we can find and remove anything that's not a number. Character classes can help with that. +Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. -A *character class* is a special notation that matches any symbol from a certain set. +Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. -For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit". +Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". -For instance, let's find the first digit in the phone number: +Por exemplo, vamos encontrar o primeiro dígito no número de telefone: ```js run let str = "+7(903)-123-45-67"; @@ -18,73 +18,73 @@ let regexp = /\d/; alert( str.match(regexp) ); // 7 ``` -Without the flag `pattern:g`, the regular expression only looks for the first match, that is the first digit `pattern:\d`. +Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. -Let's add the `pattern:g` flag to find all digits: +Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: ```js run let str = "+7(903)-123-45-67"; let regexp = /\d/g; -alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 +alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 -// let's make the digits-only phone number of them: +// vamos criar o número de telefone apenas com dígitos: alert( str.match(regexp).join('') ); // 79031234567 ``` -That was a character class for digits. There are other character classes as well. +Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. -Most used are: +As mais usadas são: -`pattern:\d` ("d" is from "digit") -: A digit: a character from `0` to `9`. +`padrão:\d` ("d" é de "digit") +: Um dígito: um caractere de `0` a `9`. -`pattern:\s` ("s" is from "space") -: A space symbol: includes spaces, tabs `\t`, newlines `\n` and few other rare characters, such as `\v`, `\f` and `\r`. +`padrão:\s` ("s" é de "space") +: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. -`pattern:\w` ("w" is from "word") -: A "wordly" character: either a letter of Latin alphabet or a digit or an underscore `_`. Non-Latin letters (like cyrillic or hindi) do not belong to `pattern:\w`. +`padrão:\w` ("w" é de "word") +: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. -For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", such as `match:1 a`. +Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. -**A regexp may contain both regular symbols and character classes.** +**Uma regexp pode conter símbolos regulares e classes de caracteres.** -For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: +Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: ```js run -let str = "Is there CSS4?"; +let str = "Existe CSS4?"; let regexp = /CSS\d/ alert( str.match(regexp) ); // CSS4 ``` -Also we can use many character classes: +Também podemos usar muitas classes de caracteres: ```js run -alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' ``` -The match (each regexp character class has the corresponding result character): +A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): ![](love-html5-classes.svg) -## Inverse classes +## Classes inversas -For every character class there exists an "inverse class", denoted with the same letter, but uppercased. +Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. -The "inverse" means that it matches all other characters, for instance: +O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: -`pattern:\D` -: Non-digit: any character except `pattern:\d`, for instance a letter. +`padrão:\D` +: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. -`pattern:\S` -: Non-space: any character except `pattern:\s`, for instance a letter. +`padrão:\S` +: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. -`pattern:\W` -: Non-wordly character: anything but `pattern:\w`, e.g a non-latin letter or a space. +`padrão:\W` +: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. -In the beginning of the chapter we saw how to make a number-only phone number from a string like `subject:+7(903)-123-45-67`: find all digits and join them. +No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. ```js run let str = "+7(903)-123-45-67"; @@ -92,7 +92,7 @@ let str = "+7(903)-123-45-67"; alert( str.match(/\d/g).join('') ); // 79031234567 ``` -An alternative, shorter way is to find non-digits `pattern:\D` and remove them from the string: +Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: ```js run let str = "+7(903)-123-45-67"; @@ -100,104 +100,104 @@ let str = "+7(903)-123-45-67"; alert( str.replace(/\D/g, "") ); // 79031234567 ``` -## A dot is "any character" +## Um ponto é "qualquer caractere" -A dot `pattern:.` is a special character class that matches "any character except a newline". +Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". -For instance: +Por exemplo: ```js run alert( "Z".match(/./) ); // Z ``` -Or in the middle of a regexp: +Ou no meio de uma regexp: ```js run let regexp = /CS.4/; alert( "CSS4".match(regexp) ); // CSS4 alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (space is also a character) +alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) ``` -Please note that a dot means "any character", but not the "absence of a character". There must be a character to match it: +Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: ```js run -alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot +alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto ``` -### Dot as literally any character with "s" flag +### Ponto como literalmente qualquer caractere com a flag "s" -By default, a dot doesn't match the newline character `\n`. +Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. -For instance, the regexp `pattern:A.B` matches `match:A`, and then `match:B` with any character between them, except a newline `\n`: +Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: ```js run -alert( "A\nB".match(/A.B/) ); // null (no match) +alert( "A\nB".match(/A.B/) ); // null (sem correspondência) ``` -There are many situations when we'd like a dot to mean literally "any character", newline included. +Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. -That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` matches literally any character: +É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: ```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (match!) +alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) ``` -````warn header="Not supported in IE" -The `pattern:s` flag is not supported in IE. +````warn header="Não suportado no Firefox, IE, Edge" +Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. -Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character" (this pattern will be covered in the article ). +Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". ```js run alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) ``` -The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter. Or even the `pattern:[^]` -- as it means match any character except nothing. +O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. -Also we can use this trick if we want both kind of "dots" in the same pattern: the actual dot `pattern:.` behaving the regular way ("not including a newline"), and also a way to match "any character" with `pattern:[\s\S]` or alike. +Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. ```` -````warn header="Pay attention to spaces" -Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. +````warn header="Preste atenção nos espaços" +Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. -But if a regexp doesn't take spaces into account, it may fail to work. +Mas se uma regexp não leva em consideração os espaços, ela pode falhar. -Let's try to find digits separated by a hyphen: +Vamos tentar encontrar dígitos separados por um hífen: ```js run -alert( "1 - 5".match(/\d-\d/) ); // null, no match! +alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! ``` -Let's fix it adding spaces into the regexp `pattern:\d - \d`: +Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: ```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works -// or we can use \s class: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona +// ou podemos usar a classe \s: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona ``` -**A space is a character. Equal in importance with any other character.** +**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** -We can't add or remove spaces from a regular expression and expect it to work the same. +Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. -In other words, in a regular expression all characters matter, spaces too. +Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. ```` -## Summary +## Resumo -There exist following character classes: +Existem as seguintes classes de caracteres: -- `pattern:\d` -- digits. -- `pattern:\D` -- non-digits. -- `pattern:\s` -- space symbols, tabs, newlines. -- `pattern:\S` -- all but `pattern:\s`. -- `pattern:\w` -- Latin letters, digits, underscore `'_'`. -- `pattern:\W` -- all but `pattern:\w`. -- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline `\n`. +- `padrão:\d` - dígitos. +- `padrão:\D` - sem dígitos. +- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. +- `padrão:\S` - todos, exceto `padrão:\s`. +- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. +- `padrão:\W` - todos, exceto `padrão:\w`. +- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. -...But that's not all! +...Mas isso não é tudo! -Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter), is it a punctuation sign, etc. +A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. -We can search by these properties as well. That requires flag `pattern:u`, covered in the next article. +Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. From 30fcc305a1f5aea0487914fbf21c2a0ac0e395de Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:42:28 +0100 Subject: [PATCH 11/32] Revert "Revert "Revert "Merge branch 'fsdude-02-regexp-character-classes' into master""" This reverts commit cdade39bdce19a3fe5bd8d861f44cd46436b54c9. --- .../02-regexp-character-classes/article.md | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/9-regular-expressions/02-regexp-character-classes/article.md b/9-regular-expressions/02-regexp-character-classes/article.md index 94c875955..201c78a05 100644 --- a/9-regular-expressions/02-regexp-character-classes/article.md +++ b/9-regular-expressions/02-regexp-character-classes/article.md @@ -1,14 +1,14 @@ -# Classes de caracteres +# Character classes -Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. +Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79031234567`. -Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. +To do so, we can find and remove anything that's not a number. Character classes can help with that. -Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. +A *character class* is a special notation that matches any symbol from a certain set. -Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". +For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit". -Por exemplo, vamos encontrar o primeiro dígito no número de telefone: +For instance, let's find the first digit in the phone number: ```js run let str = "+7(903)-123-45-67"; @@ -18,73 +18,73 @@ let regexp = /\d/; alert( str.match(regexp) ); // 7 ``` -Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. +Without the flag `pattern:g`, the regular expression only looks for the first match, that is the first digit `pattern:\d`. -Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: +Let's add the `pattern:g` flag to find all digits: ```js run let str = "+7(903)-123-45-67"; let regexp = /\d/g; -alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 +alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 -// vamos criar o número de telefone apenas com dígitos: +// let's make the digits-only phone number of them: alert( str.match(regexp).join('') ); // 79031234567 ``` -Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. +That was a character class for digits. There are other character classes as well. -As mais usadas são: +Most used are: -`padrão:\d` ("d" é de "digit") -: Um dígito: um caractere de `0` a `9`. +`pattern:\d` ("d" is from "digit") +: A digit: a character from `0` to `9`. -`padrão:\s` ("s" é de "space") -: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. +`pattern:\s` ("s" is from "space") +: A space symbol: includes spaces, tabs `\t`, newlines `\n` and few other rare characters, such as `\v`, `\f` and `\r`. -`padrão:\w` ("w" é de "word") -: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. +`pattern:\w` ("w" is from "word") +: A "wordly" character: either a letter of Latin alphabet or a digit or an underscore `_`. Non-Latin letters (like cyrillic or hindi) do not belong to `pattern:\w`. -Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. +For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", such as `match:1 a`. -**Uma regexp pode conter símbolos regulares e classes de caracteres.** +**A regexp may contain both regular symbols and character classes.** -Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: +For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: ```js run -let str = "Existe CSS4?"; +let str = "Is there CSS4?"; let regexp = /CSS\d/ alert( str.match(regexp) ); // CSS4 ``` -Também podemos usar muitas classes de caracteres: +Also we can use many character classes: ```js run -alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' ``` -A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): +The match (each regexp character class has the corresponding result character): ![](love-html5-classes.svg) -## Classes inversas +## Inverse classes -Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. +For every character class there exists an "inverse class", denoted with the same letter, but uppercased. -O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: +The "inverse" means that it matches all other characters, for instance: -`padrão:\D` -: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. +`pattern:\D` +: Non-digit: any character except `pattern:\d`, for instance a letter. -`padrão:\S` -: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. +`pattern:\S` +: Non-space: any character except `pattern:\s`, for instance a letter. -`padrão:\W` -: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. +`pattern:\W` +: Non-wordly character: anything but `pattern:\w`, e.g a non-latin letter or a space. -No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. +In the beginning of the chapter we saw how to make a number-only phone number from a string like `subject:+7(903)-123-45-67`: find all digits and join them. ```js run let str = "+7(903)-123-45-67"; @@ -92,7 +92,7 @@ let str = "+7(903)-123-45-67"; alert( str.match(/\d/g).join('') ); // 79031234567 ``` -Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: +An alternative, shorter way is to find non-digits `pattern:\D` and remove them from the string: ```js run let str = "+7(903)-123-45-67"; @@ -100,104 +100,104 @@ let str = "+7(903)-123-45-67"; alert( str.replace(/\D/g, "") ); // 79031234567 ``` -## Um ponto é "qualquer caractere" +## A dot is "any character" -Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". +A dot `pattern:.` is a special character class that matches "any character except a newline". -Por exemplo: +For instance: ```js run alert( "Z".match(/./) ); // Z ``` -Ou no meio de uma regexp: +Or in the middle of a regexp: ```js run let regexp = /CS.4/; alert( "CSS4".match(regexp) ); // CSS4 alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) +alert( "CS 4".match(regexp) ); // CS 4 (space is also a character) ``` -Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: +Please note that a dot means "any character", but not the "absence of a character". There must be a character to match it: ```js run -alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto +alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot ``` -### Ponto como literalmente qualquer caractere com a flag "s" +### Dot as literally any character with "s" flag -Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. +By default, a dot doesn't match the newline character `\n`. -Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: +For instance, the regexp `pattern:A.B` matches `match:A`, and then `match:B` with any character between them, except a newline `\n`: ```js run -alert( "A\nB".match(/A.B/) ); // null (sem correspondência) +alert( "A\nB".match(/A.B/) ); // null (no match) ``` -Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. +There are many situations when we'd like a dot to mean literally "any character", newline included. -É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: +That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` matches literally any character: ```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) +alert( "A\nB".match(/A.B/s) ); // A\nB (match!) ``` -````warn header="Não suportado no Firefox, IE, Edge" -Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. +````warn header="Not supported in IE" +The `pattern:s` flag is not supported in IE. -Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". +Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character" (this pattern will be covered in the article ). ```js run alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) ``` -O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. +The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter. Or even the `pattern:[^]` -- as it means match any character except nothing. -Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. +Also we can use this trick if we want both kind of "dots" in the same pattern: the actual dot `pattern:.` behaving the regular way ("not including a newline"), and also a way to match "any character" with `pattern:[\s\S]` or alike. ```` -````warn header="Preste atenção nos espaços" -Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. +````warn header="Pay attention to spaces" +Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. -Mas se uma regexp não leva em consideração os espaços, ela pode falhar. +But if a regexp doesn't take spaces into account, it may fail to work. -Vamos tentar encontrar dígitos separados por um hífen: +Let's try to find digits separated by a hyphen: ```js run -alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! +alert( "1 - 5".match(/\d-\d/) ); // null, no match! ``` -Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: +Let's fix it adding spaces into the regexp `pattern:\d - \d`: ```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona -// ou podemos usar a classe \s: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works +// or we can use \s class: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works ``` -**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** +**A space is a character. Equal in importance with any other character.** -Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. +We can't add or remove spaces from a regular expression and expect it to work the same. -Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. +In other words, in a regular expression all characters matter, spaces too. ```` -## Resumo +## Summary -Existem as seguintes classes de caracteres: +There exist following character classes: -- `padrão:\d` - dígitos. -- `padrão:\D` - sem dígitos. -- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. -- `padrão:\S` - todos, exceto `padrão:\s`. -- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. -- `padrão:\W` - todos, exceto `padrão:\w`. -- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. +- `pattern:\d` -- digits. +- `pattern:\D` -- non-digits. +- `pattern:\s` -- space symbols, tabs, newlines. +- `pattern:\S` -- all but `pattern:\s`. +- `pattern:\w` -- Latin letters, digits, underscore `'_'`. +- `pattern:\W` -- all but `pattern:\w`. +- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline `\n`. -...Mas isso não é tudo! +...But that's not all! -A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. +Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter), is it a punctuation sign, etc. -Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. +We can search by these properties as well. That requires flag `pattern:u`, covered in the next article. From 72e1fa8597670887abe329a0f14de499b9a5908e Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:44:11 +0100 Subject: [PATCH 12/32] Revert "Revert "Revert "Revert "Merge branch 'fsdude-02-regexp-character-classes' into master"""" This reverts commit 30fcc305a1f5aea0487914fbf21c2a0ac0e395de. --- .../02-regexp-character-classes/article.md | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/9-regular-expressions/02-regexp-character-classes/article.md b/9-regular-expressions/02-regexp-character-classes/article.md index 201c78a05..94c875955 100644 --- a/9-regular-expressions/02-regexp-character-classes/article.md +++ b/9-regular-expressions/02-regexp-character-classes/article.md @@ -1,14 +1,14 @@ -# Character classes +# Classes de caracteres -Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79031234567`. +Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. -To do so, we can find and remove anything that's not a number. Character classes can help with that. +Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. -A *character class* is a special notation that matches any symbol from a certain set. +Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. -For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit". +Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". -For instance, let's find the first digit in the phone number: +Por exemplo, vamos encontrar o primeiro dígito no número de telefone: ```js run let str = "+7(903)-123-45-67"; @@ -18,73 +18,73 @@ let regexp = /\d/; alert( str.match(regexp) ); // 7 ``` -Without the flag `pattern:g`, the regular expression only looks for the first match, that is the first digit `pattern:\d`. +Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. -Let's add the `pattern:g` flag to find all digits: +Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: ```js run let str = "+7(903)-123-45-67"; let regexp = /\d/g; -alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 +alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 -// let's make the digits-only phone number of them: +// vamos criar o número de telefone apenas com dígitos: alert( str.match(regexp).join('') ); // 79031234567 ``` -That was a character class for digits. There are other character classes as well. +Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. -Most used are: +As mais usadas são: -`pattern:\d` ("d" is from "digit") -: A digit: a character from `0` to `9`. +`padrão:\d` ("d" é de "digit") +: Um dígito: um caractere de `0` a `9`. -`pattern:\s` ("s" is from "space") -: A space symbol: includes spaces, tabs `\t`, newlines `\n` and few other rare characters, such as `\v`, `\f` and `\r`. +`padrão:\s` ("s" é de "space") +: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. -`pattern:\w` ("w" is from "word") -: A "wordly" character: either a letter of Latin alphabet or a digit or an underscore `_`. Non-Latin letters (like cyrillic or hindi) do not belong to `pattern:\w`. +`padrão:\w` ("w" é de "word") +: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. -For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", such as `match:1 a`. +Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. -**A regexp may contain both regular symbols and character classes.** +**Uma regexp pode conter símbolos regulares e classes de caracteres.** -For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: +Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: ```js run -let str = "Is there CSS4?"; +let str = "Existe CSS4?"; let regexp = /CSS\d/ alert( str.match(regexp) ); // CSS4 ``` -Also we can use many character classes: +Também podemos usar muitas classes de caracteres: ```js run -alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' ``` -The match (each regexp character class has the corresponding result character): +A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): ![](love-html5-classes.svg) -## Inverse classes +## Classes inversas -For every character class there exists an "inverse class", denoted with the same letter, but uppercased. +Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. -The "inverse" means that it matches all other characters, for instance: +O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: -`pattern:\D` -: Non-digit: any character except `pattern:\d`, for instance a letter. +`padrão:\D` +: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. -`pattern:\S` -: Non-space: any character except `pattern:\s`, for instance a letter. +`padrão:\S` +: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. -`pattern:\W` -: Non-wordly character: anything but `pattern:\w`, e.g a non-latin letter or a space. +`padrão:\W` +: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. -In the beginning of the chapter we saw how to make a number-only phone number from a string like `subject:+7(903)-123-45-67`: find all digits and join them. +No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. ```js run let str = "+7(903)-123-45-67"; @@ -92,7 +92,7 @@ let str = "+7(903)-123-45-67"; alert( str.match(/\d/g).join('') ); // 79031234567 ``` -An alternative, shorter way is to find non-digits `pattern:\D` and remove them from the string: +Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: ```js run let str = "+7(903)-123-45-67"; @@ -100,104 +100,104 @@ let str = "+7(903)-123-45-67"; alert( str.replace(/\D/g, "") ); // 79031234567 ``` -## A dot is "any character" +## Um ponto é "qualquer caractere" -A dot `pattern:.` is a special character class that matches "any character except a newline". +Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". -For instance: +Por exemplo: ```js run alert( "Z".match(/./) ); // Z ``` -Or in the middle of a regexp: +Ou no meio de uma regexp: ```js run let regexp = /CS.4/; alert( "CSS4".match(regexp) ); // CSS4 alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (space is also a character) +alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) ``` -Please note that a dot means "any character", but not the "absence of a character". There must be a character to match it: +Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: ```js run -alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot +alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto ``` -### Dot as literally any character with "s" flag +### Ponto como literalmente qualquer caractere com a flag "s" -By default, a dot doesn't match the newline character `\n`. +Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. -For instance, the regexp `pattern:A.B` matches `match:A`, and then `match:B` with any character between them, except a newline `\n`: +Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: ```js run -alert( "A\nB".match(/A.B/) ); // null (no match) +alert( "A\nB".match(/A.B/) ); // null (sem correspondência) ``` -There are many situations when we'd like a dot to mean literally "any character", newline included. +Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. -That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` matches literally any character: +É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: ```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (match!) +alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) ``` -````warn header="Not supported in IE" -The `pattern:s` flag is not supported in IE. +````warn header="Não suportado no Firefox, IE, Edge" +Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. -Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character" (this pattern will be covered in the article ). +Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". ```js run alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) ``` -The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter. Or even the `pattern:[^]` -- as it means match any character except nothing. +O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. -Also we can use this trick if we want both kind of "dots" in the same pattern: the actual dot `pattern:.` behaving the regular way ("not including a newline"), and also a way to match "any character" with `pattern:[\s\S]` or alike. +Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. ```` -````warn header="Pay attention to spaces" -Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. +````warn header="Preste atenção nos espaços" +Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. -But if a regexp doesn't take spaces into account, it may fail to work. +Mas se uma regexp não leva em consideração os espaços, ela pode falhar. -Let's try to find digits separated by a hyphen: +Vamos tentar encontrar dígitos separados por um hífen: ```js run -alert( "1 - 5".match(/\d-\d/) ); // null, no match! +alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! ``` -Let's fix it adding spaces into the regexp `pattern:\d - \d`: +Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: ```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works -// or we can use \s class: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona +// ou podemos usar a classe \s: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona ``` -**A space is a character. Equal in importance with any other character.** +**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** -We can't add or remove spaces from a regular expression and expect it to work the same. +Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. -In other words, in a regular expression all characters matter, spaces too. +Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. ```` -## Summary +## Resumo -There exist following character classes: +Existem as seguintes classes de caracteres: -- `pattern:\d` -- digits. -- `pattern:\D` -- non-digits. -- `pattern:\s` -- space symbols, tabs, newlines. -- `pattern:\S` -- all but `pattern:\s`. -- `pattern:\w` -- Latin letters, digits, underscore `'_'`. -- `pattern:\W` -- all but `pattern:\w`. -- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline `\n`. +- `padrão:\d` - dígitos. +- `padrão:\D` - sem dígitos. +- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. +- `padrão:\S` - todos, exceto `padrão:\s`. +- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. +- `padrão:\W` - todos, exceto `padrão:\w`. +- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. -...But that's not all! +...Mas isso não é tudo! -Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter), is it a punctuation sign, etc. +A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. -We can search by these properties as well. That requires flag `pattern:u`, covered in the next article. +Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. From 08e5000d018f190b610c7ee0577d296aa65a0cf2 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:44:54 +0100 Subject: [PATCH 13/32] Revert "Revert "Revert "Revert "Revert "Merge branch 'fsdude-02-regexp-character-classes' into master""""" This reverts commit 72e1fa8597670887abe329a0f14de499b9a5908e. --- .../02-regexp-character-classes/article.md | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/9-regular-expressions/02-regexp-character-classes/article.md b/9-regular-expressions/02-regexp-character-classes/article.md index 94c875955..201c78a05 100644 --- a/9-regular-expressions/02-regexp-character-classes/article.md +++ b/9-regular-expressions/02-regexp-character-classes/article.md @@ -1,14 +1,14 @@ -# Classes de caracteres +# Character classes -Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. +Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79031234567`. -Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. +To do so, we can find and remove anything that's not a number. Character classes can help with that. -Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. +A *character class* is a special notation that matches any symbol from a certain set. -Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". +For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit". -Por exemplo, vamos encontrar o primeiro dígito no número de telefone: +For instance, let's find the first digit in the phone number: ```js run let str = "+7(903)-123-45-67"; @@ -18,73 +18,73 @@ let regexp = /\d/; alert( str.match(regexp) ); // 7 ``` -Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. +Without the flag `pattern:g`, the regular expression only looks for the first match, that is the first digit `pattern:\d`. -Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: +Let's add the `pattern:g` flag to find all digits: ```js run let str = "+7(903)-123-45-67"; let regexp = /\d/g; -alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 +alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 -// vamos criar o número de telefone apenas com dígitos: +// let's make the digits-only phone number of them: alert( str.match(regexp).join('') ); // 79031234567 ``` -Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. +That was a character class for digits. There are other character classes as well. -As mais usadas são: +Most used are: -`padrão:\d` ("d" é de "digit") -: Um dígito: um caractere de `0` a `9`. +`pattern:\d` ("d" is from "digit") +: A digit: a character from `0` to `9`. -`padrão:\s` ("s" é de "space") -: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. +`pattern:\s` ("s" is from "space") +: A space symbol: includes spaces, tabs `\t`, newlines `\n` and few other rare characters, such as `\v`, `\f` and `\r`. -`padrão:\w` ("w" é de "word") -: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. +`pattern:\w` ("w" is from "word") +: A "wordly" character: either a letter of Latin alphabet or a digit or an underscore `_`. Non-Latin letters (like cyrillic or hindi) do not belong to `pattern:\w`. -Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. +For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", such as `match:1 a`. -**Uma regexp pode conter símbolos regulares e classes de caracteres.** +**A regexp may contain both regular symbols and character classes.** -Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: +For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: ```js run -let str = "Existe CSS4?"; +let str = "Is there CSS4?"; let regexp = /CSS\d/ alert( str.match(regexp) ); // CSS4 ``` -Também podemos usar muitas classes de caracteres: +Also we can use many character classes: ```js run -alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' ``` -A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): +The match (each regexp character class has the corresponding result character): ![](love-html5-classes.svg) -## Classes inversas +## Inverse classes -Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. +For every character class there exists an "inverse class", denoted with the same letter, but uppercased. -O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: +The "inverse" means that it matches all other characters, for instance: -`padrão:\D` -: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. +`pattern:\D` +: Non-digit: any character except `pattern:\d`, for instance a letter. -`padrão:\S` -: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. +`pattern:\S` +: Non-space: any character except `pattern:\s`, for instance a letter. -`padrão:\W` -: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. +`pattern:\W` +: Non-wordly character: anything but `pattern:\w`, e.g a non-latin letter or a space. -No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. +In the beginning of the chapter we saw how to make a number-only phone number from a string like `subject:+7(903)-123-45-67`: find all digits and join them. ```js run let str = "+7(903)-123-45-67"; @@ -92,7 +92,7 @@ let str = "+7(903)-123-45-67"; alert( str.match(/\d/g).join('') ); // 79031234567 ``` -Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: +An alternative, shorter way is to find non-digits `pattern:\D` and remove them from the string: ```js run let str = "+7(903)-123-45-67"; @@ -100,104 +100,104 @@ let str = "+7(903)-123-45-67"; alert( str.replace(/\D/g, "") ); // 79031234567 ``` -## Um ponto é "qualquer caractere" +## A dot is "any character" -Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". +A dot `pattern:.` is a special character class that matches "any character except a newline". -Por exemplo: +For instance: ```js run alert( "Z".match(/./) ); // Z ``` -Ou no meio de uma regexp: +Or in the middle of a regexp: ```js run let regexp = /CS.4/; alert( "CSS4".match(regexp) ); // CSS4 alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) +alert( "CS 4".match(regexp) ); // CS 4 (space is also a character) ``` -Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: +Please note that a dot means "any character", but not the "absence of a character". There must be a character to match it: ```js run -alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto +alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot ``` -### Ponto como literalmente qualquer caractere com a flag "s" +### Dot as literally any character with "s" flag -Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. +By default, a dot doesn't match the newline character `\n`. -Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: +For instance, the regexp `pattern:A.B` matches `match:A`, and then `match:B` with any character between them, except a newline `\n`: ```js run -alert( "A\nB".match(/A.B/) ); // null (sem correspondência) +alert( "A\nB".match(/A.B/) ); // null (no match) ``` -Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. +There are many situations when we'd like a dot to mean literally "any character", newline included. -É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: +That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` matches literally any character: ```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) +alert( "A\nB".match(/A.B/s) ); // A\nB (match!) ``` -````warn header="Não suportado no Firefox, IE, Edge" -Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. +````warn header="Not supported in IE" +The `pattern:s` flag is not supported in IE. -Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". +Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character" (this pattern will be covered in the article ). ```js run alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) ``` -O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. +The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter. Or even the `pattern:[^]` -- as it means match any character except nothing. -Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. +Also we can use this trick if we want both kind of "dots" in the same pattern: the actual dot `pattern:.` behaving the regular way ("not including a newline"), and also a way to match "any character" with `pattern:[\s\S]` or alike. ```` -````warn header="Preste atenção nos espaços" -Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. +````warn header="Pay attention to spaces" +Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. -Mas se uma regexp não leva em consideração os espaços, ela pode falhar. +But if a regexp doesn't take spaces into account, it may fail to work. -Vamos tentar encontrar dígitos separados por um hífen: +Let's try to find digits separated by a hyphen: ```js run -alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! +alert( "1 - 5".match(/\d-\d/) ); // null, no match! ``` -Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: +Let's fix it adding spaces into the regexp `pattern:\d - \d`: ```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona -// ou podemos usar a classe \s: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works +// or we can use \s class: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works ``` -**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** +**A space is a character. Equal in importance with any other character.** -Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. +We can't add or remove spaces from a regular expression and expect it to work the same. -Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. +In other words, in a regular expression all characters matter, spaces too. ```` -## Resumo +## Summary -Existem as seguintes classes de caracteres: +There exist following character classes: -- `padrão:\d` - dígitos. -- `padrão:\D` - sem dígitos. -- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. -- `padrão:\S` - todos, exceto `padrão:\s`. -- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. -- `padrão:\W` - todos, exceto `padrão:\w`. -- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. +- `pattern:\d` -- digits. +- `pattern:\D` -- non-digits. +- `pattern:\s` -- space symbols, tabs, newlines. +- `pattern:\S` -- all but `pattern:\s`. +- `pattern:\w` -- Latin letters, digits, underscore `'_'`. +- `pattern:\W` -- all but `pattern:\w`. +- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline `\n`. -...Mas isso não é tudo! +...But that's not all! -A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. +Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter), is it a punctuation sign, etc. -Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. +We can search by these properties as well. That requires flag `pattern:u`, covered in the next article. From 082dff24db8e40f9f7d82dbba576a7b18cac69f8 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:45:07 +0100 Subject: [PATCH 14/32] Revert "Revert "Revert "Revert "Merge branch 'fsdude-02-regexp-character-classes' into master"""" This reverts commit 30fcc305a1f5aea0487914fbf21c2a0ac0e395de. --- .../02-regexp-character-classes/article.md | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/9-regular-expressions/02-regexp-character-classes/article.md b/9-regular-expressions/02-regexp-character-classes/article.md index 201c78a05..94c875955 100644 --- a/9-regular-expressions/02-regexp-character-classes/article.md +++ b/9-regular-expressions/02-regexp-character-classes/article.md @@ -1,14 +1,14 @@ -# Character classes +# Classes de caracteres -Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79031234567`. +Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. -To do so, we can find and remove anything that's not a number. Character classes can help with that. +Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. -A *character class* is a special notation that matches any symbol from a certain set. +Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. -For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit". +Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". -For instance, let's find the first digit in the phone number: +Por exemplo, vamos encontrar o primeiro dígito no número de telefone: ```js run let str = "+7(903)-123-45-67"; @@ -18,73 +18,73 @@ let regexp = /\d/; alert( str.match(regexp) ); // 7 ``` -Without the flag `pattern:g`, the regular expression only looks for the first match, that is the first digit `pattern:\d`. +Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. -Let's add the `pattern:g` flag to find all digits: +Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: ```js run let str = "+7(903)-123-45-67"; let regexp = /\d/g; -alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 +alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 -// let's make the digits-only phone number of them: +// vamos criar o número de telefone apenas com dígitos: alert( str.match(regexp).join('') ); // 79031234567 ``` -That was a character class for digits. There are other character classes as well. +Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. -Most used are: +As mais usadas são: -`pattern:\d` ("d" is from "digit") -: A digit: a character from `0` to `9`. +`padrão:\d` ("d" é de "digit") +: Um dígito: um caractere de `0` a `9`. -`pattern:\s` ("s" is from "space") -: A space symbol: includes spaces, tabs `\t`, newlines `\n` and few other rare characters, such as `\v`, `\f` and `\r`. +`padrão:\s` ("s" é de "space") +: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. -`pattern:\w` ("w" is from "word") -: A "wordly" character: either a letter of Latin alphabet or a digit or an underscore `_`. Non-Latin letters (like cyrillic or hindi) do not belong to `pattern:\w`. +`padrão:\w` ("w" é de "word") +: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. -For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", such as `match:1 a`. +Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. -**A regexp may contain both regular symbols and character classes.** +**Uma regexp pode conter símbolos regulares e classes de caracteres.** -For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: +Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: ```js run -let str = "Is there CSS4?"; +let str = "Existe CSS4?"; let regexp = /CSS\d/ alert( str.match(regexp) ); // CSS4 ``` -Also we can use many character classes: +Também podemos usar muitas classes de caracteres: ```js run -alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' ``` -The match (each regexp character class has the corresponding result character): +A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): ![](love-html5-classes.svg) -## Inverse classes +## Classes inversas -For every character class there exists an "inverse class", denoted with the same letter, but uppercased. +Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. -The "inverse" means that it matches all other characters, for instance: +O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: -`pattern:\D` -: Non-digit: any character except `pattern:\d`, for instance a letter. +`padrão:\D` +: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. -`pattern:\S` -: Non-space: any character except `pattern:\s`, for instance a letter. +`padrão:\S` +: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. -`pattern:\W` -: Non-wordly character: anything but `pattern:\w`, e.g a non-latin letter or a space. +`padrão:\W` +: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. -In the beginning of the chapter we saw how to make a number-only phone number from a string like `subject:+7(903)-123-45-67`: find all digits and join them. +No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. ```js run let str = "+7(903)-123-45-67"; @@ -92,7 +92,7 @@ let str = "+7(903)-123-45-67"; alert( str.match(/\d/g).join('') ); // 79031234567 ``` -An alternative, shorter way is to find non-digits `pattern:\D` and remove them from the string: +Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: ```js run let str = "+7(903)-123-45-67"; @@ -100,104 +100,104 @@ let str = "+7(903)-123-45-67"; alert( str.replace(/\D/g, "") ); // 79031234567 ``` -## A dot is "any character" +## Um ponto é "qualquer caractere" -A dot `pattern:.` is a special character class that matches "any character except a newline". +Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". -For instance: +Por exemplo: ```js run alert( "Z".match(/./) ); // Z ``` -Or in the middle of a regexp: +Ou no meio de uma regexp: ```js run let regexp = /CS.4/; alert( "CSS4".match(regexp) ); // CSS4 alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (space is also a character) +alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) ``` -Please note that a dot means "any character", but not the "absence of a character". There must be a character to match it: +Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: ```js run -alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot +alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto ``` -### Dot as literally any character with "s" flag +### Ponto como literalmente qualquer caractere com a flag "s" -By default, a dot doesn't match the newline character `\n`. +Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. -For instance, the regexp `pattern:A.B` matches `match:A`, and then `match:B` with any character between them, except a newline `\n`: +Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: ```js run -alert( "A\nB".match(/A.B/) ); // null (no match) +alert( "A\nB".match(/A.B/) ); // null (sem correspondência) ``` -There are many situations when we'd like a dot to mean literally "any character", newline included. +Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. -That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` matches literally any character: +É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: ```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (match!) +alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) ``` -````warn header="Not supported in IE" -The `pattern:s` flag is not supported in IE. +````warn header="Não suportado no Firefox, IE, Edge" +Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. -Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character" (this pattern will be covered in the article ). +Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". ```js run alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) ``` -The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter. Or even the `pattern:[^]` -- as it means match any character except nothing. +O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. -Also we can use this trick if we want both kind of "dots" in the same pattern: the actual dot `pattern:.` behaving the regular way ("not including a newline"), and also a way to match "any character" with `pattern:[\s\S]` or alike. +Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. ```` -````warn header="Pay attention to spaces" -Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. +````warn header="Preste atenção nos espaços" +Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. -But if a regexp doesn't take spaces into account, it may fail to work. +Mas se uma regexp não leva em consideração os espaços, ela pode falhar. -Let's try to find digits separated by a hyphen: +Vamos tentar encontrar dígitos separados por um hífen: ```js run -alert( "1 - 5".match(/\d-\d/) ); // null, no match! +alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! ``` -Let's fix it adding spaces into the regexp `pattern:\d - \d`: +Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: ```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works -// or we can use \s class: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona +// ou podemos usar a classe \s: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona ``` -**A space is a character. Equal in importance with any other character.** +**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** -We can't add or remove spaces from a regular expression and expect it to work the same. +Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. -In other words, in a regular expression all characters matter, spaces too. +Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. ```` -## Summary +## Resumo -There exist following character classes: +Existem as seguintes classes de caracteres: -- `pattern:\d` -- digits. -- `pattern:\D` -- non-digits. -- `pattern:\s` -- space symbols, tabs, newlines. -- `pattern:\S` -- all but `pattern:\s`. -- `pattern:\w` -- Latin letters, digits, underscore `'_'`. -- `pattern:\W` -- all but `pattern:\w`. -- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline `\n`. +- `padrão:\d` - dígitos. +- `padrão:\D` - sem dígitos. +- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. +- `padrão:\S` - todos, exceto `padrão:\s`. +- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. +- `padrão:\W` - todos, exceto `padrão:\w`. +- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. -...But that's not all! +...Mas isso não é tudo! -Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter), is it a punctuation sign, etc. +A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. -We can search by these properties as well. That requires flag `pattern:u`, covered in the next article. +Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. From f86d836a1d015861b82207febd4db8f02ed6a2b4 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:45:27 +0100 Subject: [PATCH 15/32] Revert "Merge branch 'fsdude-02-regexp-character-classes' into master" This reverts commit df62d2ca2dc707248253bd2dc4046afffc8fdf86, reversing changes made to e9c30cea82bafd76c254b5704c005c00e06b2ee0. --- .../03-regexp-character-classes/article.md | 203 ++++++++++++++++++ .../love-html5-classes.svg | 1 + 2 files changed, 204 insertions(+) create mode 100644 9-regular-expressions/03-regexp-character-classes/article.md create mode 100644 9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg diff --git a/9-regular-expressions/03-regexp-character-classes/article.md b/9-regular-expressions/03-regexp-character-classes/article.md new file mode 100644 index 000000000..1a45309a0 --- /dev/null +++ b/9-regular-expressions/03-regexp-character-classes/article.md @@ -0,0 +1,203 @@ +# Classes de caracteres + +Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. + +Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. + +Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. + +Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". + +Por exemplo, vamos encontrar o primeiro dígito no número de telefone: + +```js run +let str = "+7(903)-123-45-67"; + +let regexp = /\d/; + +alert( str.match(regexp) ); // 7 +``` + +Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. + +Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: + +```js run +let str = "+7(903)-123-45-67"; + +let regexp = /\d/g; + +alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 + +// vamos criar o número de telefone apenas com dígitos: +alert( str.match(regexp).join('') ); // 79031234567 +``` + +Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. + +As mais usadas são: + +`padrão:\d` ("d" é de "digit") +: Um dígito: um caractere de `0` a `9`. + +`padrão:\s` ("s" é de "space") +: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. + +`padrão:\w` ("w" é de "word") +: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. + +Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. + +**Uma regexp pode conter símbolos regulares e classes de caracteres.** + +Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: + +```js run +let str = "Existe CSS4?"; +let regexp = /CSS\d/ + +alert( str.match(regexp) ); // CSS4 +``` + +Também podemos usar muitas classes de caracteres: + +```js run +alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +``` + +A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): + +![](love-html5-classes.svg) + +## Classes inversas + +Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. + +O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: + +`padrão:\D` +: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. + +`padrão:\S` +: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. + +`padrão:\W` +: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. + +No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. + +```js run +let str = "+7(903)-123-45-67"; + +alert( str.match(/\d/g).join('') ); // 79031234567 +``` + +Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: + +```js run +let str = "+7(903)-123-45-67"; + +alert( str.replace(/\D/g, "") ); // 79031234567 +``` + +## Um ponto é "qualquer caractere" + +Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". + +Por exemplo: + +```js run +alert( "Z".match(/./) ); // Z +``` + +Ou no meio de uma regexp: + +```js run +let regexp = /CS.4/; + +alert( "CSS4".match(regexp) ); // CSS4 +alert( "CS-4".match(regexp) ); // CS-4 +alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) +``` + +Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: + +```js run +alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto +``` + +### Ponto como literalmente qualquer caractere com a flag "s" + +Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. + +Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: + +```js run +alert( "A\nB".match(/A.B/) ); // null (sem correspondência) +``` + +Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. + +É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: + +```js run +alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) +``` + +````warn header="Não suportado no Firefox, IE, Edge" +Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. + +Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". + +```js run +alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) +``` + +O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. + +Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. +```` + +````warn header="Preste atenção nos espaços" +Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. + +Mas se uma regexp não leva em consideração os espaços, ela pode falhar. + +Vamos tentar encontrar dígitos separados por um hífen: + +```js run +alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! +``` + +Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: + +```js run +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona +// ou podemos usar a classe \s: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona +``` + +**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** + +Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. + +Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. +```` + +## Resumo + +Existem as seguintes classes de caracteres: + +- `padrão:\d` - dígitos. +- `padrão:\D` - sem dígitos. +- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. +- `padrão:\S` - todos, exceto `padrão:\s`. +- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. +- `padrão:\W` - todos, exceto `padrão:\w`. +- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. + +...Mas isso não é tudo! + +A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. + +Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. \ No newline at end of file diff --git a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg b/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg new file mode 100644 index 000000000..9c88cc088 --- /dev/null +++ b/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg @@ -0,0 +1 @@ + \ No newline at end of file From 72ffd484fb5c4efa60a782ff67c44b47b62c05d3 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:45:53 +0100 Subject: [PATCH 16/32] Revert "Merge branch 'fsdude-02-regexp-character-classes' into master" This reverts commit e9c30cea82bafd76c254b5704c005c00e06b2ee0, reversing changes made to 41188c4f41719a8e9b4b21eeeda5d43071914fe8. --- .../03-regexp-character-classes/article.md | 203 ------------------ .../love-html5-classes.svg | 1 - 2 files changed, 204 deletions(-) delete mode 100644 9-regular-expressions/03-regexp-character-classes/article.md delete mode 100644 9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg diff --git a/9-regular-expressions/03-regexp-character-classes/article.md b/9-regular-expressions/03-regexp-character-classes/article.md deleted file mode 100644 index 1a45309a0..000000000 --- a/9-regular-expressions/03-regexp-character-classes/article.md +++ /dev/null @@ -1,203 +0,0 @@ -# Classes de caracteres - -Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. - -Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. - -Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. - -Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". - -Por exemplo, vamos encontrar o primeiro dígito no número de telefone: - -```js run -let str = "+7(903)-123-45-67"; - -let regexp = /\d/; - -alert( str.match(regexp) ); // 7 -``` - -Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. - -Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: - -```js run -let str = "+7(903)-123-45-67"; - -let regexp = /\d/g; - -alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 - -// vamos criar o número de telefone apenas com dígitos: -alert( str.match(regexp).join('') ); // 79031234567 -``` - -Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. - -As mais usadas são: - -`padrão:\d` ("d" é de "digit") -: Um dígito: um caractere de `0` a `9`. - -`padrão:\s` ("s" é de "space") -: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. - -`padrão:\w` ("w" é de "word") -: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. - -Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. - -**Uma regexp pode conter símbolos regulares e classes de caracteres.** - -Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: - -```js run -let str = "Existe CSS4?"; -let regexp = /CSS\d/ - -alert( str.match(regexp) ); // CSS4 -``` - -Também podemos usar muitas classes de caracteres: - -```js run -alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' -``` - -A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): - -![](love-html5-classes.svg) - -## Classes inversas - -Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. - -O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: - -`padrão:\D` -: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. - -`padrão:\S` -: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. - -`padrão:\W` -: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. - -No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. - -```js run -let str = "+7(903)-123-45-67"; - -alert( str.match(/\d/g).join('') ); // 79031234567 -``` - -Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: - -```js run -let str = "+7(903)-123-45-67"; - -alert( str.replace(/\D/g, "") ); // 79031234567 -``` - -## Um ponto é "qualquer caractere" - -Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". - -Por exemplo: - -```js run -alert( "Z".match(/./) ); // Z -``` - -Ou no meio de uma regexp: - -```js run -let regexp = /CS.4/; - -alert( "CSS4".match(regexp) ); // CSS4 -alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) -``` - -Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: - -```js run -alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto -``` - -### Ponto como literalmente qualquer caractere com a flag "s" - -Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. - -Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: - -```js run -alert( "A\nB".match(/A.B/) ); // null (sem correspondência) -``` - -Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. - -É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: - -```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) -``` - -````warn header="Não suportado no Firefox, IE, Edge" -Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. - -Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". - -```js run -alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) -``` - -O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. - -Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. -```` - -````warn header="Preste atenção nos espaços" -Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. - -Mas se uma regexp não leva em consideração os espaços, ela pode falhar. - -Vamos tentar encontrar dígitos separados por um hífen: - -```js run -alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! -``` - -Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: - -```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona -// ou podemos usar a classe \s: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona -``` - -**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** - -Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. - -Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. -```` - -## Resumo - -Existem as seguintes classes de caracteres: - -- `padrão:\d` - dígitos. -- `padrão:\D` - sem dígitos. -- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. -- `padrão:\S` - todos, exceto `padrão:\s`. -- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. -- `padrão:\W` - todos, exceto `padrão:\w`. -- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. - -...Mas isso não é tudo! - -A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. - -Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. \ No newline at end of file diff --git a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg b/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg deleted file mode 100644 index 9c88cc088..000000000 --- a/9-regular-expressions/03-regexp-character-classes/love-html5-classes.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 24b8013c09e0331e117be674ba92e62e65f4a399 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 01:46:08 +0100 Subject: [PATCH 17/32] Revert "Merge branch 'fsdude-02-regexp-character-classes' into master" This reverts commit 41188c4f41719a8e9b4b21eeeda5d43071914fe8, reversing changes made to 0c959f95af58cd8700054fd32d63fcb669025019. --- .../02-regexp-character-classes/article.md | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/9-regular-expressions/02-regexp-character-classes/article.md b/9-regular-expressions/02-regexp-character-classes/article.md index 94c875955..201c78a05 100644 --- a/9-regular-expressions/02-regexp-character-classes/article.md +++ b/9-regular-expressions/02-regexp-character-classes/article.md @@ -1,14 +1,14 @@ -# Classes de caracteres +# Character classes -Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. +Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79031234567`. -Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. +To do so, we can find and remove anything that's not a number. Character classes can help with that. -Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. +A *character class* is a special notation that matches any symbol from a certain set. -Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". +For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit". -Por exemplo, vamos encontrar o primeiro dígito no número de telefone: +For instance, let's find the first digit in the phone number: ```js run let str = "+7(903)-123-45-67"; @@ -18,73 +18,73 @@ let regexp = /\d/; alert( str.match(regexp) ); // 7 ``` -Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. +Without the flag `pattern:g`, the regular expression only looks for the first match, that is the first digit `pattern:\d`. -Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: +Let's add the `pattern:g` flag to find all digits: ```js run let str = "+7(903)-123-45-67"; let regexp = /\d/g; -alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 +alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 -// vamos criar o número de telefone apenas com dígitos: +// let's make the digits-only phone number of them: alert( str.match(regexp).join('') ); // 79031234567 ``` -Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. +That was a character class for digits. There are other character classes as well. -As mais usadas são: +Most used are: -`padrão:\d` ("d" é de "digit") -: Um dígito: um caractere de `0` a `9`. +`pattern:\d` ("d" is from "digit") +: A digit: a character from `0` to `9`. -`padrão:\s` ("s" é de "space") -: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. +`pattern:\s` ("s" is from "space") +: A space symbol: includes spaces, tabs `\t`, newlines `\n` and few other rare characters, such as `\v`, `\f` and `\r`. -`padrão:\w` ("w" é de "word") -: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. +`pattern:\w` ("w" is from "word") +: A "wordly" character: either a letter of Latin alphabet or a digit or an underscore `_`. Non-Latin letters (like cyrillic or hindi) do not belong to `pattern:\w`. -Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. +For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", such as `match:1 a`. -**Uma regexp pode conter símbolos regulares e classes de caracteres.** +**A regexp may contain both regular symbols and character classes.** -Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: +For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: ```js run -let str = "Existe CSS4?"; +let str = "Is there CSS4?"; let regexp = /CSS\d/ alert( str.match(regexp) ); // CSS4 ``` -Também podemos usar muitas classes de caracteres: +Also we can use many character classes: ```js run -alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' +alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' ``` -A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): +The match (each regexp character class has the corresponding result character): ![](love-html5-classes.svg) -## Classes inversas +## Inverse classes -Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. +For every character class there exists an "inverse class", denoted with the same letter, but uppercased. -O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: +The "inverse" means that it matches all other characters, for instance: -`padrão:\D` -: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. +`pattern:\D` +: Non-digit: any character except `pattern:\d`, for instance a letter. -`padrão:\S` -: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. +`pattern:\S` +: Non-space: any character except `pattern:\s`, for instance a letter. -`padrão:\W` -: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. +`pattern:\W` +: Non-wordly character: anything but `pattern:\w`, e.g a non-latin letter or a space. -No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. +In the beginning of the chapter we saw how to make a number-only phone number from a string like `subject:+7(903)-123-45-67`: find all digits and join them. ```js run let str = "+7(903)-123-45-67"; @@ -92,7 +92,7 @@ let str = "+7(903)-123-45-67"; alert( str.match(/\d/g).join('') ); // 79031234567 ``` -Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: +An alternative, shorter way is to find non-digits `pattern:\D` and remove them from the string: ```js run let str = "+7(903)-123-45-67"; @@ -100,104 +100,104 @@ let str = "+7(903)-123-45-67"; alert( str.replace(/\D/g, "") ); // 79031234567 ``` -## Um ponto é "qualquer caractere" +## A dot is "any character" -Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". +A dot `pattern:.` is a special character class that matches "any character except a newline". -Por exemplo: +For instance: ```js run alert( "Z".match(/./) ); // Z ``` -Ou no meio de uma regexp: +Or in the middle of a regexp: ```js run let regexp = /CS.4/; alert( "CSS4".match(regexp) ); // CSS4 alert( "CS-4".match(regexp) ); // CS-4 -alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) +alert( "CS 4".match(regexp) ); // CS 4 (space is also a character) ``` -Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: +Please note that a dot means "any character", but not the "absence of a character". There must be a character to match it: ```js run -alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto +alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot ``` -### Ponto como literalmente qualquer caractere com a flag "s" +### Dot as literally any character with "s" flag -Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. +By default, a dot doesn't match the newline character `\n`. -Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: +For instance, the regexp `pattern:A.B` matches `match:A`, and then `match:B` with any character between them, except a newline `\n`: ```js run -alert( "A\nB".match(/A.B/) ); // null (sem correspondência) +alert( "A\nB".match(/A.B/) ); // null (no match) ``` -Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. +There are many situations when we'd like a dot to mean literally "any character", newline included. -É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: +That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` matches literally any character: ```js run -alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) +alert( "A\nB".match(/A.B/s) ); // A\nB (match!) ``` -````warn header="Não suportado no Firefox, IE, Edge" -Verifique para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. +````warn header="Not supported in IE" +The `pattern:s` flag is not supported in IE. -Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". +Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character" (this pattern will be covered in the article ). ```js run alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) ``` -O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. +The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter. Or even the `pattern:[^]` -- as it means match any character except nothing. -Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. +Also we can use this trick if we want both kind of "dots" in the same pattern: the actual dot `pattern:.` behaving the regular way ("not including a newline"), and also a way to match "any character" with `pattern:[\s\S]` or alike. ```` -````warn header="Preste atenção nos espaços" -Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. +````warn header="Pay attention to spaces" +Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. -Mas se uma regexp não leva em consideração os espaços, ela pode falhar. +But if a regexp doesn't take spaces into account, it may fail to work. -Vamos tentar encontrar dígitos separados por um hífen: +Let's try to find digits separated by a hyphen: ```js run -alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! +alert( "1 - 5".match(/\d-\d/) ); // null, no match! ``` -Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: +Let's fix it adding spaces into the regexp `pattern:\d - \d`: ```js run -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona -// ou podemos usar a classe \s: -alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works +// or we can use \s class: +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works ``` -**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** +**A space is a character. Equal in importance with any other character.** -Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. +We can't add or remove spaces from a regular expression and expect it to work the same. -Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. +In other words, in a regular expression all characters matter, spaces too. ```` -## Resumo +## Summary -Existem as seguintes classes de caracteres: +There exist following character classes: -- `padrão:\d` - dígitos. -- `padrão:\D` - sem dígitos. -- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. -- `padrão:\S` - todos, exceto `padrão:\s`. -- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. -- `padrão:\W` - todos, exceto `padrão:\w`. -- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. +- `pattern:\d` -- digits. +- `pattern:\D` -- non-digits. +- `pattern:\s` -- space symbols, tabs, newlines. +- `pattern:\S` -- all but `pattern:\s`. +- `pattern:\w` -- Latin letters, digits, underscore `'_'`. +- `pattern:\W` -- all but `pattern:\w`. +- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline `\n`. -...Mas isso não é tudo! +...But that's not all! -A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. +Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter), is it a punctuation sign, etc. -Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. +We can search by these properties as well. That requires flag `pattern:u`, covered in the next article. From 43eec8ea50de8270b2c9ba34593a4fb8f9e0b33f Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 02:50:15 +0100 Subject: [PATCH 18/32] Replace 'en' version by translation. --- .../17-regexp-methods/article.md | 265 ++++++++---------- 1 file changed, 124 insertions(+), 141 deletions(-) diff --git a/9-regular-expressions/17-regexp-methods/article.md b/9-regular-expressions/17-regexp-methods/article.md index 0d5168b40..12385b1ff 100644 --- a/9-regular-expressions/17-regexp-methods/article.md +++ b/9-regular-expressions/17-regexp-methods/article.md @@ -1,32 +1,32 @@ -# Methods of RegExp and String +# Métodos de RegExp e String -In this article we'll cover various methods that work with regexps in-depth. +Neste artigo, abordaremos vários métodos que funcionam com regexps em profundidade. ## str.match(regexp) -The method `str.match(regexp)` finds matches for `regexp` in the string `str`. +O método `str.macth(regexp)` pesquisa correspondências para `regexp` na string `str`. -It has 3 modes: +Possui 3 modos: -1. If the `regexp` doesn't have flag `pattern:g`, then it returns the first match as an array with capturing groups and properties `index` (position of the match), `input` (input string, equals `str`): +1. Se a `regexp` não tiver a flag `padrão:g`, ela retornará a primeira correspondências como uma matriz com a captura de grupos e propriedades `index` (posição da correspondência), `input` (string de entrada, igual a `str`): ```js run - let str = "I love JavaScript"; + let str = "Eu amo JavaScript"; let result = str.match(/Java(Script)/); - alert( result[0] ); // JavaScript (full match) - alert( result[1] ); // Script (first capturing group) + alert( result[0] ); // JavaScript (correspondência completa) + alert( result[1] ); // Script (primeira captura de grupo) alert( result.length ); // 2 - // Additional information: - alert( result.index ); // 7 (match position) - alert( result.input ); // I love JavaScript (source string) + // Informação adicional: + alert( result.index ); // 0 (posição da correspondÊncia) + alert( result.input ); // Eu amo JavaScript (string original) ``` -2. If the `regexp` has flag `pattern:g`, then it returns an array of all matches as strings, without capturing groups and other details. +2. Se a `regexp` tiver a flag `padrão:g`, ela retornará uma matriz de todas as correspondências como strings, sem capturar grupos e outros detalhes. ```js run - let str = "I love JavaScript"; + let str = "Eu amo JavaScript"; let result = str.match(/Java(Script)/g); @@ -34,12 +34,12 @@ It has 3 modes: alert( result.length ); // 1 ``` -3. If there are no matches, no matter if there's flag `pattern:g` or not, `null` is returned. +3. Se não houver correspondências, não importa se há flag `padrão:g` ou não, `null` é retornado. - That's an important nuance. If there are no matches, we don't get an empty array, but `null`. It's easy to make a mistake forgetting about it, e.g.: + Essa é uma nuance importante. Se não há correspondências, não teremos uma matriz vazia, mas `null`. É fácil de cometer um erro esquecendo disso, por exemplo: ```js run - let str = "I love JavaScript"; + let str = "Eu amo JavaScript"; let result = str.match(/HTML/); @@ -47,7 +47,7 @@ It has 3 modes: alert(result.length); // Error: Cannot read property 'length' of null ``` - If we want the result to be an array, we can write like this: + Se desejamos que o resultado seja uma matriz, podemos escrever assim: ```js let result = str.match(regexp) || []; @@ -55,144 +55,144 @@ It has 3 modes: ## str.matchAll(regexp) -[recent browser="new"] +[navegador recente="new"] -The method `str.matchAll(regexp)` is a "newer, improved" variant of `str.match`. +O método `str.matchAll(regexp)` é uma "nova, melhorada" variante do `str.match`. -It's used mainly to search for all matches with all groups. +É usada principalmente para buscar todas as correspondências com todos os grupos. -There are 3 differences from `match`: +Existem 3 diferenças em relação ao `match`: -1. It returns an iterable object with matches instead of an array. We can make a regular array from it using `Array.from`. -2. Every match is returned as an array with capturing groups (the same format as `str.match` without flag `pattern:g`). -3. If there are no results, it returns not `null`, but an empty iterable object. +1. Ela retorna um objeto iterável com correspondências em vez de uma matriz. Podemos fazer uma matriz regular usando `Array.from`. +2. Cada correspondência é retornada como uma matriz com grupos de captura (o mesmo formate que `str.match` sem a flag `padrão:g`). +3. Se não houver resultados, não retornará `null`, mas um objeto iterável vazio. -Usage example: +Exemplo de uso: ```js run -let str = '

Hello, world!

'; +let str = '

Olá, mundo!

'; let regexp = /<(.*?)>/g; let matchAll = str.matchAll(regexp); -alert(matchAll); // [object RegExp String Iterator], not array, but an iterable +alert(matchAll); // [object RegExp String Iterator], não é matriz, mas é iterável -matchAll = Array.from(matchAll); // array now +matchAll = Array.from(matchAll); // matriz agora let firstMatch = matchAll[0]; alert( firstMatch[0] ); //

alert( firstMatch[1] ); // h1 alert( firstMatch.index ); // 0 -alert( firstMatch.input ); //

Hello, world!

+alert( firstMatch.input ); //

Olá, mundo!

``` -If we use `for..of` to loop over `matchAll` matches, then we don't need `Array.from` any more. +Se usarmos `for..of` para repetir as correspondências do `matchAll`, então não precisaremos mais do `Array.from`. ## str.split(regexp|substr, limit) -Splits the string using the regexp (or a substring) as a delimiter. +Divide a string usando regexp (ou uma substring) como um delimitador. -We can use `split` with strings, like this: +Podemos usar `split` com strings, desse jeito: ```js run -alert('12-34-56'.split('-')) // array of [12, 34, 56] +alert('12-34-56'.split('-')) // matriz de [12, 34, 56] ``` -But we can split by a regular expression, the same way: +Mas podemos dividir por uma expressão regular, do mesmo modo: ```js run -alert('12, 34, 56'.split(/,\s*/)) // array of [12, 34, 56] +alert('12, 34, 56'.split(/,\s*/)) // matriz de [12, 34, 56] ``` ## str.search(regexp) -The method `str.search(regexp)` returns the position of the first match or `-1` if none found: +O método `str.search(regexp)` retorna a posição da primeira correspondência ou `-1` se nada for encontrado: ```js run -let str = "A drop of ink may make a million think"; +let str = "Uma gota de tinta pode fazer um milhão pensar"; -alert( str.search( /ink/i ) ); // 10 (first match position) +alert( str.search( /tinta/i ) ); // 12 (posição da primeira correspondência) ``` -**The important limitation: `search` only finds the first match.** +**A importante limitação: `search` apenas encontra a primeira correspondência.** -If we need positions of further matches, we should use other means, such as finding them all with `str.matchAll(regexp)`. +Se precisarmos de posições de correspondências mais distantes, devemos usar outros meios, como encontrar todos eles com `str.matchAll(regexp)`. ## str.replace(str|regexp, str|func) -This is a generic method for searching and replacing, one of most useful ones. The swiss army knife for searching and replacing. +Esse é um método genério para buscar e substituir, um dos mais úteis. O canivete suíço para procurar e substituir. -We can use it without regexps, to search and replace a substring: +Podemos usá-lo sem regexps, para buscar e substituir uma substring: ```js run -// replace a dash by a colon +// substitui um hífen por dois-pontos alert('12-34-56'.replace("-", ":")) // 12:34-56 ``` -There's a pitfall though. +No entanto há uma armadilha. -**When the first argument of `replace` is a string, it only replaces the first match.** +**Quando o primeiro argumento do `replace` é uma string, ele apenas substitui a primeira correspondência** -You can see that in the example above: only the first `"-"` is replaced by `":"`. +Você pode ver isso no exemplo acima: apenas o primeiro `"-"` é substituído por `":"`. -To find all hyphens, we need to use not the string `"-"`, but a regexp `pattern:/-/g`, with the obligatory `pattern:g` flag: +Para encontrar todos os hífens, não precisamos usar a string `"-"`, mas a regexp `padrão:/-/g`, com a flag obrigatória `padrão:g`: ```js run -// replace all dashes by a colon -alert( '12-34-56'.replace( *!*/-/g*/!*, ":" ) ) // 12:34:56 +// substitui todos os hífens por um dois-pontos +alert( '12-34-56'.replace( /-/g, ":" ) ) // 12:34:56 ``` -The second argument is a replacement string. We can use special characters in it: +O segundo argumento é uma string substituta. Podemos usar caracteres especiais: -| Symbols | Action in the replacement string | +| Símbolos | Ação na string substituta | |--------|--------| -|`$&`|inserts the whole match| -|$`|inserts a part of the string before the match| -|`$'`|inserts a part of the string after the match| -|`$n`|if `n` is a 1-2 digit number, inserts the contents of n-th capturing group, for details see [](info:regexp-groups)| -|`$`|inserts the contents of the parentheses with the given `name`, for details see [](info:regexp-groups)| -|`$$`|inserts character `$` | +|`$&`|insere a correspondência toda| +|$`|insere uma parte da string antes da correspondência| +|`$'`|insere uma parte da string depois da correspondência| +|`$n`|se `n` for um número de 1-2 dígitos, insere o conteúdo do n-ésimo grupo de captura, para detalhes, consulte [](info:regexp-groups)| +|`$`|insere o conteúdo dos parênteses com `name` fornecido, para detalhes, consulte [](info:regexp-groups)| +|`$$`|insere o caractere `$` | -For instance: +Por exemplo: ```js run let str = "John Smith"; -// swap first and last name +// troca nome e sobrenome alert(str.replace(/(john) (smith)/i, '$2, $1')) // Smith, John ``` -**For situations that require "smart" replacements, the second argument can be a function.** +**Para situações que exigem "inteligentes" substituições, o segundo argumento pode ser uma função** -It will be called for each match, and the returned value will be inserted as a replacement. +Isso será chamado para cada correspondência e o valor retornado será inserido como uma substituição. -The function is called with arguments `func(match, p1, p2, ..., pn, offset, input, groups)`: +A função é chamada com argumentos `func(match, p1, p2, ..., pn, offset, input, groups)`: -1. `match` -- the match, -2. `p1, p2, ..., pn` -- contents of capturing groups (if there are any), -3. `offset` -- position of the match, -4. `input` -- the source string, -5. `groups` -- an object with named groups. +1. `match` -- a correspondência, +2. `p1, p2, ..., pn` -- conteúdo dos grupos de captura (se existir algum), +3. `offset` -- posição da correspondência, +4. `input` -- a string original, +5. `groups` -- um objeto com grupos nomeados. -If there are no parentheses in the regexp, then there are only 3 arguments: `func(str, offset, input)`. +Se não existem parênteses na regexp, terá apenas 3 argumentos: `func(str, offset, input)`. -For example, let's uppercase all matches: +Por exemplo, vamos colocar todas as correspondências em maiúsculas: ```js run -let str = "html and css"; +let str = "html e css"; let result = str.replace(/html|css/gi, str => str.toUpperCase()); -alert(result); // HTML and CSS +alert(result); // HTML e CSS ``` -Replace each match by its position in the string: +Substituir cada correspondência pela sua posição na string: ```js run alert("Ho-Ho-ho".replace(/ho/gi, (match, offset) => offset)); // 0-3-6 ``` -In the example below there are two parentheses, so the replacement function is called with 5 arguments: the first is the full match, then 2 parentheses, and after it (not used in the example) the match position and the source string: +No exemplo abaixo, existem dois parênteses, então a função de substituição é chamada com 5 argumentos: o primeiro é a correspondência completa, em seguida, 2 parênteses, e depois dele (não usado no exemplo) a posição da correspondência e a string original: ```js run let str = "John Smith"; @@ -202,7 +202,7 @@ let result = str.replace(/(\w+) (\w+)/, (match, name, surname) => `${surname}, $ alert(result); // Smith, John ``` -If there are many groups, it's convenient to use rest parameters to access them: +Se existirem muitos grupos, é conveniente usar os parâmetros de descanso para acessá-los: ```js run let str = "John Smith"; @@ -212,7 +212,7 @@ let result = str.replace(/(\w+) (\w+)/, (...match) => `${match[2]}, ${match[1]}` alert(result); // Smith, John ``` -Or, if we're using named groups, then `groups` object with them is always the last, so we can obtain it like this: +Ou, se usarmos grupos nomeados, o objeto `groups` com eles é sempre o último, para que possamos obtê-los assim: ```js run let str = "John Smith"; @@ -226,136 +226,119 @@ let result = str.replace(/(?\w+) (?\w+)/, (...match) => { alert(result); // Smith, John ``` -Using a function gives us the ultimate replacement power, because it gets all the information about the match, has access to outer variables and can do everything. - -## str.replaceAll(str|regexp, str|func) - -This method is essentially the same as `str.replace`, with two major differences: - -1. If the first argument is a string, it replaces *all occurences* of the string, while `replace` replaces only the *first occurence*. -2. If the first argument is a regular expression without the `g` flag, there'll be an error. With `g` flag, it works the same as `replace`. - -The main use case for `replaceAll` is replacing all occurences of a string. - -Like this: - -```js run -// replace all dashes by a colon -alert('12-34-56'.replaceAll("-", ":")) // 12:34:56 -``` - +O uso de uma função nos dá o poder de substituição definitivo, porque obtém todas as informações sobre a correspondência, tem a variáveis externas e pode fazer tudo. ## regexp.exec(str) -The method `regexp.exec(str)` method returns a match for `regexp` in the string `str`. Unlike previous methods, it's called on a regexp, not on a string. +O método `regexp.exec(str)` retorna uma correspondência para `regexp` na string `str`. Diferentes dos métodos anteriores, é chamado numa regexp, não em uma string. -It behaves differently depending on whether the regexp has flag `pattern:g`. +Se comporta de modo diferente dependendo se a regexp possui a flag `padrão:g`. -If there's no `pattern:g`, then `regexp.exec(str)` returns the first match exactly as `str.match(regexp)`. This behavior doesn't bring anything new. +Se não houver `padrão:g`, a `regexp.exec(str)` retorna a primeira correspondência exatamente como `str.match(regexp)`. Esse comportamento não traz nada de novo. -But if there's flag `pattern:g`, then: -- A call to `regexp.exec(str)` returns the first match and saves the position immediately after it in the property `regexp.lastIndex`. -- The next such call starts the search from position `regexp.lastIndex`, returns the next match and saves the position after it in `regexp.lastIndex`. -- ...And so on. -- If there are no matches, `regexp.exec` returns `null` and resets `regexp.lastIndex` to `0`. +Mas se houver a flag `padrão:g`, então: +- A chamada para `regexp.exec(str)` retorna a primeira correspondência e salva a posição imediatamente após ela na propriedade `regexp.lastIndex`. +- A próxima chamada inicia a pesquisa na posição `regexp.lastIndex`, retorna a próxima correspondência e salva a posição após elas em `regexp.lastIndex`. +- ...e assim por diante. +- Se não houver correspondências, `regexp.exec` retorna `null` e reinicia `regexp.lastIndex` para `0`. -So, repeated calls return all matches one after another, using property `regexp.lastIndex` to keep track of the current search position. +Portanto, repetidas chamadas retornam todas as correspondências uma após outra, usando a propriedade `regexp.lastIndex` para manter o controle da atual posição de busca. -In the past, before the method `str.matchAll` was added to JavaScript, calls of `regexp.exec` were used in the loop to get all matches with groups: +No passado, antes do método `str.matchAll` ser adicionado ao JavaScript, as chamadas de `regexp.exec` eram usadas em repetição para obter todas as correspondências com grupos: ```js run -let str = 'More about JavaScript at https://javascript.info'; +let str = 'Mais sobre JavaScript em https://javascript.info'; let regexp = /javascript/ig; let result; while (result = regexp.exec(str)) { - alert( `Found ${result[0]} at position ${result.index}` ); - // Found JavaScript at position 11, then - // Found javascript at position 33 + alert( `Encontrado ${result[0]} na posição ${result.index}` ); + // Encontrado JavaScript na posição 11, depois + // Encontrado javascript na posição 33 } ``` -This works now as well, although for newer browsers `str.matchAll` is usually more convenient. +Isso funciona bem agora, no entanto para navegadores novos `str.matchAll` é usualmente mais conveniente. -**We can use `regexp.exec` to search from a given position by manually setting `lastIndex`.** +**Podemos usar `regexp.exec` para buscar de uma posição dada, configurando manualmente `lastIndex`.** -For instance: +Por exemplo: ```js run -let str = 'Hello, world!'; +let str = 'Olá, mundo!'; -let regexp = /\w+/g; // without flag "g", lastIndex property is ignored -regexp.lastIndex = 5; // search from 5th position (from the comma) +let regexp = /\w+/g; // sem a flag "g", propriedade lastIndex é ignorada +regexp.lastIndex = 3; // pesquisa a partir da 5º posição (a partir da vírgula) -alert( regexp.exec(str) ); // world +alert( regexp.exec(str) ); // mundo ``` -If the regexp has flag `pattern:y`, then the search will be performed exactly at the position `regexp.lastIndex`, not any further. +Se o regexp tiver flag `padrão:y`, então a pesquisa será realizada exatamente na posição `regexp.lastIndex`, nada mais. -Let's replace flag `pattern:g` with `pattern:y` in the example above. There will be no matches, as there's no word at position `5`: +Vamos substituir a flag `padrão:g` pela `padrão:y` no exemplo acima. Não haverá correspondências, como não haverá palavra na posição `3`: ```js run -let str = 'Hello, world!'; +let str = 'Olá, mundo!'; let regexp = /\w+/y; -regexp.lastIndex = 5; // search exactly at position 5 +regexp.lastIndex = 3; // pesquisa exatamente na posição 5 alert( regexp.exec(str) ); // null ``` -That's convenient for situations when we need to "read" something from the string by a regexp at the exact position, not somewhere further. +Isso é conveniente para situações em que precisamos "ler" algo da string por uma regexp nessa posição exata, não em outro lugar. ## regexp.test(str) -The method `regexp.test(str)` looks for a match and returns `true/false` whether it exists. +O método `regex.test(str)` procura por uma correspondência e retorna `true/false` se existe. -For instance: +Por exemplo: ```js run -let str = "I love JavaScript"; +let str = "Eu amo JavaScript"; -// these two tests do the same -alert( *!*/love/i*/!*.test(str) ); // true -alert( str.search(*!*/love/i*/!*) != -1 ); // true +// esses dois testes fazem o mesmo +alert( /amo/i.test(str) ); // true +alert( str.search(/amo/i) != -1 ); // true ``` -An example with the negative answer: +Um exemplo com a resposta negativa: ```js run let str = "Bla-bla-bla"; -alert( *!*/love/i*/!*.test(str) ); // false -alert( str.search(*!*/love/i*/!*) != -1 ); // false +alert( /amo/i.test(str) ); // false +alert( str.search(/love/i) != -1 ); // false ``` -If the regexp has flag `pattern:g`, then `regexp.test` looks from `regexp.lastIndex` property and updates this property, just like `regexp.exec`. +Se a regexp tiver a flag `padrão:g`, o `regexp.test` procura na propriedade `regexp.lastIndex` e atualiza-a, assim como `regexp.exec` -So we can use it to search from a given position: +Então podemos usar isso para buscar a partir de uma posição fornecida: ```js run -let regexp = /love/gi; +let regexp = /amo/gi; -let str = "I love JavaScript"; +let str = "Eu amo JavaScript"; -// start the search from position 10: +// inicia a pesquisa da posição 10: regexp.lastIndex = 10; -alert( regexp.test(str) ); // false (no match) +alert( regexp.test(str) ); // false (sem correspondência) ``` -````warn header="Same global regexp tested repeatedly on different sources may fail" -If we apply the same global regexp to different inputs, it may lead to wrong result, because `regexp.test` call advances `regexp.lastIndex` property, so the search in another string may start from non-zero position. +````warn header="A mesma regexp global testada repetidamente em diferentes fontes pode falhar" +Se aplicarmos a mesma regexp global em diferentes entradas, isso poderá levar a resultados incorreto, porque a chamada `regexp.test` avança a propriedade `regexp.lastIndex`, portanto a pesquisa em outra string pode ter um início numa posição diferente de zero. -For instance, here we call `regexp.test` twice on the same text, and the second time fails: +Por exemplo, aqui chamamos `regexp.test` duas vezes no mesmo texto e a segunda vez falha: ```js run -let regexp = /javascript/g; // (regexp just created: regexp.lastIndex=0) +let regexp = /javascript/g; // (regexp recém criada: regexp.lastIndex=0) -alert( regexp.test("javascript") ); // true (regexp.lastIndex=10 now) +alert( regexp.test("javascript") ); // true (regexp.lastIndex=10 agora) alert( regexp.test("javascript") ); // false ``` -That's exactly because `regexp.lastIndex` is non-zero in the second test. +Isso é exatamente porque `regexp.lastIndex` é diferente de zero no segundo teste. -To work around that, we can set `regexp.lastIndex = 0` before each search. Or instead of calling methods on regexp, use string methods `str.match/search/...`, they don't use `lastIndex`. +Para contornar isso, podemos definir `regexp.lastIndex = 0` antes de cada busca. Ou, em vez de chamar métodos no regexp, usar métodos de string `str.match/search/...`, eles não usam `lastIndex`. ```` From a5063b3bd7fbf2d18c0390b5d128835ad1217b0b Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 25 Dec 2020 03:24:52 +0100 Subject: [PATCH 19/32] Remove unrelated files. --- 1-js/01-getting-started/1-intro/article.md | 17 +- .../2-manuals-specifications/article.md | 5 +- .../3-code-editors/article.md | 23 +- 1-js/01-getting-started/4-devtools/article.md | 20 +- .../01-hello-world/1-hello-alert/index.html | 12 + .../01-hello-world/1-hello-alert/solution.md | 2 + .../01-hello-world/1-hello-alert/task.md | 2 +- 1-js/02-first-steps/01-hello-world/article.md | 12 +- 1-js/02-first-steps/02-structure/article.md | 9 +- 1-js/02-first-steps/03-strict-mode/article.md | 54 +- .../2-declare-variables/solution.md | 10 +- 1-js/02-first-steps/04-variables/article.md | 69 +- 1-js/02-first-steps/05-types/article.md | 92 +- .../06-alert-prompt-confirm/article.md | 4 +- .../07-type-conversions/article.md | 130 +- .../solution.md | 26 + .../3-primitive-conversions-questions/task.md | 27 + .../08-operators/4-fix-prompt/solution.md | 32 + .../08-operators/4-fix-prompt/task.md | 18 + 1-js/02-first-steps/08-operators/article.md | 235 +- .../1-comparison-questions/solution.md | 24 +- .../1-comparison-questions/task.md | 1 + 1-js/02-first-steps/09-comparison/article.md | 179 +- .../2-check-standard/ifelse_task2.svg | 49 +- 1-js/02-first-steps/10-ifelse/article.md | 18 +- .../2-alert-or/solution.md | 2 +- .../6-check-if-in-range/task.md | 2 +- .../7-check-if-out-range/task.md | 2 +- .../9-check-login/ifelse_task.svg | 102 +- .../9-check-login/solution.md | 6 +- .../11-logical-operators/article.md | 64 +- .../12-nullish-coalescing-operator/article.md | 115 +- .../6-repeat-until-correct/solution.md | 2 +- .../13-while-for/7-list-primes/solution.md | 2 +- 1-js/02-first-steps/13-while-for/article.md | 29 +- 1-js/02-first-steps/14-switch/article.md | 115 +- .../1-if-else-required/solution.md | 2 +- .../1-if-else-required/task.md | 14 +- .../solution.md | 10 +- .../2-rewrite-function-question-or/task.md | 16 +- .../15-function-basics/4-pow/task.md | 8 +- .../15-function-basics/article.md | 67 +- .../16-function-expressions/article.md | 365 +- .../17-arrow-functions-basics/article.md | 70 +- .../18-javascript-specials/article.md | 33 +- .../01-debugging-chrome/article.md | 189 +- .../chrome-open-sources.svg | 16 +- .../chrome-sources-breakpoint.svg | 21 +- .../chrome-sources-console.svg | 15 +- .../chrome-sources-debugger-pause.svg | 68 +- .../chrome-sources-debugger-trace-1.svg | 16 +- .../01-debugging-chrome/chrome-tabs.svg | 56 +- .../debugging.view/hello.js | 2 +- .../debugging.view/index.html | 2 +- .../01-debugging-chrome/head.html | 6 +- .../01-debugging-chrome/largeIcons.svg | 1472 ++ .../toolbarButtonGlyphs.svg | 1035 - .../1-style-errors/solution.md | 33 +- .../02-coding-style/1-style-errors/task.md | 10 +- .../02-coding-style/article.md | 245 +- .../02-coding-style/code-style.svg | 83 +- .../02-coding-style/figure-bracket-style.png | Bin 76932 -> 0 bytes .../figure-bracket-style@2x.png | Bin 155668 -> 0 bytes 1-js/03-code-quality/03-comments/article.md | 138 +- 1-js/03-code-quality/04-ninja-code/article.md | 8 +- .../3-pow-test-wrong/solution.md | 34 +- .../05-testing-mocha/3-pow-test-wrong/task.md | 10 +- .../05-testing-mocha/article.md | 321 +- .../beforeafter.view/index.html | 16 +- .../05-testing-mocha/beforeafter.view/test.js | 19 +- .../05-testing-mocha/index.html | 23 +- .../05-testing-mocha/pow-1.view/index.html | 18 +- .../05-testing-mocha/pow-1.view/test.js | 2 +- .../05-testing-mocha/pow-2.view/index.html | 18 +- .../05-testing-mocha/pow-2.view/test.js | 6 +- .../05-testing-mocha/pow-3.view/index.html | 16 +- .../05-testing-mocha/pow-3.view/test.js | 2 +- .../05-testing-mocha/pow-4.view/index.html | 16 +- .../05-testing-mocha/pow-4.view/test.js | 6 +- .../05-testing-mocha/pow-full.view/index.html | 16 +- .../05-testing-mocha/pow-full.view/test.js | 8 +- .../05-testing-mocha/pow-min.view/index.html | 18 +- .../05-testing-mocha/pow-min.view/test.js | 2 +- .../05-testing-mocha/pow-nan.view/index.html | 16 +- .../05-testing-mocha/pow-nan.view/test.js | 8 +- 1-js/03-code-quality/06-polyfills/article.md | 89 +- .../01-object/2-hello-object/task.md | 17 +- .../01-object/3-is-empty/_js.view/solution.js | 2 +- .../01-object/3-is-empty/_js.view/test.js | 6 +- .../01-object/3-is-empty/solution.md | 2 +- .../01-object/3-is-empty/task.md | 15 +- .../01-object/4-const-object/solution.md | 19 - .../01-object/4-const-object/task.md | 18 - .../01-object/5-sum-object/solution.md | 1 - .../01-object/5-sum-object/task.md | 10 +- .../8-multiply-numeric/_js.view/source.js | 7 +- .../8-multiply-numeric/_js.view/test.js | 8 +- .../01-object/8-multiply-numeric/task.md | 20 +- 1-js/04-object-basics/01-object/article.md | 652 +- .../01-object/object-user-delete.svg | 37 +- .../01-object/object-user-empty.svg | 22 +- .../01-object/object-user-isadmin.svg | 46 +- .../01-object/object-user-props.svg | 46 +- .../01-object/object-user.svg | 37 +- 1-js/04-object-basics/01-object/object.svg | 42 +- .../01-object/variable-contains-reference.svg | 36 - .../01-object/variable-copy-reference.svg | 56 - .../01-object/variable-copy-value.svg | 40 - .../02-object-copy/article.md | 80 +- .../03-garbage-collection/article.md | 10 +- .../family-delete-refs.svg | 57 +- .../family-no-family.svg | 58 +- .../family-no-father-2.svg | 34 +- .../family-no-father.svg | 51 +- .../03-garbage-collection/family.svg | 53 +- .../garbage-collection-1.svg | 163 +- .../garbage-collection-2.svg | 179 +- .../garbage-collection-3.svg | 191 +- .../garbage-collection-4.svg | 195 +- .../garbage-collection-5.svg | 213 +- .../memory-user-john-admin.svg | 30 +- .../memory-user-john-lost.svg | 31 +- .../memory-user-john.svg | 26 +- .../2-check-syntax/solution.md | 43 - .../04-object-methods/2-check-syntax/task.md | 19 - .../04-object-methods/3-why-this/solution.md | 22 - .../04-object-methods/3-why-this/task.md | 26 - .../4-object-property-this/solution.md | 15 +- .../4-object-property-this/task.md | 2 +- .../04-object-methods/article.md | 137 +- .../06-constructor-new/article.md | 15 +- .../07-optional-chaining/article.md | 128 +- 1-js/04-object-basics/08-symbol/article.md | 36 +- .../09-object-toprimitive/article.md | 99 +- .../01-primitives-methods/article.md | 4 +- 1-js/05-data-types/02-number/article.md | 33 +- .../03-string/3-truncate/solution.md | 2 +- 1-js/05-data-types/03-string/article.md | 139 +- .../04-array/10-maximal-subarray/solution.md | 2 +- .../04-array/10-maximal-subarray/task.md | 14 +- .../04-array/3-call-array-this/solution.md | 2 +- 1-js/05-data-types/04-array/article.md | 100 +- .../12-reduce-object/_js.view/solution.js | 6 + .../12-reduce-object/_js.view/test.js | 21 + .../12-reduce-object}/solution.md | 0 .../05-array-methods/12-reduce-object/task.md | 37 + .../05-array-methods/2-filter-range/task.md | 2 +- .../05-array-methods/4-sort-back/task.md | 4 +- .../_js.view/solution.js | 12 +- .../6-calculator-extendable/solution.md | 2 +- .../6-calculator-extendable/task.md | 2 +- .../7-map-objects/solution.md | 2 +- .../8-sort-objects/solution.md | 2 +- .../05-data-types/05-array-methods/article.md | 211 +- .../05-data-types/05-array-methods/reduce.svg | 65 +- 1-js/05-data-types/06-iterable/article.md | 36 +- .../07-map-set/03-iterable-keys/task.md | 2 +- 1-js/05-data-types/07-map-set/article.md | 26 +- .../08-weakmap-weakset/article.md | 29 +- .../09-keys-values-entries/article.md | 40 +- .../10-destructuring-assignment/article.md | 30 +- .../destructuring-complex.svg | 60 +- .../11-date/1-new-date/solution.md | 14 +- .../11-date/6-get-seconds-today/solution.md | 2 + .../11-date/6-get-seconds-today/task.md | 4 +- .../8-format-date-relative/solution.md | 4 +- .../11-date/8-format-date-relative/task.md | 2 +- 1-js/05-data-types/11-date/article.md | 60 +- 1-js/05-data-types/12-json/article.md | 21 +- 1-js/05-data-types/12-json/json-meetup.svg | 36 +- .../01-recursion/02-factorial/solution.md | 2 +- .../fibonacci-recursion-tree.svg | 73 +- .../01-recursion/article.md | 23 +- .../01-recursion/linked-list-0.svg | 72 +- .../01-recursion/linked-list-remove-1.svg | 72 +- .../01-recursion/linked-list-split.svg | 67 +- .../01-recursion/linked-list.svg | 61 +- .../01-recursion/recursion-pow.svg | 51 +- .../01-recursion/recursive-salaries.svg | 91 +- .../02-rest-parameters-spread/article.md | 2 +- .../1-closure-latest-changes/solution.md | 5 + .../1-closure-latest-changes/task.md | 23 + .../_js.view/solution.js | 0 .../_js.view/source.js | 0 .../_js.view/test.js | 0 .../10-make-army/lexenv-makearmy-empty.svg | 1 + .../lexenv-makearmy-for-fixed.svg | 1 + .../lexenv-makearmy-while-fixed.svg | 1 + .../03-closure/10-make-army/solution.md | 129 + .../03-closure/10-make-army/task.md | 41 + .../lexenv-nested-work.svg | 1 + .../2-closure-variable-access/solution.md | 9 + .../2-closure-variable-access/task.md | 29 + .../solution.md | 0 .../task.md | 0 .../solution.md | 0 .../task.md | 0 .../solution.md | 0 .../task.md | 0 .../solution.md | 0 .../{4-closure-sum => 6-closure-sum}/task.md | 0 .../03-closure/7-let-scope/solution.md | 40 + .../03-closure/7-let-scope/task.md | 21 + .../03-closure/7-sort-by-field/solution.md | 22 - .../_js.view/solution.js | 0 .../_js.view/source.js | 0 .../_js.view/test.js | 0 .../solution.md | 0 .../task.md | 0 .../03-closure/8-make-army/solution.md | 120 - .../03-closure/8-make-army/task.md | 35 - .../9-sort-by-field/_js.view/solution.js | 3 + .../9-sort-by-field/_js.view/source.js | 5 + .../9-sort-by-field/_js.view/test.js | 39 + .../03-closure/9-sort-by-field/solution.md | 1 + .../task.md | 0 .../03-closure/article.md | 596 +- .../closure-function-declaration.svg | 1 + .../closure-makecounter-environment.svg | 1 + .../closure-makecounter-nested-call-2.svg | 1 + .../closure-makecounter-nested-call.svg | 1 + .../03-closure/closure-makecounter.svg | 1 + .../03-closure/closure-variable-phrase.svg | 1 + .../03-closure/lexenv-if.svg | 70 +- .../lexenv-nested-makecounter-1.svg | 40 +- .../lexenv-nested-makecounter-2.svg | 70 +- .../lexenv-nested-makecounter-3.svg | 72 +- .../lexenv-nested-makecounter-4.svg | 87 +- .../lexenv-nested-makecounter-5.svg | 96 +- .../lexenv-nested-makecounter-6.svg | 86 +- .../03-closure/lexenv-nested-work.svg | 90 - .../lexical-environment-global-2.svg | 65 +- .../lexical-environment-global-3.svg | 62 +- .../03-closure/lexical-environment-global.svg | 41 +- .../lexical-environment-simple-lookup.svg | 74 +- .../03-closure/lexical-environment-simple.svg | 68 +- .../03-closure/lexical-search-order.svg | 49 +- .../03-closure/variable-scope-lookup.svg | 1 + 1-js/06-advanced-functions/04-var/article.md | 137 +- .../05-global-object/article.md | 14 +- .../5-sum-many-brackets/_js.view/solution.js | 15 + .../5-sum-many-brackets/_js.view/source.js | 12 + .../5-sum-many-brackets/_js.view/test.js | 19 + .../5-sum-many-brackets/solution.md | 2 +- .../06-function-object/article.md | 7 +- .../07-new-function/article.md | 2 +- .../1-output-numbers-100ms/solution.md | 2 +- .../1-output-numbers-100ms/task.md | 3 +- .../08-settimeout-setinterval/article.md | 49 +- .../settimeout-interval.svg | 40 +- .../01-spy-decorator/_js.view/solution.js | 5 +- .../01-spy-decorator/solution.md | 2 +- .../03-debounce/_js.view/solution.js | 18 +- .../03-debounce/_js.view/test.js | 49 +- .../03-debounce/debounce.svg | 1 + .../03-debounce/debounce.view/index.html | 24 + .../03-debounce/solution.md | 27 +- .../03-debounce/task.md | 49 +- .../04-throttle/_js.view/test.js | 20 +- .../04-throttle/solution.md | 4 +- .../04-throttle/task.md | 19 +- .../09-call-apply-decorators/article.md | 147 +- .../decorator-makecaching-wrapper.svg | 65 +- .../4-function-property-after-bind/task.md | 2 +- 1-js/06-advanced-functions/10-bind/article.md | 131 +- .../1-ask-currying/task.md | 2 +- .../12-arrow-functions/article.md | 1 - .../01-property-descriptors/article.md | 73 +- .../02-property-accessors/article.md | 32 +- .../2-search-algorithm/task.md | 2 +- .../3-proto-and-this/task.md | 2 +- .../4-hamster-proto/solution.md | 2 +- .../4-hamster-proto/task.md | 4 +- .../01-prototype-inheritance/article.md | 116 +- .../object-prototype-empty.svg | 23 +- .../proto-animal-rabbit-chain.svg | 41 +- .../proto-animal-rabbit-walk-2.svg | 30 +- .../proto-animal-rabbit-walk-3.svg | 31 +- .../proto-animal-rabbit-walk.svg | 30 +- .../proto-animal-rabbit.svg | 29 +- .../proto-user-admin.svg | 33 +- .../rabbit-animal-object.svg | 1 + .../1-changing-prototype/solution.md | 2 +- .../1-changing-prototype/task.md | 4 +- .../4-new-object-same-constructor/solution.md | 4 +- .../02-function-prototype/article.md | 12 +- .../function-prototype-constructor.svg | 27 +- .../proto-constructor-animal-rabbit.svg | 37 +- .../rabbit-prototype-constructor.svg | 40 +- .../2-defer-to-prototype-extended/solution.md | 24 + .../03-native-prototypes/article.md | 24 +- .../function-prototype-constructor.svg | 27 +- .../native-prototypes-array-tostring.svg | 40 +- .../native-prototypes-classes.svg | 88 +- .../object-prototype-1.svg | 39 +- .../object-prototype-null.svg | 22 +- .../03-native-prototypes/object-prototype.svg | 31 +- .../proto-constructor-animal-rabbit.svg | 37 +- .../rabbit-prototype-constructor.svg | 40 +- .../04-prototype-methods/article.md | 62 +- .../object-prototype-2.svg | 39 +- .../object-prototype-null.svg | 22 +- .../01-class/1-rewrite-to-class/task.md | 2 +- 1-js/09-classes/01-class/article.md | 152 +- 1-js/09-classes/01-class/class-user.svg | 30 +- .../solution.view/extended-clock.js | 2 +- .../rabbit-extends-object.svg | 67 - .../animal-rabbit-extends.svg | 65 +- .../02-class-inheritance/article.md | 286 +- .../class-inheritance-array-object.svg | 42 +- .../class-inheritance-rabbit-animal-2.svg | 63 +- .../class-inheritance-rabbit-animal.svg | 40 +- .../rabbit-animal-independent-animal.svg | 43 +- .../rabbit-animal-independent-rabbit.svg | 42 +- .../super-homeobject-wrong.svg | 1 + .../02-class-inheritance/this-super-loop.svg | 73 +- .../rabbit-extends-object.svg | 1 + .../3-class-extend-object/solution.md | 2 +- .../3-class-extend-object/task.md | 5 +- .../animal-rabbit-static.svg | 65 +- .../03-static-properties-methods/article.md | 32 +- .../article.md | 80 +- 1-js/09-classes/05-extend-natives/article.md | 10 +- .../object-date-inheritance.svg | 72 +- .../1-strange-instanceof/task.md | 2 +- 1-js/09-classes/06-instanceof/article.md | 18 +- 1-js/09-classes/06-instanceof/instanceof.svg | 52 +- 1-js/09-classes/07-mixins/article.md | 30 +- 1-js/09-classes/07-mixins/head.html | 2 +- .../07-mixins/mixin-inheritance.svg | 55 +- 1-js/10-error-handling/1-try-catch/article.md | 68 +- .../1-try-catch/try-catch-flow.svg | 59 +- .../1-format-error/solution.md | 2 +- .../2-custom-errors/article.md | 54 +- 1-js/11-async/01-callbacks/article.md | 48 +- 1-js/11-async/01-callbacks/callback-hell.svg | 355 +- 1-js/11-async/02-promise-basics/article.md | 114 +- .../02-promise-basics/promise-reject-1.svg | 28 +- .../02-promise-basics/promise-resolve-1.svg | 28 +- .../promise-resolve-reject.svg | 37 +- .../01-then-vs-catch/solution.md | 2 +- 1-js/11-async/03-promise-chaining/article.md | 22 +- .../04-promise-error-handling/article.md | 203 +- .../promise-then-chain.svg | 39 +- .../promise-then-many.svg | 33 +- 1-js/11-async/05-promise-api/article.md | 290 +- 1-js/11-async/06-promisify/article.md | 60 +- 1-js/11-async/07-microtask-queue/article.md | 40 +- .../07-microtask-queue/promiseQueue.svg | 44 +- .../08-async-await/01-rewrite-async/task.md | 6 +- .../08-async-await/02-rewrite-async-2/task.md | 4 +- .../03-async-from-regular/task.md | 4 +- 1-js/11-async/08-async-await/article.md | 51 +- .../01-pseudo-random-generator/solution.md | 2 +- .../01-pseudo-random-generator/task.md | 4 +- .../1-generators/article.md | 165 +- .../1-generators/genYield2-2.svg | 70 +- .../1-generators/genYield2.svg | 42 +- .../1-generators/generateSequence-1.svg | 28 +- .../1-generators/generateSequence-2.svg | 31 +- .../1-generators/generateSequence-3.svg | 31 +- .../1-generators/generateSequence-4.svg | 31 +- .../2-async-iterators-generators/article.md | 282 +- .../2-async-iterators-generators/head.html | 2 +- 1-js/13-modules/01-modules-intro/article.md | 67 +- 1-js/13-modules/02-import-export/article.md | 17 +- .../03-modules-dynamic-imports/article.md | 3 +- .../01-proxy/01-error-nonexisting/solution.md | 23 + .../01-proxy/01-error-nonexisting/task.md | 32 + 1-js/99-js-misc/01-proxy/article.md | 142 +- .../01-proxy/proxy-inherit-admin.svg | 2 +- 1-js/99-js-misc/01-proxy/proxy.svg | 2 +- 1-js/99-js-misc/02-eval/article.md | 4 +- .../03-currying-partials/article.md | 22 +- .../04-reference-type/3-why-this/solution.md | 4 +- 1-js/99-js-misc/04-reference-type/article.md | 8 +- 1-js/99-js-misc/05-bigint/article.md | 4 +- 10-misc/12-mutation-observer/article.md | 249 - 10-misc/index.md | 4 - .../01-browser-environment/article.md | 37 +- .../01-browser-environment/windowObjects.svg | 73 +- 2-ui/1-document/02-dom-nodes/article.md | 92 +- 2-ui/1-document/02-dom-nodes/domconsole0.png | Bin 94995 -> 0 bytes 2-ui/1-document/02-dom-nodes/domconsole0.svg | 1 + .../02-dom-nodes/domconsole0@2x.png | Bin 167554 -> 0 bytes 2-ui/1-document/02-dom-nodes/domconsole1.png | Bin 72398 -> 0 bytes 2-ui/1-document/02-dom-nodes/domconsole1.svg | 1 + .../02-dom-nodes/domconsole1@2x.png | Bin 141140 -> 0 bytes .../02-dom-nodes/{elks.html => elk.html} | 2 +- 2-ui/1-document/02-dom-nodes/elk.svg | 1 + 2-ui/1-document/02-dom-nodes/elks.png | Bin 74948 -> 0 bytes 2-ui/1-document/02-dom-nodes/elks@2x.png | Bin 132790 -> 0 bytes 2-ui/1-document/02-dom-nodes/inspect.png | Bin 112368 -> 0 bytes 2-ui/1-document/02-dom-nodes/inspect.svg | 1 + 2-ui/1-document/02-dom-nodes/inspect@2x.png | Bin 198241 -> 0 bytes .../03-dom-navigation/1-dom-children/task.md | 4 +- .../3-navigation-links-which-null/solution.md | 4 +- 2-ui/1-document/03-dom-navigation/article.md | 32 +- .../03-dom-navigation/dom-links-elements.svg | 64 +- .../03-dom-navigation/dom-links.svg | 60 +- .../04-searching-elements-dom/article.md | 75 +- .../05-basic-dom-node-properties/article.md | 45 +- .../dom-class-hierarchy.svg | 86 +- .../article.md | 8 +- .../10-clock-setinterval/solution.md | 10 +- .../solution.view/index.html | 7 +- .../12-sort-table/solution.md | 21 +- .../12-sort-table/solution.view/index.html | 59 +- .../12-sort-table/source.view/index.html | 54 +- .../12-sort-table/task.md | 46 +- .../07-modifying-document/5-why-aaa/task.md | 6 +- .../9-calendar-table/solution.md | 8 +- .../07-modifying-document/article.md | 118 +- .../before-prepend-append-after.svg | 71 +- .../07-modifying-document/insert-adjacent.svg | 71 +- .../08-styles-and-classes/article.md | 4 +- .../1-get-scroll-height-bottom/task.md | 2 +- .../4-put-ball-in-center/ball-half/index.html | 6 +- .../4-put-ball-in-center/field.svg | 21 +- .../4-put-ball-in-center/solution.md | 9 +- .../solution.view/index.html | 2 +- .../4-put-ball-in-center/task.md | 2 +- 2-ui/1-document/09-size-and-scroll/article.md | 20 +- .../09-size-and-scroll/metric-all.svg | 137 +- .../metric-client-left-top-rtl.svg | 71 +- .../metric-client-left-top.svg | 60 +- .../metric-client-width-height.svg | 113 +- .../metric-client-width-nopadding.svg | 78 +- .../09-size-and-scroll/metric-css.svg | 110 +- .../metric-offset-parent.svg | 89 +- .../metric-offset-width-height.svg | 113 +- .../09-size-and-scroll/metric-scroll-top.svg | 88 +- .../metric-scroll-width-height.svg | 92 +- .../10-size-and-scroll-window/article.md | 72 +- .../document-client-width-height.svg | 29 +- .../1-find-point-coordinates/solution.md | 2 +- .../solution.view/index.html | 4 +- .../solution.view/index.html | 4 +- 2-ui/1-document/11-coordinates/article.md | 42 +- .../11-coordinates/coordinates-negative.svg | 1 + .../1-document/11-coordinates/coordinates.svg | 1 + ...cument-and-window-coordinates-scrolled.svg | 1 + .../04-move-ball-field/move-ball-coords.svg | 52 +- .../04-move-ball-field/solution.md | 4 +- .../07-carousel/carousel1.svg | 32 +- .../07-carousel/carousel2.svg | 34 +- .../07-carousel/solution.md | 2 +- .../01-introduction-browser-events/article.md | 123 +- .../02-bubbling-and-capturing/article.md | 21 +- .../event-order-bubbling.svg | 29 +- .../4-behavior-tooltip/task.md | 4 +- 2-ui/2-events/03-event-delegation/article.md | 24 +- .../03-event-delegation/bagua-bubble.svg | 28 +- .../1-why-return-false-fails/solution.md | 4 +- .../1-why-return-false-fails/task.md | 2 +- .../solution.view/index.html | 2 +- .../source.view/index.html | 2 +- .../2-catch-link-navigation/task.md | 2 +- .../04-default-browser-action/article.md | 30 +- 2-ui/2-events/05-dispatch-events/article.md | 76 +- .../1-mouse-events-basics/article.md | 129 +- .../1-mouse-events-basics/head.html | 2 +- .../2-hoverintent/solution.md | 2 +- .../2-hoverintent/solution.view/index.html | 25 +- .../2-hoverintent/solution.view/test.js | 6 +- .../2-hoverintent/source.view/hoverIntent.js | 1 + .../2-hoverintent/source.view/index.html | 26 +- .../2-hoverintent/source.view/style.css | 18 +- .../2-hoverintent/source.view/test.js | 24 +- .../2-hoverintent/task.md | 4 - .../article.md | 61 +- .../index.html | 4 + .../script.js | 21 +- .../script.js | 8 +- .../mouseleave.view/style.css | 2 +- .../mouseover-bubble-nested.svg | 2 +- .../mouseover-to-child.svg | 30 +- .../mouseoverout-child.view/style.css | 2 +- .../mouseoverout-fast.view/script.js | 1 + .../mouseoverout-fast.view/style.css | 2 +- .../2-drag-heroes/solution.view/field.svg | 21 +- .../2-drag-heroes/solution.view/soccer.js | 14 +- .../4-mouse-drag-and-drop/article.md | 94 +- .../ball.view/index.html | 9 +- .../ball2.view/index.html | 9 +- .../4-mouse-drag-and-drop/ball_shift.svg | 42 +- .../6-pointer-events/article.md | 147 +- .../8-onscroll/1-endless-page/solution.md | 10 +- .../3-load-visible-img/source.view/index.html | 32 +- 2-ui/3-event-details/8-onscroll/article.md | 10 +- .../1-add-select-option/task.md | 2 + .../1-form-elements/article.md | 65 +- .../1-form-elements/form-navigation.svg | 46 +- 2-ui/4-forms-controls/2-focus-blur/article.md | 33 +- .../3-events-change-input/article.md | 10 +- .../01-onload-ondomcontentloaded/article.md | 45 +- .../02-script-async-defer/article.md | 106 +- 2-ui/5-loading/03-onload-onerror/article.md | 40 +- .../01-mutation-observer/article.md | 37 +- 2-ui/99-ui-misc/02-selection-range/article.md | 67 +- .../range-example-p-2-b-3-range.svg | 2 +- 2-ui/99-ui-misc/03-event-loop/article.md | 18 +- .../01-popup-windows/article.md | 166 +- .../03-cross-window-communication/article.md | 6 +- .../sandbox.view/index.html | 2 +- .../8bit-integer-256.svg | 27 +- .../8bit-integer-257.svg | 27 +- .../arraybuffer-view-buffersource.svg | 172 +- .../01-arraybuffer-binary-arrays/article.md | 37 +- 4-binary/02-text-decoder/article.md | 6 +- 4-binary/03-blob/article.md | 68 +- 4-binary/03-blob/blob.svg | 56 +- 4-binary/04-file/article.md | 6 + 5-network/01-fetch-basics/article.md | 13 - .../01-fetch-users/_js.view/solution.js | 24 + .../01-fetch-users/_js.view/source.js | 4 + .../01-fetch/01-fetch-users/_js.view/test.js | 10 + 5-network/01-fetch/01-fetch-users/solution.md | 40 + 5-network/01-fetch/01-fetch-users/task.md | 13 + 5-network/01-fetch/article.md | 316 + 5-network/01-fetch/logo-fetch.svg | 4 + 5-network/01-fetch/post.view/server.js | 34 + 5-network/02-formdata/article.md | 189 + 5-network/02-formdata/post.view/server.js | 78 + 5-network/03-fetch-progress/article.md | 114 + 5-network/03-fetch-progress/logo-fetch.svg | 4 + .../progress.view/index.html | 36 + .../03-fetch-progress/progress.view/long.txt | 20465 ++++++++++++++++ 5-network/04-fetch-abort/article.md | 148 + 5-network/04-fetch-abort/demo.view/server.js | 21 + .../1-do-we-need-origin/solution.md | 9 + .../1-do-we-need-origin/task.md | 28 + 5-network/05-fetch-crossorigin/article.md | 387 + .../cors-gmail-messages.svg | 1 + .../xhr-another-domain.svg | 1 + .../05-fetch-crossorigin/xhr-preflight.svg | 1 + 5-network/06-fetch-api/article.md | 224 + 5-network/06-fetch-api/logo-fetch.svg | 4 + 5-network/06-fetch-api/post.view/index.html | 36 + 5-network/06-fetch-api/post.view/server.js | 55 + 5-network/07-url/article.md | 22 +- 5-network/07-url/url-object.svg | 2 +- 5-network/07-xmlhttprequest/article.md | 26 - 5-network/08-xmlhttprequest/article.md | 528 + .../08-xmlhttprequest/example.view/index.html | 30 + .../08-xmlhttprequest/example.view/server.js | 52 + 5-network/08-xmlhttprequest/hello.txt | 1 + .../phones-async.view/index.html | 42 + .../phones-async.view/phones.json | 155 + .../phones-async.view/server.js | 30 + 5-network/08-xmlhttprequest/phones.json | 155 + .../08-xmlhttprequest/phones.view/index.html | 28 + .../08-xmlhttprequest/phones.view/phones.json | 155 + .../08-xmlhttprequest/phones.view/server.js | 30 + .../08-xmlhttprequest/post.view/index.html | 36 + .../08-xmlhttprequest/post.view/server.js | 58 + 5-network/09-resume-upload/article.md | 6 +- .../upload-resume.view/index.html | 50 + .../upload-resume.view/server.js | 123 + .../upload-resume.view/uploader.js | 75 + 5-network/10-long-polling/article.md | 10 +- 5-network/10-long-polling/long-polling.svg | 1 + .../10-long-polling/longpoll.view/browser.js | 54 + .../10-long-polling/longpoll.view/index.html | 18 + .../10-long-polling/longpoll.view/server.js | 87 + 5-network/11-websocket/article.md | 388 + 5-network/11-websocket/chat.view/index.html | 39 + 5-network/11-websocket/chat.view/server.js | 61 + 5-network/11-websocket/demo.view/server.js | 35 + .../11-websocket/websocket-handshake.svg | 1 + 5-network/12-server-sent-events/article.md | 271 + .../eventsource.view/index.html | 50 + .../eventsource.view/server.js | 48 + 6-data-storage/01-cookie/article.md | 83 +- .../01-cookie/cookie-third-party-2.svg | 29 +- .../01-cookie/cookie-third-party-3.svg | 30 +- .../01-cookie/cookie-third-party.svg | 30 +- 6-data-storage/01-cookie/cookie-xsrf.svg | 35 +- 6-data-storage/01-cookie/cookie.js | 2 +- .../02-localstorage/1-form-autosave/task.md | 2 +- 6-data-storage/02-localstorage/article.md | 42 +- 6-data-storage/03-indexeddb/article.md | 244 +- .../03-indexeddb/indexeddb-index.svg | 47 +- 7-animation/1-bezier-curve/article.md | 18 +- .../2-animate-logo-bezier-css/task.md | 2 +- .../4-animate-circle-callback/solution.md | 0 .../solution.view/index.html | 0 .../4-animate-circle-callback}/task.md | 0 7-animation/2-css-animations/article.md | 38 +- .../3-js-animation/1-animate-ball/solution.md | 6 +- 7-animation/3-js-animation/article.md | 12 +- 7-animation/3-js-animation/back.svg | 23 +- 7-animation/3-js-animation/bounce-inout.svg | 24 +- 7-animation/3-js-animation/circ-ease.svg | 25 +- 7-animation/3-js-animation/circ.svg | 23 +- 7-animation/3-js-animation/elastic.svg | 23 +- 7-animation/3-js-animation/linear.svg | 23 +- 7-animation/3-js-animation/quad.svg | 23 +- 7-animation/3-js-animation/quint.svg | 23 +- .../1-webcomponents-intro/article.md | 4 +- 8-web-components/2-custom-elements/article.md | 33 +- 8-web-components/3-shadow-dom/article.md | 6 +- .../5-slots-composition/article.md | 71 +- .../6-shadow-dom-style/article.md | 30 +- .../01-regexp-introduction/article.md | 170 +- .../02-regexp-character-classes/article.md | 203 + .../love-html5-classes.svg | 0 .../02-regexp-methods/article.md | 458 - .../03-regexp-character-classes/article.md | 203 - .../03-regexp-unicode/article.md | 161 + .../1-start-end/solution.md | 3 +- .../1-start-end/task.md | 0 .../04-regexp-anchors/article.md | 52 + .../article.md | 114 - .../05-regexp-multiline-mode/article.md | 87 + .../1-find-time-hh-mm/solution.md | 6 + .../1-find-time-hh-mm/task.md | 9 + .../06-regexp-boundary/article.md | 52 + .../hello-java-boundaries.svg | 1 + .../article.md | 36 +- .../1-find-range-1/solution.md | 2 +- .../1-find-range-1/task.md | 0 .../2-find-time-2-formats/solution.md | 4 +- .../2-find-time-2-formats/task.md | 4 +- .../article.md | 197 + .../3-find-html-comments/solution.md | 17 - .../4-find-html-tags-greedy-lazy/task.md | 15 - .../witch_greedy1.svg | 16 - .../witch_greedy2.svg | 16 - .../witch_greedy3.svg | 16 - .../witch_greedy4.svg | 19 - .../witch_greedy5.svg | 19 - .../witch_greedy6.svg | 17 - .../08-regexp-greedy-and-lazy/witch_lazy3.svg | 18 - .../08-regexp-greedy-and-lazy/witch_lazy4.svg | 18 - .../08-regexp-greedy-and-lazy/witch_lazy5.svg | 16 - .../08-regexp-greedy-and-lazy/witch_lazy6.svg | 18 - .../1-find-webcolor-3-or-6/solution.md | 29 - .../solution.md | 18 - .../3-find-decimal-positive-numbers/task.md | 12 - .../4-find-decimal-numbers/solution.md | 11 - .../5-parse-expression/solution.md | 51 - .../09-regexp-groups/article.md | 241 - .../09-regexp-groups/regexp-nested-groups.svg | 48 - .../1-find-text-manydots/solution.md | 4 +- .../1-find-text-manydots/task.md | 4 +- .../2-find-html-colors-6hex/solution.md | 10 +- .../2-find-html-colors-6hex/task.md | 6 +- .../article.md | 64 +- .../10-regexp-backreferences/article.md | 65 - .../1-lazy-greedy/solution.md | 0 .../1-lazy-greedy/task.md | 2 +- .../3-find-html-comments/solution.md | 15 + .../3-find-html-comments/task.md | 4 +- .../4-find-html-tags-greedy-lazy/solution.md | 4 +- .../4-find-html-tags-greedy-lazy/task.md | 15 + .../article.md | 85 +- .../witch_greedy1.svg | 1 + .../witch_greedy2.svg | 1 + .../witch_greedy3.svg | 1 + .../witch_greedy4.svg | 1 + .../witch_greedy5.svg | 1 + .../witch_greedy6.svg | 1 + .../10-regexp-greedy-and-lazy/witch_lazy3.svg | 1 + .../10-regexp-greedy-and-lazy/witch_lazy4.svg | 1 + .../10-regexp-greedy-and-lazy/witch_lazy5.svg | 1 + .../10-regexp-greedy-and-lazy/witch_lazy6.svg | 1 + .../02-find-matching-bbtags/solution.md | 23 - .../11-regexp-alternation/article.md | 59 - .../11-regexp-groups/01-test-mac/solution.md | 21 + .../01-test-mac}/task.md | 10 +- .../02-find-webcolor-3-or-6/solution.md | 27 + .../02-find-webcolor-3-or-6}/task.md | 6 +- .../03-find-decimal-numbers/solution.md | 11 + .../03-find-decimal-numbers}/task.md | 4 +- .../04-parse-expression/solution.md | 56 + .../04-parse-expression}/task.md | 0 .../11-regexp-groups/article.md | 364 + .../regexp-nested-groups-matches.svg | 1 + .../regexp-nested-groups-pattern.svg | 1 + .../12-regexp-anchors/2-test-mac/solution.md | 21 - .../12-regexp-anchors/article.md | 55 - .../12-regexp-backreferences/article.md | 72 + .../01-find-programming-language/solution.md | 8 +- .../01-find-programming-language/task.md | 4 +- .../02-find-matching-bbtags/solution.md | 23 + .../02-find-matching-bbtags/task.md | 10 +- .../03-match-quoted-string/solution.md | 4 +- .../03-match-quoted-string/task.md | 6 +- .../04-match-exact-tag/solution.md | 4 +- .../04-match-exact-tag/task.md | 4 +- .../13-regexp-alternation/article.md | 70 + .../13-regexp-multiline-mode/article.md | 76 - .../1-find-non-negative-integers/solution.md | 28 + .../1-find-non-negative-integers/task.md | 14 + .../2-insert-after-head/solution.md | 36 + .../2-insert-after-head/task.md | 30 + .../14-regexp-lookahead-lookbehind/article.md | 101 +- .../article.md | 318 + .../article.md | 293 - .../16-regexp-sticky/article.md | 138 + .../17-regexp-methods/article.md | 344 + .../20-regexp-unicode/article.md | 89 - .../21-regexp-unicode-properties/article.md | 86 - .../22-regexp-sticky/article.md | 71 - README.md | 141 +- css.md | 4 + 707 files changed, 36266 insertions(+), 18414 deletions(-) create mode 100644 1-js/02-first-steps/01-hello-world/1-hello-alert/index.html create mode 100644 1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md create mode 100644 1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md create mode 100644 1-js/02-first-steps/08-operators/4-fix-prompt/solution.md create mode 100644 1-js/02-first-steps/08-operators/4-fix-prompt/task.md create mode 100644 1-js/03-code-quality/01-debugging-chrome/largeIcons.svg delete mode 100644 1-js/03-code-quality/01-debugging-chrome/toolbarButtonGlyphs.svg delete mode 100644 1-js/03-code-quality/02-coding-style/figure-bracket-style.png delete mode 100644 1-js/03-code-quality/02-coding-style/figure-bracket-style@2x.png delete mode 100644 1-js/04-object-basics/01-object/4-const-object/solution.md delete mode 100644 1-js/04-object-basics/01-object/4-const-object/task.md delete mode 100644 1-js/04-object-basics/01-object/variable-contains-reference.svg delete mode 100644 1-js/04-object-basics/01-object/variable-copy-reference.svg delete mode 100644 1-js/04-object-basics/01-object/variable-copy-value.svg delete mode 100644 1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md delete mode 100644 1-js/04-object-basics/04-object-methods/2-check-syntax/task.md delete mode 100644 1-js/04-object-basics/04-object-methods/3-why-this/solution.md delete mode 100644 1-js/04-object-basics/04-object-methods/3-why-this/task.md create mode 100644 1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/solution.js create mode 100644 1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/test.js rename 1-js/{11-async/01-callbacks/01-animate-circle-callback => 05-data-types/05-array-methods/12-reduce-object}/solution.md (100%) create mode 100644 1-js/05-data-types/05-array-methods/12-reduce-object/task.md create mode 100644 1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md create mode 100644 1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md rename 1-js/06-advanced-functions/03-closure/{8-make-army => 10-make-army}/_js.view/solution.js (100%) rename 1-js/06-advanced-functions/03-closure/{8-make-army => 10-make-army}/_js.view/source.js (100%) rename 1-js/06-advanced-functions/03-closure/{8-make-army => 10-make-army}/_js.view/test.js (100%) create mode 100644 1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg create mode 100644 1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg create mode 100644 1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg create mode 100644 1-js/06-advanced-functions/03-closure/10-make-army/solution.md create mode 100644 1-js/06-advanced-functions/03-closure/10-make-army/task.md create mode 100644 1-js/06-advanced-functions/03-closure/2-closure-variable-access/lexenv-nested-work.svg create mode 100644 1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md create mode 100644 1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md rename 1-js/06-advanced-functions/03-closure/{1-counter-independent => 3-counter-independent}/solution.md (100%) rename 1-js/06-advanced-functions/03-closure/{1-counter-independent => 3-counter-independent}/task.md (100%) rename 1-js/06-advanced-functions/03-closure/{2-counter-object-independent => 4-counter-object-independent}/solution.md (100%) rename 1-js/06-advanced-functions/03-closure/{2-counter-object-independent => 4-counter-object-independent}/task.md (100%) rename 1-js/06-advanced-functions/03-closure/{3-function-in-if => 5-function-in-if}/solution.md (100%) rename 1-js/06-advanced-functions/03-closure/{3-function-in-if => 5-function-in-if}/task.md (100%) rename 1-js/06-advanced-functions/03-closure/{4-closure-sum => 6-closure-sum}/solution.md (100%) rename 1-js/06-advanced-functions/03-closure/{4-closure-sum => 6-closure-sum}/task.md (100%) create mode 100644 1-js/06-advanced-functions/03-closure/7-let-scope/solution.md create mode 100644 1-js/06-advanced-functions/03-closure/7-let-scope/task.md delete mode 100644 1-js/06-advanced-functions/03-closure/7-sort-by-field/solution.md rename 1-js/06-advanced-functions/03-closure/{6-filter-through-function => 8-filter-through-function}/_js.view/solution.js (100%) rename 1-js/06-advanced-functions/03-closure/{6-filter-through-function => 8-filter-through-function}/_js.view/source.js (100%) rename 1-js/06-advanced-functions/03-closure/{6-filter-through-function => 8-filter-through-function}/_js.view/test.js (100%) rename 1-js/06-advanced-functions/03-closure/{6-filter-through-function => 8-filter-through-function}/solution.md (100%) rename 1-js/06-advanced-functions/03-closure/{6-filter-through-function => 8-filter-through-function}/task.md (100%) delete mode 100644 1-js/06-advanced-functions/03-closure/8-make-army/solution.md delete mode 100644 1-js/06-advanced-functions/03-closure/8-make-army/task.md create mode 100644 1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/solution.js create mode 100644 1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js create mode 100644 1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js create mode 100644 1-js/06-advanced-functions/03-closure/9-sort-by-field/solution.md rename 1-js/06-advanced-functions/03-closure/{7-sort-by-field => 9-sort-by-field}/task.md (100%) create mode 100644 1-js/06-advanced-functions/03-closure/closure-function-declaration.svg create mode 100644 1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg create mode 100644 1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg create mode 100644 1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg create mode 100644 1-js/06-advanced-functions/03-closure/closure-makecounter.svg create mode 100644 1-js/06-advanced-functions/03-closure/closure-variable-phrase.svg delete mode 100644 1-js/06-advanced-functions/03-closure/lexenv-nested-work.svg create mode 100644 1-js/06-advanced-functions/03-closure/variable-scope-lookup.svg create mode 100644 1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/solution.js create mode 100644 1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/source.js create mode 100644 1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/test.js create mode 100644 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg create mode 100644 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.view/index.html create mode 100644 1-js/08-prototypes/01-prototype-inheritance/rabbit-animal-object.svg delete mode 100644 1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg create mode 100644 1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg create mode 100644 1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg rename 1-js/09-classes/{02-class-inheritance => 03-static-properties-methods}/3-class-extend-object/solution.md (97%) rename 1-js/09-classes/{02-class-inheritance => 03-static-properties-methods}/3-class-extend-object/task.md (88%) create mode 100644 1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md create mode 100644 1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md delete mode 100644 10-misc/12-mutation-observer/article.md delete mode 100644 10-misc/index.md delete mode 100644 2-ui/1-document/02-dom-nodes/domconsole0.png create mode 100644 2-ui/1-document/02-dom-nodes/domconsole0.svg delete mode 100644 2-ui/1-document/02-dom-nodes/domconsole0@2x.png delete mode 100644 2-ui/1-document/02-dom-nodes/domconsole1.png create mode 100644 2-ui/1-document/02-dom-nodes/domconsole1.svg delete mode 100644 2-ui/1-document/02-dom-nodes/domconsole1@2x.png rename 2-ui/1-document/02-dom-nodes/{elks.html => elk.html} (86%) create mode 100644 2-ui/1-document/02-dom-nodes/elk.svg delete mode 100644 2-ui/1-document/02-dom-nodes/elks.png delete mode 100644 2-ui/1-document/02-dom-nodes/elks@2x.png delete mode 100644 2-ui/1-document/02-dom-nodes/inspect.png create mode 100644 2-ui/1-document/02-dom-nodes/inspect.svg delete mode 100644 2-ui/1-document/02-dom-nodes/inspect@2x.png create mode 100644 2-ui/1-document/11-coordinates/coordinates-negative.svg create mode 100644 2-ui/1-document/11-coordinates/coordinates.svg create mode 100644 2-ui/1-document/11-coordinates/document-and-window-coordinates-scrolled.svg create mode 100644 5-network/01-fetch/01-fetch-users/_js.view/solution.js create mode 100644 5-network/01-fetch/01-fetch-users/_js.view/source.js create mode 100644 5-network/01-fetch/01-fetch-users/_js.view/test.js create mode 100644 5-network/01-fetch/01-fetch-users/solution.md create mode 100644 5-network/01-fetch/01-fetch-users/task.md create mode 100644 5-network/01-fetch/article.md create mode 100644 5-network/01-fetch/logo-fetch.svg create mode 100644 5-network/01-fetch/post.view/server.js create mode 100644 5-network/02-formdata/article.md create mode 100644 5-network/02-formdata/post.view/server.js create mode 100644 5-network/03-fetch-progress/article.md create mode 100644 5-network/03-fetch-progress/logo-fetch.svg create mode 100644 5-network/03-fetch-progress/progress.view/index.html create mode 100644 5-network/03-fetch-progress/progress.view/long.txt create mode 100644 5-network/04-fetch-abort/article.md create mode 100644 5-network/04-fetch-abort/demo.view/server.js create mode 100644 5-network/05-fetch-crossorigin/1-do-we-need-origin/solution.md create mode 100644 5-network/05-fetch-crossorigin/1-do-we-need-origin/task.md create mode 100644 5-network/05-fetch-crossorigin/article.md create mode 100644 5-network/05-fetch-crossorigin/cors-gmail-messages.svg create mode 100644 5-network/05-fetch-crossorigin/xhr-another-domain.svg create mode 100644 5-network/05-fetch-crossorigin/xhr-preflight.svg create mode 100644 5-network/06-fetch-api/article.md create mode 100644 5-network/06-fetch-api/logo-fetch.svg create mode 100644 5-network/06-fetch-api/post.view/index.html create mode 100644 5-network/06-fetch-api/post.view/server.js create mode 100644 5-network/08-xmlhttprequest/article.md create mode 100644 5-network/08-xmlhttprequest/example.view/index.html create mode 100644 5-network/08-xmlhttprequest/example.view/server.js create mode 100644 5-network/08-xmlhttprequest/hello.txt create mode 100644 5-network/08-xmlhttprequest/phones-async.view/index.html create mode 100644 5-network/08-xmlhttprequest/phones-async.view/phones.json create mode 100644 5-network/08-xmlhttprequest/phones-async.view/server.js create mode 100644 5-network/08-xmlhttprequest/phones.json create mode 100644 5-network/08-xmlhttprequest/phones.view/index.html create mode 100644 5-network/08-xmlhttprequest/phones.view/phones.json create mode 100644 5-network/08-xmlhttprequest/phones.view/server.js create mode 100644 5-network/08-xmlhttprequest/post.view/index.html create mode 100644 5-network/08-xmlhttprequest/post.view/server.js create mode 100644 5-network/09-resume-upload/upload-resume.view/index.html create mode 100644 5-network/09-resume-upload/upload-resume.view/server.js create mode 100644 5-network/09-resume-upload/upload-resume.view/uploader.js create mode 100644 5-network/10-long-polling/long-polling.svg create mode 100644 5-network/10-long-polling/longpoll.view/browser.js create mode 100644 5-network/10-long-polling/longpoll.view/index.html create mode 100644 5-network/10-long-polling/longpoll.view/server.js create mode 100644 5-network/11-websocket/article.md create mode 100644 5-network/11-websocket/chat.view/index.html create mode 100644 5-network/11-websocket/chat.view/server.js create mode 100644 5-network/11-websocket/demo.view/server.js create mode 100644 5-network/11-websocket/websocket-handshake.svg create mode 100644 5-network/12-server-sent-events/article.md create mode 100644 5-network/12-server-sent-events/eventsource.view/index.html create mode 100644 5-network/12-server-sent-events/eventsource.view/server.js create mode 100644 7-animation/2-css-animations/4-animate-circle-callback/solution.md rename {1-js/11-async/01-callbacks/01-animate-circle-callback => 7-animation/2-css-animations/4-animate-circle-callback}/solution.view/index.html (100%) rename {1-js/11-async/01-callbacks/01-animate-circle-callback => 7-animation/2-css-animations/4-animate-circle-callback}/task.md (100%) create mode 100644 9-regular-expressions/02-regexp-character-classes/article.md rename 9-regular-expressions/{03-regexp-character-classes => 02-regexp-character-classes}/love-html5-classes.svg (100%) delete mode 100644 9-regular-expressions/02-regexp-methods/article.md delete mode 100644 9-regular-expressions/03-regexp-character-classes/article.md create mode 100644 9-regular-expressions/03-regexp-unicode/article.md rename 9-regular-expressions/{12-regexp-anchors => 04-regexp-anchors}/1-start-end/solution.md (77%) rename 9-regular-expressions/{12-regexp-anchors => 04-regexp-anchors}/1-start-end/task.md (100%) create mode 100644 9-regular-expressions/04-regexp-anchors/article.md delete mode 100644 9-regular-expressions/05-regexp-character-sets-and-ranges/article.md create mode 100644 9-regular-expressions/05-regexp-multiline-mode/article.md create mode 100644 9-regular-expressions/06-regexp-boundary/1-find-time-hh-mm/solution.md create mode 100644 9-regular-expressions/06-regexp-boundary/1-find-time-hh-mm/task.md create mode 100644 9-regular-expressions/06-regexp-boundary/article.md create mode 100644 9-regular-expressions/06-regexp-boundary/hello-java-boundaries.svg rename 9-regular-expressions/{04-regexp-escaping => 07-regexp-escaping}/article.md (54%) rename 9-regular-expressions/{05-regexp-character-sets-and-ranges => 08-regexp-character-sets-and-ranges}/1-find-range-1/solution.md (66%) rename 9-regular-expressions/{05-regexp-character-sets-and-ranges => 08-regexp-character-sets-and-ranges}/1-find-range-1/task.md (100%) rename 9-regular-expressions/{05-regexp-character-sets-and-ranges => 08-regexp-character-sets-and-ranges}/2-find-time-2-formats/solution.md (69%) rename 9-regular-expressions/{05-regexp-character-sets-and-ranges => 08-regexp-character-sets-and-ranges}/2-find-time-2-formats/task.md (76%) create mode 100644 9-regular-expressions/08-regexp-character-sets-and-ranges/article.md delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/3-find-html-comments/solution.md delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_greedy1.svg delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_greedy2.svg delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_greedy3.svg delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_greedy4.svg delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_greedy5.svg delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_greedy6.svg delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_lazy3.svg delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_lazy4.svg delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_lazy5.svg delete mode 100644 9-regular-expressions/08-regexp-greedy-and-lazy/witch_lazy6.svg delete mode 100644 9-regular-expressions/09-regexp-groups/1-find-webcolor-3-or-6/solution.md delete mode 100644 9-regular-expressions/09-regexp-groups/3-find-decimal-positive-numbers/solution.md delete mode 100644 9-regular-expressions/09-regexp-groups/3-find-decimal-positive-numbers/task.md delete mode 100644 9-regular-expressions/09-regexp-groups/4-find-decimal-numbers/solution.md delete mode 100644 9-regular-expressions/09-regexp-groups/5-parse-expression/solution.md delete mode 100644 9-regular-expressions/09-regexp-groups/article.md delete mode 100644 9-regular-expressions/09-regexp-groups/regexp-nested-groups.svg rename 9-regular-expressions/{07-regexp-quantifiers => 09-regexp-quantifiers}/1-find-text-manydots/solution.md (57%) rename 9-regular-expressions/{07-regexp-quantifiers => 09-regexp-quantifiers}/1-find-text-manydots/task.md (59%) rename 9-regular-expressions/{07-regexp-quantifiers => 09-regexp-quantifiers}/2-find-html-colors-6hex/solution.md (60%) rename 9-regular-expressions/{07-regexp-quantifiers => 09-regexp-quantifiers}/2-find-html-colors-6hex/task.md (71%) rename 9-regular-expressions/{07-regexp-quantifiers => 09-regexp-quantifiers}/article.md (63%) delete mode 100644 9-regular-expressions/10-regexp-backreferences/article.md rename 9-regular-expressions/{08-regexp-greedy-and-lazy => 10-regexp-greedy-and-lazy}/1-lazy-greedy/solution.md (100%) rename 9-regular-expressions/{08-regexp-greedy-and-lazy => 10-regexp-greedy-and-lazy}/1-lazy-greedy/task.md (56%) create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/3-find-html-comments/solution.md rename 9-regular-expressions/{08-regexp-greedy-and-lazy => 10-regexp-greedy-and-lazy}/3-find-html-comments/task.md (56%) rename 9-regular-expressions/{08-regexp-greedy-and-lazy => 10-regexp-greedy-and-lazy}/4-find-html-tags-greedy-lazy/solution.md (51%) create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md rename 9-regular-expressions/{08-regexp-greedy-and-lazy => 10-regexp-greedy-and-lazy}/article.md (70%) create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy1.svg create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy2.svg create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy3.svg create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy4.svg create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy5.svg create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy6.svg create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy3.svg create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy4.svg create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy5.svg create mode 100644 9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy6.svg delete mode 100644 9-regular-expressions/11-regexp-alternation/02-find-matching-bbtags/solution.md delete mode 100644 9-regular-expressions/11-regexp-alternation/article.md create mode 100644 9-regular-expressions/11-regexp-groups/01-test-mac/solution.md rename 9-regular-expressions/{12-regexp-anchors/2-test-mac => 11-regexp-groups/01-test-mac}/task.md (50%) create mode 100644 9-regular-expressions/11-regexp-groups/02-find-webcolor-3-or-6/solution.md rename 9-regular-expressions/{09-regexp-groups/1-find-webcolor-3-or-6 => 11-regexp-groups/02-find-webcolor-3-or-6}/task.md (59%) create mode 100644 9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/solution.md rename 9-regular-expressions/{09-regexp-groups/4-find-decimal-numbers => 11-regexp-groups/03-find-decimal-numbers}/task.md (71%) create mode 100644 9-regular-expressions/11-regexp-groups/04-parse-expression/solution.md rename 9-regular-expressions/{09-regexp-groups/5-parse-expression => 11-regexp-groups/04-parse-expression}/task.md (100%) create mode 100644 9-regular-expressions/11-regexp-groups/article.md create mode 100644 9-regular-expressions/11-regexp-groups/regexp-nested-groups-matches.svg create mode 100644 9-regular-expressions/11-regexp-groups/regexp-nested-groups-pattern.svg delete mode 100644 9-regular-expressions/12-regexp-anchors/2-test-mac/solution.md delete mode 100644 9-regular-expressions/12-regexp-anchors/article.md create mode 100644 9-regular-expressions/12-regexp-backreferences/article.md rename 9-regular-expressions/{11-regexp-alternation => 13-regexp-alternation}/01-find-programming-language/solution.md (79%) rename 9-regular-expressions/{11-regexp-alternation => 13-regexp-alternation}/01-find-programming-language/task.md (65%) create mode 100644 9-regular-expressions/13-regexp-alternation/02-find-matching-bbtags/solution.md rename 9-regular-expressions/{11-regexp-alternation => 13-regexp-alternation}/02-find-matching-bbtags/task.md (78%) rename 9-regular-expressions/{11-regexp-alternation => 13-regexp-alternation}/03-match-quoted-string/solution.md (87%) rename 9-regular-expressions/{11-regexp-alternation => 13-regexp-alternation}/03-match-quoted-string/task.md (64%) rename 9-regular-expressions/{11-regexp-alternation => 13-regexp-alternation}/04-match-exact-tag/solution.md (72%) rename 9-regular-expressions/{11-regexp-alternation => 13-regexp-alternation}/04-match-exact-tag/task.md (68%) create mode 100644 9-regular-expressions/13-regexp-alternation/article.md delete mode 100644 9-regular-expressions/13-regexp-multiline-mode/article.md create mode 100644 9-regular-expressions/14-regexp-lookahead-lookbehind/1-find-non-negative-integers/solution.md create mode 100644 9-regular-expressions/14-regexp-lookahead-lookbehind/1-find-non-negative-integers/task.md create mode 100644 9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/solution.md create mode 100644 9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/task.md create mode 100644 9-regular-expressions/15-regexp-catastrophic-backtracking/article.md delete mode 100644 9-regular-expressions/15-regexp-infinite-backtracking-problem/article.md create mode 100644 9-regular-expressions/16-regexp-sticky/article.md create mode 100644 9-regular-expressions/17-regexp-methods/article.md delete mode 100644 9-regular-expressions/20-regexp-unicode/article.md delete mode 100644 9-regular-expressions/21-regexp-unicode-properties/article.md delete mode 100644 9-regular-expressions/22-regexp-sticky/article.md create mode 100644 css.md diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md index 6c2a5157d..98de73575 100644 --- a/1-js/01-getting-started/1-intro/article.md +++ b/1-js/01-getting-started/1-intro/article.md @@ -12,8 +12,8 @@ Os scripts são fornecidos e executados como texto puro. Eles não precisam de p Neste aspecto, o JavaScript é muito diferente de outra linguagem chamada [Java](https://pt.wikipedia.org/wiki/Java_(linguagem_de_programação)). -```smart header="Por que JavaScript?" -Quando foi criado, inicialmente o JavaScript tinha outro nome: "LiveScript". Mas Java era muito popular naquela época, então foi decidido que posicionar uma nova linguagem como um "irmão mais novo" de Java ajudaria. +```smart header="Por que é chamado JavaScript?" +Quando o JavaScript foi criado, inicialmente tinha outro nome: "LiveScript". Mas Java era muito popular naquela época, então foi decidido que posicionar uma nova linguagem como um "irmão mais novo" de Java ajudaria. Mas à medida que ele evoluiu, o JavaScript se tornou uma linguagem totalmente independente com sua própria especificação chamada [ECMAScript] (http://en.wikipedia.org/wiki/ECMAScript), e agora ele não tem nenhuma relação com Java. ``` @@ -26,7 +26,7 @@ Interpretadores diferentes têm "codinomes" diferentes. Por exemplo: - [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- no Chrome e no Opera. - [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- no Firefox. -- ...Há outros codinomes como "Trident" e "Chakra" para diferentes versões do IE, "ChakraCore" para Microsoft Edge, "Nitro" e "SquirrelFish" para Safari, etc. +- ...Há outros codinomes como "Chakra" para o IE, "ChakraCore" para Microsoft Edge, "Nitro" e "SquirrelFish" para Safari, etc. Os termos acima são bons para lembrar, pois são usados em artigos de desenvolvedores na internet. Vamos usá-los também. Por exemplo, se "um recurso X é suportado pelo V8", então ele provavelmente funciona no Chrome e no Opera. @@ -38,7 +38,7 @@ Os interpretadores são complicados. Mas o básico é fácil. 2. Depois converte ("compila") o script para a linguagem da máquina. 3. E então o código da máquina é executado, bem rápido. -O interpretador aplica otimizações em cada etapa do processo. Ele ainda observa o script compilado enquanto ele roda, analisa os dados que passam por ele e aplica otimizações ao código da máquina com base nesse conhecimento. Quando isso é feito, os scripts são executados rapidamente. +O interpretador aplica otimizações em cada etapa do processo. Ele ainda observa o script compilado enquanto ele roda, analisa os dados que passam por ele e aplica otimizações ao código da máquina com base nesse conhecimento. ``` ## O que o JavaScript no navegador pode fazer? @@ -94,7 +94,6 @@ Isso é o que torna o JavaScript único. É por isso que é a ferramenta mais di Ao passo que planeja aprender uma nova tecnologia, é benéfico verificar suas perspectivas. Então, vamos seguir para as tendências modernas que o afetam, incluindo novas linguagens e habilidades de navegador. - ## Linguagens "sobre" JavaScript A sintaxe do JavaScript não se adapta às necessidades de todos. Pessoas diferentes querem características diferentes. @@ -108,10 +107,12 @@ Ferramentas modernas tornam a transpilação muito rápida e transparente, permi Exemplos de tais linguagens: - [CoffeeScript](http://coffeescript.org/) é um "açúcar sintático" para JavaScript. Ele introduz uma sintaxe mais curta, permitindo-nos escrever um código mais claro e preciso. Normalmente, Ruby devs gostam dele. -- [TypeScript](http://www.typescriptlang.org/) está concentrado em adicionar "dados estritos de digitação" para simplificar o desenvolvimento e suporte de sistemas complexos. É desenvolvido pela Microsoft. -- [Dart](https://www.dartlang.org/) é uma linguagem autônoma que tem seu próprio mecanismo que roda em ambientes sem navegador (como aplicativos móveis). Ela foi inicialmente oferecida pelo Google como um substituto para JavaScript, mas a partir de agora, os navegadores exigem que ela seja transpilada para JavaScript da mesma forma que as anteriores. +- [TypeScript](http://www.typescriptlang.org/) está concentrado em adicionar "estritos tipos de dados" para simplificar o desenvolvimento e suporte de sistemas complexos. É desenvolvido pela Microsoft. +- [Flow](http://flow.org/) também adiciona tipos de dados, mas de uma forma diferente. Desenvolvido pela Facebook. +- [Dart](https://www.dartlang.org/) é uma linguagem autônoma que tem seu próprio interpretador que roda em ambientes fora do navegador (como aplicativos móveis), mas também pode ser transpilada para JavaScript. Desenvolvido pela Google. +- [Brython](https://brython.info/) é um transpilador de Python para JavaScript que permite escrever aplicativos em puro Python, sem JavaScript. -Há mais. Claro que, mesmo que usemos uma dessas linguagens, também devemos saber JavaScript para entender o que estamos fazendo. +Há mais. Claro que, mesmo que usemos uma dessas linguagens transpiladas, também devemos saber JavaScript para entender o que estamos fazendo. ## Resumo diff --git a/1-js/01-getting-started/2-manuals-specifications/article.md b/1-js/01-getting-started/2-manuals-specifications/article.md index 361b970ad..8456de0f8 100644 --- a/1-js/01-getting-started/2-manuals-specifications/article.md +++ b/1-js/01-getting-started/2-manuals-specifications/article.md @@ -1,10 +1,11 @@ + # Manuais e especificações Este livro é um *tutorial*. Ele tem como objetivo lhe ajudar a aprender gradualmente a linguagem. Mas uma vez familiarizado com o básico, irá precisar de outros recursos. ## Especificação -A [Especificacão ECMA-262](https://www.ecma-international.org/publications/standards/Ecma-262.htm) contém as mais profundas, detalhadas e formalizadas informações sobre JavaScript. Ela define a linguagem. +A [Especificação ECMA-262](https://www.ecma-international.org/publications/standards/Ecma-262.htm) contém as mais profundas, detalhadas e formalizadas informações sobre JavaScript. Ela define a linguagem. Mas, estando num formato mais formal, fica difícil de entender à primeira vista. Porém, se você precisa da mais confiável fonte de informações sobre detalhes da linguagem, está no lugar certo. Contudo, não é para o uso cotidiano. @@ -12,7 +13,7 @@ Uma nova versão dessa especificação é lançada todos os anos. Entre estes la Para ler sobre as mais novas funcionalidades (*bleeding-edge features*), incluindo as que estão em fase de padronização (chamadas também de "estágio 3"), veja as suas propostas em . -E mais, se você está desenvolvendo para browsers, há outras especificações que cobrem esta demanda na [segunda parte](https://javascript.info/browser-environment) do tutorial. +E mais, se você está desenvolvendo para browsers, há outras especificações que cobrem esta demanda na [segunda parte](info:browser-environment) do tutorial. ## Manuais diff --git a/1-js/01-getting-started/3-code-editors/article.md b/1-js/01-getting-started/3-code-editors/article.md index 1915da9ef..f9fdb18cd 100644 --- a/1-js/01-getting-started/3-code-editors/article.md +++ b/1-js/01-getting-started/3-code-editors/article.md @@ -12,10 +12,8 @@ Uma IDE carrega o projeto (que pode ter muitos arquivos), permite navegação en Se você ainda não tiver selecionado uma IDE, considere as seguintes opções: -- [WebStorm](http://www.jetbrains.com/webstorm/) para desenvolvimento de front-end. A mesma empresa oferece outros editores para outras linguagens (pago). -- [Netbeans](http://netbeans.org/) (livre). - -Todas essas IDEs são multi-plataforma. +- [Visual Studio Code](https://code.visualstudio.com/) (plataforma cruzada, livre). +- [WebStorm](http://www.jetbrains.com/webstorm/) (plataforma cruzada, pago). Para Windows, há também "Visual Studio", que não deve ser confundido com "Visual Studio Code". "Visual Studio" é um editor pago e poderoso somente para Windows, bem adequado para a plataforma .NET . Uma versão gratuita é chamada [Visual Studio Community](https://www.visualstudio.com/vs/community/). @@ -33,25 +31,16 @@ Na prática, os editores leves podem ter muitos plug-ins, incluindo analisadores As seguintes opções merecem sua atenção: -- [Visual Studio Code](https://code.visualstudio.com/) (plataforma cruzada, livre) também tem muitos recursos similares a IDE. -- [Atom](https://atom.io/) (multi-plataforma, livre). -- [Sublime Text](http://www.sublimetext.com) (multi-plataforma, shareware). +- [Atom](https://atom.io/) (plataforma cruzada, livre). +- [Visual Studio Code](https://code.visualstudio.com/) (plataforma cruzada, livre). +- [Sublime Text](http://www.sublimetext.com) (plataforma cruzada, shareware). - [Notepad++](https://notepad-plus-plus.org/) (Windows, livre). - [Vim](http://www.vim.org/) e [Emacs](https://www.gnu.org/software/emacs/) também são legais se você sabe como usá-los. -## Os meus favoritos - -A preferência pessoal do autor deve ter uma IDE para projetos e um editor leve para edição de arquivo rápida e fácil. - -Eu estou usando: - -- Como uma IDE para JS -- [WebStorm](http://www.jetbrains.com/webstorm/) (Eu mudo para uma das outras ofertas do JetBrains quando uso outras linguagens) -- Como um editor de peso leve -- [Sublime Text](http://www.sublimetext.com) ou [Atom](https://atom.io/). - ## Não vamos discutir Os editores nas listas acima são aqueles que eu ou os meus amigos que eu considero bons desenvolvedores têm usado por um longo tempo e estão felizes com eles. Há outros grandes editores no nosso grande mundo. Por favor, escolha o que você mais gosta. -A escolha de um editor, como qualquer outra ferramenta, é individual e depende de seus projetos, hábitos e preferências pessoais. \ No newline at end of file +A escolha de um editor, como qualquer outra ferramenta, é individual e depende de seus projetos, hábitos e preferências pessoais. diff --git a/1-js/01-getting-started/4-devtools/article.md b/1-js/01-getting-started/4-devtools/article.md index 723430dbb..db4cae785 100644 --- a/1-js/01-getting-started/4-devtools/article.md +++ b/1-js/01-getting-started/4-devtools/article.md @@ -1,6 +1,6 @@ # Console do desenvolvedor -O código é propenso a erros. Você provavelmente cometerá erros ... Oh, do que estou falando? Você está * inevitavelmente * cometendo erros, pelo menos se você for um humano, não um [robô] (https://pt.wikipedia.org/wiki/Bender_Bending_Rodr%C3%ADguez). +O código é propenso a erros. Você provavelmente cometerá erros ... Oh, do que estou falando? Você está *inevitavelmente* cometendo erros, pelo menos se você for um humano, não um [robô] ( Mas no navegador, os usuários não vêem os erros por padrão. Assim, se algo correr mal no script, não veremos de onde está partindo e não poderemos corrigir. @@ -8,7 +8,7 @@ Para que possamos visualizar erros e obter muitas outras informações úteis so A maioria dos desenvolvedores escolhem o Chrome ou o Firefox para o desenvolvimento porque esses navegadores têm as melhores ferramentas de desenvolvedor. Outros navegadores também fornecem ferramentas de desenvolvedor, às vezes com recursos especiais, mas geralmente estão jogando "catch-up" no Chrome ou Firefox. Assim, a maioria dos desenvolvedores tem um navegador "favorito" e muda para outros se um problema é específico do navegador. -As ferramentas do desenvolvedor são potentes; elas têm muitos recursos. Para começar, vamos aprender como abri-las, olhar para erros e executar comandos JavaScript. +As ferramentas do desenvolvedor são potentes; elas têm muitos recursos. Para começar, vamos aprender como as abrir, olhar para erros e executar comandos JavaScript. ## Google Chrome @@ -29,10 +29,16 @@ O aspecto exato das ferramentas de desenvolvimento depende da sua versão do Chr - Aqui podemos ver a mensagem de erro de cor vermelha. Neste caso, o script contém um comando "lalala" desconhecido. - À direita, há um link clicável para o código-fonte `bug.html:12` com o número da linha onde o erro ocorreu. -Abaixo da mensagem de erro, há um símbolo azul `>`. Ele marca uma "linha de comando" onde podemos digitar comandos JavaScript. Pressione `key:Enter` para executá-los (`key:Shift+Enter` para introduzir comandos multi-linha). +Abaixo da mensagem de erro, há um símbolo azul `>`. Ele marca uma "linha de comando" onde podemos digitar comandos JavaScript. Pressione `key:Enter` para executá-los. Agora podemos ver erros, e isso é suficiente para começar. Voltaremos mais tarde às ferramentas de desenvolvedor e abordaremos a depuração mais profundamente no capítulo . +```smart header="Multi-line input" +Usually, when we put a line of code into the console, and then press `key:Enter`, it executes. + +To insert multiple lines, press `key:Shift+Enter`. This way one can enter long fragments of JavaScript code. +``` + ## Firefox, Edge, e outros A maioria dos outros navegadores usam `key:F12` para abrir ferramentas de desenvolvimento. @@ -49,15 +55,9 @@ Abra Preferências e vá para o painel "Avançado". Há uma caixa de seleção n Agora o `key:Cmd+Opt+C` pode alternar o console. Além disso, note que o novo item do menu superior chamado "Develop" apareceu. Ele tem muitos comandos e opções. -## Entrada multi-linha - -Normalmente, quando colocamos uma linha de código no console, e então pressionamos `key:Enter`, ele executa. - -Para inserir várias linhas, pressione `key:Shift+Enter`. - ## Resumo - As ferramentas de desenvolvedor nos permitem ver erros, executar comandos, examinar variáveis e muito mais. - Elas podem ser abertas com `key:F12` para a maioria dos navegadores no Windows. O Chrome para Mac precisa de `key:Cmd+Opt+J`, Safari: `key:Cmd+Opt+C` (precisa ser ativado primeiro). -Agora temos o ambiente pronto. Na próxima seção, chegaremos ao JavaScript. \ No newline at end of file +Agora temos o ambiente pronto. Na próxima seção, chegaremos ao JavaScript. diff --git a/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html b/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html new file mode 100644 index 000000000..ff1d871b0 --- /dev/null +++ b/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md b/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md index e69de29bb..77b3abbb5 100644 --- a/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md +++ b/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md @@ -0,0 +1,2 @@ + +[html src="index.html"] diff --git a/1-js/02-first-steps/01-hello-world/1-hello-alert/task.md b/1-js/02-first-steps/01-hello-world/1-hello-alert/task.md index bae5ec948..62ad2cc03 100644 --- a/1-js/02-first-steps/01-hello-world/1-hello-alert/task.md +++ b/1-js/02-first-steps/01-hello-world/1-hello-alert/task.md @@ -1,4 +1,4 @@ -importância: 5 +importance: 5 --- diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md index 6a5794e08..621b7aecc 100644 --- a/1-js/02-first-steps/01-hello-world/article.md +++ b/1-js/02-first-steps/01-hello-world/article.md @@ -1,6 +1,6 @@ # Olá, mundo! -O tutorial que você está lendo é sobre a core do JavaScript, que é independente de plataforma. Mais tarde, você vai aprender sobre Node.js e outras plataformas que o usam. +Esta parte do tutorial é sobre a core do JavaScript, a própria linguagem. Mas precisamos de um ambiente de trabalho para rodar nossos scripts e, como esse livro está online, o navegador é uma boa escolha. Vamos manter a quantidade de comandos específicos do navegador (como `alert`) no mínimo para que você não gaste tempo com eles se você planeja se concentrar em outro ambiente (como Node.js). Vamos focar em JavaScript no navegador na [próxima parte](/ui) do tutorial. @@ -9,7 +9,7 @@ Então, primeiro, vamos ver como anexar um script a uma página. Para ambientes ## A tag "script" -Os programas JavaScript podem ser inseridos em qualquer parte de um documento HTML com a ajuda da tag ` ``` -Aqui, `/path/to/script.js` é um caminho absoluto para o arquivo script (da raiz do site). - -Você também pode fornecer um caminho relativo a partir da página atual. Por exemplo, `src="script.js"` significaria um arquivo `"script.js"` na pasta atual. +Aqui, `/path/to/script.js` é um caminho absoluto para o arquivo script (da raiz do site). Você também pode fornecer um caminho relativo a partir da página atual. Por exemplo, `src="script.js"` significaria um arquivo `"script.js"` na pasta atual. Nós também podemos dar uma URL completa. Por exemplo: ```html - + ``` Para anexar vários scripts, use múltiplas tags: diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md index 02279dd78..3b80aea66 100644 --- a/1-js/02-first-steps/02-structure/article.md +++ b/1-js/02-first-steps/02-structure/article.md @@ -36,9 +36,10 @@ alert('Mundo') Aqui, o JavaScript interpreta a quebra de linha como um ponto-e-vírgula "implícito". Isso é chamado de [inserção automática de ponto-e-vírgula](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion). -**Na maioria dos casos, uma nova linha implica um ponto e vírgula. Mas "na maioria dos casos" não significa "sempre"! +**Na maioria dos casos, uma nova linha implica um ponto e vírgula. Mas "na maioria dos casos" não significa "sempre"!** Há casos em que uma nova linha não significa ponto e vírgula. Por exemplo: + ```js run no-beautify alert(3 + 1 @@ -93,7 +94,7 @@ Mas devem ser duas declarações separadas, não uma. Tal fusão neste caso é c Recomendamos colocar ponto e vírgula entre as frases, mesmo que estejam separadas por novas linhas. Esta regra é amplamente adotada pela comunidade. Vamos notar mais uma vez -- *é possível* deixar de fora os pontos e vírgulas na maior parte do tempo. Mas é mais seguro -- especialmente para um iniciante -- usá-los. -## Comentários +## Comentários [#code-comments] Com o passar do tempo, os programas tornam-se cada vez mais complexos. Torna-se necessário adicionar *comentários* que descrevem o que o código faz e porquê. @@ -135,11 +136,11 @@ alert('Mundo'); ``` ```smart header="Use hotkeys!" -Na maioria dos editores, uma linha de código pode ser comentada pressionando a tecla de atalho `key:Ctrl+/` para um comentário de linha única e algo como `key:Ctrl+Shift+/` -- para comentários multilinha (selecione um pedaço de código e pressione a tecla de atalho). Para Mac, tente `key:Cmd` em vez de `key:Ctrl`. +Na maioria dos editores, uma linha de código pode ser comentada pressionando a tecla de atalho `key:Ctrl+/` para um comentário de linha única e algo como `key:Ctrl+Shift+/` -- para comentários multilinha (selecione um pedaço de código e pressione a tecla de atalho). Para Mac, tente `key:Cmd` em vez de `key:Ctrl` e `key:Option` em vez de `key:Shift`. ``` ````warn header="Comentários aninhados não são suportados!" -Pode não haver `/*...*/` dentro de outro `/*...*/`. +Não pode haver `/*...*/` dentro de outro `/*...*/`. Tal código morrerá com um erro: diff --git a/1-js/02-first-steps/03-strict-mode/article.md b/1-js/02-first-steps/03-strict-mode/article.md index 1f04ee2c8..0013c5b5b 100644 --- a/1-js/02-first-steps/03-strict-mode/article.md +++ b/1-js/02-first-steps/03-strict-mode/article.md @@ -19,10 +19,10 @@ For example: ... ``` -Nós vamos aprender sobre funções, uma forma de agupar comandos, em breve. +Muito em breve, nós vamos aprender sobre funções (uma forma de agrupar comandos), assim vamos pré-anotar que `"use strict"` pode ser colocado no início de uma função. Fazer isso habilita o modo estrito apenas nessa função. Mas geralmente, as pessoas usam no script inteiro. - -Vamos apenas observar que "use strict" pode ser colocado no início da maioria dos tipos de funções em vez do script inteiro. Fazer isso habilita o modo estrito apenas nessa função. Mas geralmente, as pessoas usam no script inteiro. +````warn header="Se assegure que \"use strict\" está no topo" +Por favor, se assegure que `"use strict"` está no topo dos seus scripts, de contrário o modo estrito pode não estar ativado. O modo estrito não está ativado aqui: @@ -35,35 +35,55 @@ alert("algum código"); // modo estrito não está ativado ``` -Apenas comentários devem aparecer acima de `"use strict"`. +Apenas comentários podem aparecer acima de `"use strict"`. +```` + +```warn header="Não há forma de cancelar `use strict`" +Não existe uma diretiva como `"no use strict"` para reverter o interpretador (*engine*) para o comportamento antigo. + +Assim que entramos para o modo estrito, não podemos voltar atrás. +``` ## Console do navegador -Para o futuro, quando você usar o console do navegador para testar funcionalidades, observe que ele não "usa strict" por padrão. +Quando você usar o [console do navegador](info:devtools) para testar funcionalidades, por favor observe que ele não "usa strict" por padrão. + +As vezes, quando usar `use strict` fizer alguma diferença, você terá resultados incorretos. + +Assim, como ativar `use strict` no console? -As vezes, quando usar `use strict` faz alguma diferença, você terá resultados incorretos. +Primeiro, podemos tentar pressionar `key: Shift + Enter` para inserir várias linhas, e colocar` use strict` no topo, assim: -Mesmo se pressionarmos `key: Shift + Enter` para inserir várias linhas e colocar` use strict` no topo, isso não funcionará. Isso é por causa de como o console executa o código internamente. +```js +'use strict'; +// ...seu código + +``` + +Funciona em vários navegadores, nomeadamente Firefox and Chrome. -A maneira confiável de garantir `use strict` seria inserir o código no console da seguinte forma: +Se não funcionar, ex. num navegador antigo, existe uma maneira feia, mas confiável, de garantir `use strict`. Coloque ele dentro deste tipo de contentor (*wrapper*): ```js (function() { 'use strict'; - // ...seu código... + // ...seu código aqui... })() ``` -## Sempre "use strict" +## Devemos usar "use strict"? + +A questão pode parecer óbvia, mas não é tanto. + +Pode-se recomendar iniciar scripts com `" use strict "`... Mas sabe o que é legal? + +O JavaScript moderno suporta "classes" e "módulos" - estruturas avançadas da linguagem (vamos seguramente chegar até elas), que ativam `use strict` automaticamente. Assim, não precisamos de adicionar a diretiva `" use strict "`, quando as usamos. -Ainda precisamos cobrir as diferenças entre o modo estrito e o modo "padrão". +**Assim, por agora `" use strict "` é um convidado bem-vindo no topo dos seus scripts. Mais adiante, quando todo o seu código estiver em classes e módulos, você pode omitir** -Nos próximos capítulos, assim como nós vamos aprender novas funcinalidades, vamos aprender as diferenças entre o modo estrito e os modos padrões. Felizmente, não há muitos e eles realmente tornam nossas vidas melhores. +Por agora, nós temos de saber sobre `use strict` de um modo geral. -Por agora, de um momento geral, basta saber sobre isso: +Nos próximos capítulos, à medida que aprendermos novas funcionalidades, vamos ver as diferenças entre o modo estrito e os modos padrões. Felizmente, não há muitos e eles realmente tornam nossas vidas melhores. -1. A diretiva `" use strict "` alterna o mecanismo para o modo "moderno", alterando o comportamento de alguns recursos internos. Vamos ver os detalhes mais tarde no tutorial. -2. O modo estrito é ativado colocando `" use strict "` no topo de um script ou função. Vários recursos de idioma, como "classes" e "módulos", ativam o modo estrito automaticamente. -3. Modo estrito é suportado por todos os navegadores modernos. -4. Recomendamos sempre iniciar scripts com `" use strict "`. Todos os exemplos neste tutorial assumem o modo estrito, a menos que (muito raramente) seja especificado de outra forma. +Todos os exemplos neste tutorial assumem o modo estrito, a menos que (muito raramente) seja especificado de outra forma. diff --git a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md index 8e0595094..ce8fb6946 100644 --- a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md +++ b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md @@ -1,4 +1,4 @@ -Primeiro, a variável para o nome do nosso planeta. +## A variável para o nosso planeta Isso é simples: @@ -6,16 +6,16 @@ Isso é simples: let ourPlanetName = "Earth"; ``` -Note que poderíamos usar um nome mais curto, `planet`, mas pode não ser óbvio a que planeta se refere. É bom ser mais detalhado. Pelo menos até a variável isNotTooLong. +Note que poderíamos usar um nome mais curto, `planet`, mas pode não ser óbvio a que planeta se refere. É bom ser mais detalhado. Pelo menos até a variável naoForDemasiadoLonga. -Em segundo lugar, o nome do visitante atual: +## O nome do visitante atual ```js let currentUserName = "John"; ``` -Novamente, nós poderíamos encurtar isso para `userName` se tivermos certeza que o usuário é atual. +Novamente, nós poderíamos encurtar isso para `userName` se tivermos a certeza de que o usuário é o atual. Os editores modernos e o autocomplete facilitam a escrita de nomes longos de variáveis. Não salve neles. Um nome com 3 palavras é o suficiente. -E se o seu editor não possui autocompletar corretamente, obtenha [um novo](/code-editors). \ No newline at end of file +E se o seu editor não possui autocompletar corretamente, obtenha [um novo](/code-editors). diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md index 51eaa9f2b..51c112f09 100644 --- a/1-js/02-first-steps/04-variables/article.md +++ b/1-js/02-first-steps/04-variables/article.md @@ -1,6 +1,6 @@ # Variáveis -Na maioria das vezes, um aplicativo JavaScript precisa trabalhar com informações. Aqui estão dois exemplos: +Na maioria das vezes, um aplicativo JavaScript precisa de trabalhar com informações. Aqui estão dois exemplos: 1. Uma loja online -- a informação pode incluir mercadorias vendidas e um carrinho de compras. 2. Uma aplicação de chat -- a informação pode incluir usuários, mensagens e muito mais. @@ -12,7 +12,7 @@ Uma [variável](https://pt.wikipedia.org/wiki/Variável_(programação)) é um " Para criar uma variável em JavaScript, use a palavra-chave `let`. -A declaração abaixo cria (em outras palavras: * declara * ou * define *) uma variável com o nome "message": +A declaração abaixo cria (em outras palavras: *declara*) uma variável com o nome "message": ```js let message; @@ -35,7 +35,7 @@ let message; message = 'Olá!'; *!* -alert(message); // mostra o conteúdo variável +alert(message); // mostra o conteúdo da variável */!* ``` @@ -70,7 +70,7 @@ let user = 'John', message = 'Olá'; ``` -... Ou até mesmo no estilo "comma-first": +... Ou até mesmo no estilo "vírgula-primeiro": ```js no-beautify let user = 'John' @@ -80,8 +80,7 @@ let user = 'John' Tecnicamente, todas estas variantes fazem a mesma coisa. Então, é uma questão de gosto pessoal e estética. - -````smart header="`var` instead of `let`" +````smart header="`var` em vez de `let`" Em scripts antigos, você também pode encontrar outra palavra-chave: `var` em vez de `let`: ```js @@ -95,13 +94,13 @@ Existem diferenças sutis entre `let` e `var`, mas elas ainda não são importan ## Uma analogia da vida real -Podemos facilmente compreender o conceito de uma "variável" se a imaginarmos como uma "box" de dados, com um adesivo de nome exclusivo. +Podemos facilmente compreender o conceito de uma "variável" se a imaginarmos como uma "caixa" para dados, com um adesivo de nome exclusivo. -Por exemplo, a variável `mensagem` pode ser imaginada como uma box chamada `"message"`com o valor `"Olá"`!: +Por exemplo, a variável `mensagem` pode ser imaginada como uma caixa chamada `"message"`com o valor `"Olá"`!: ![](variable.svg) -Podemos pôr qualquer valor na box. +Podemos pôr qualquer valor na caixa. Também podemos mudá-lo quantas vezes quisermos: ```js run @@ -126,21 +125,35 @@ let hello = 'Olá Mundo!'; let message; *!* -// copiar 'Olá Mundo' do hello para message +// copiar 'Olá Mundo' de hello para message message = hello; */!* -// agora duas variáveis mantêm os mesmos dados +// agora duas variáveis contêm os mesmos dados alert(hello); // Olá Mundo! alert(message); // Olá Mundo! ``` +````warn header="Declarar duas vezes lança um erro" +Uma variável deve ser declarada apenas uma vez. + +Uma declaração repetida da mesma variável é um erro: + +```js run +let message = "Isto"; + +// um 'let' repetido conduz a um erro +let message = "Aquilo"; // SyntaxError: 'message' has already been declared (Erro-de-sintaxe: 'message' já foi declarada) +``` +Assim, devemos declarar uma variável apenas uma vez e depois fazer referência a ela sem o `let`. +```` + ```smart header="Linguagens funcionais" -É interessante notar que linguagens de programação [funcional](https://en.wikipedia.org/wiki/Functional_programming), como [Scala](http://www.scala-lang.org/) or [Erlang](http://www.erlang.org/), proibem a modificação de valores de variáveis. +É interessante notar que existem linguagens de programação [funcionais](https://en.wikipedia.org/wiki/Functional_programming), como [Scala](http://www.scala-lang.org/) ou [Erlang](http://www.erlang.org/), que proíbem a modificação de valores de variáveis. -Em tais linguagens, uma vez que o valor é armazenado "na box", ele está lá para sempre. Se precisarmos de armazenar algo mais, a linguagem nos obriga a criar uma nova box (declarar uma nova variável). Não podemos reutilizar a antiga. +Em tais linguagens, uma vez que o valor é armazenado "na caixa", ele está lá para sempre. Se precisarmos de armazenar algo mais, a linguagem nos obriga a criar uma nova caixa (declarar uma nova variável). Não podemos reutilizar a antiga. -Embora possa parecer um pouco estranho à primeira vista, estas línguas são bastante capazes de um desenvolvimento sério. Mais do que isso, há áreas como cálculos paralelos onde essa limitação confere certos benefícios. Estudar tal linguagem (mesmo que você não esteja planejando usá-la em breve) é recomendado para ampliar a mente. +Embora possa parecer um pouco estranho à primeira vista, estas linguagens são bastante capazes de um desenvolvimento sério. Mais do que isso, há áreas como cálculos paralelos onde essa limitação confere certos benefícios. Estudar alguma dessas linguagens (mesmo que você não esteja planejando usá-la em breve) é recomendado para ampliar a mente. ``` ## Nomeação de variável [#variable-naming] @@ -157,7 +170,7 @@ let userName; let test123; ``` -Quando o nome contém várias palavras, [camelCase](https://en.wikipedia.org/wiki/CamelCase) é normalmente utilizado. Isto é: as palavras vão uma após a outra, cada palavra exceto a primeira que começa com uma letra maiúscula: `myVeryLongName`. +Quando o nome contém várias palavras, o [camelCase](https://en.wikipedia.org/wiki/CamelCase) é normalmente utilizado. Isto é: as palavras vão uma após a outra, e cada palavra exceto a primeira começa com uma letra maiúscula: `myVeryLongName`. O que é interessante -- o sinal de dólar `'$'` e o sublinhado `'_'` também podem ser usados em nomes. Eles são símbolos regulares, assim como letras, sem nenhum significado especial. @@ -182,19 +195,19 @@ let my-name; // hífens '-' não são permitidos no nome Variáveis chamadas `apple` e `AppLE` são duas variáveis diferentes. ``` -````smart header="Letras não inglesas são permitidas, mas não são recomendadas" -É possível usar qualquer idioma, incluindo letras cirílicas ou até hieróglifos, como este: +````smart header="Letras não-Latin são permitidas, mas não são recomendadas" +É possível usar qualquer idioma, incluindo letras cirílicas ou até hieróglifos, como estes: ```js let имя = '...'; let 我 = '...'; ``` -Tecnicamente, não há erro aqui, tais nomes são permitidos, mas há uma tradição internacional de usar o inglês em nomes de variáveis. Mesmo que estejamos escrevendo um pequeno script, ele pode ter uma longa vida pela frente. Pessoas de outros países podem precisar lê-lo em algum momento. +Tecnicamente, não há erro aqui. Tais nomes são permitidos, mas há uma tradição internacional de usar o inglês em nomes de variáveis. Mesmo que estejamos escrevendo um pequeno script, ele pode ter uma longa vida pela frente. Pessoas de outros países podem precisar de o ler em algum momento. ```` ````warn header="Nomes reservados" -Existe uma [lista de palavras reservadas](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords), que não pode ser usada como nomes de variáveis porque elas são usadas pela própria linguagem. +Existe uma [lista de palavras reservadas](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords), que não podem ser usadas como nomes de variáveis porque elas são usadas pela própria linguagem. Por exemplo: `let`, `class`, `return`, e `function` são reservadas. @@ -208,7 +221,7 @@ let return = 5; // também não pode nomear como "return", erro! ````warn header="Uma atribuição sem `use strict`" -Normalmente, precisamos definir uma variável antes de usá-la. Mas nos velhos tempos, era tecnicamente possível criar uma variável através de uma mera atribuição do valor sem usar `let`. Isso ainda funciona se não colocarmos `use strict` em nossos scripts para manter a compatibilidade com scripts antigos. +Normalmente, precisamos definir uma variável antes de a usar. Mas nos velhos tempos, era tecnicamente possível criar uma variável através de uma mera atribuição de valor, sem usar `let`. Isso ainda funciona se não colocarmos `use strict` em nossos scripts para manter a compatibilidade com scripts antigos. ```js run no-strict // nota: nenhum "use strict" neste exemplo @@ -224,7 +237,7 @@ Esta é uma má prática e causaria um erro no modo estrito: "use strict"; *!* -num = 5; // erro: o número não está definido +num = 5; // erro: 'num' não está definido */!* ``` ```` @@ -245,7 +258,7 @@ const myBirthday = '18.04.1982'; myBirthday = '01.01.2001'; // erro, não é possível reatribuir a constante! ``` -Quando um programador é certo que uma variável nunca mudará, eles podem declará-la com `const` para garantir e comunicar claramente esse fato a todos. +Quando um programador está certo de que uma variável nunca mudará, ele pode declará-la com `const` para garantir e comunicar claramente esse fato a todos. ### Constantes maiúsculas @@ -284,17 +297,17 @@ const pageLoadTime = /* tempo necessário para carregar uma página web */; O valor de `pageLoadTime` não é conhecido antes do carregamento da página, portanto é nomeado normalmente. Mas ainda é uma constante porque não muda após a atribuição. -Em outras palavras, constantes com nomes maiúsculos são usadas apenas como pseudônimos para valores "codificação rígida". +Em outras palavras, constantes com nomes maiúsculos são usadas apenas como pseudônimos para valores de "codificação rígida". ## Nomeie as coisas como devem ser Falando em variáveis, há mais uma coisa extremamente importante. -Por favor, nomeie as suas variáveis de forma sensata. Tome tempo para pensar sobre isso. +O nome de uma variável deveria ter um significado claro e óbvio, descrevendo os dados que ela armazena. -A nomenclatura variável é uma das habilidades mais importantes e complexas em programação. Uma rápida olhada em nomes de variáveis pode revelar qual código foi escrito por um iniciante versus um desenvolvedor experiente. +A nomenclatura variável é uma das habilidades mais importantes e complexas em programação. Uma rápida olhada em nomes de variáveis pode revelar que código foi escrito por um iniciante versus um desenvolvedor experiente. -Em um projeto real, a maior parte do tempo é gasto modificando e estendendo uma base de código existente ao invés de escrever algo completamente separado do zero. Quando voltamos a algum código depois de fazer outra coisa por um tempo, é muito mais fácil encontrar informações bem rotuladas. Ou, em outras palavras, quando as variáveis têm bons nomes. +Em um projeto real, a maior parte do tempo é gasto modificando e estendendo uma base de código existente ao invés de escrever algo completamente separado do zero. Quando voltamos a algum código depois de fazer outra coisa por um tempo, é muito mais fácil encontrar informação se for bem rotulada. Ou, em outras palavras, quando as variáveis têm bons nomes. Por favor, gaste tempo pensando sobre o nome certo para uma variável antes de declará-lo. Fazê-lo irá recompensá-lo generosamente. @@ -314,7 +327,7 @@ Como resultado, suas variáveis são como caixas em que as pessoas jogam coisas Tais programadores economizam um pouco na declaração de variáveis, mas perdem dez vezes mais na depuração. -Uma variável extra é o bom, não ruim. +Uma variável extra é bom, não ruim. Os minificadores e navegadores JavaScript modernos otimizam o código o suficiente para que ele não crie problemas de desempenho. Usar variáveis diferentes para valores diferentes pode até mesmo ajudar o mecanismo a otimizar seu código. ``` @@ -323,7 +336,7 @@ Os minificadores e navegadores JavaScript modernos otimizam o código o suficien Podemos declarar variáveis para armazenar dados usando as palavras-chave `var`, `let`, ou `const`. -- `let` -- é uma declaração de variável moderna. O código deve estar em modo estrito para usar `let` no Chrome (V8). +- `let` -- é uma declaração de variável moderna. - `var` -- é uma declaração de variável da velha escola. Normalmente não a usamos de todo, mas vamos cobrir diferenças sutis de `let` no capítulo , para o caso de você precisar delas. - `const` -- é como `let`, mas o valor da variável não pode ser alterado. diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md index d84ef8ce8..a75367f1e 100644 --- a/1-js/02-first-steps/05-types/article.md +++ b/1-js/02-first-steps/05-types/article.md @@ -1,6 +1,10 @@ # Tipos de dados -Uma variável em JavaScript pode conter quaisquer dados. Uma variável pode em um momento ser uma string e em outro um número: +Uma variável em JavaScript é sempre de um certo tipo. Por exemplo, uma string ou um número. + +Há oito tipos de dados básicos em JavaScript. Aqui, vamos cobri-los em geral e nos próximos capítulos vamos falar sobre cada um deles em detalhe. + +Podemos por qualquer tipo numa variável. Por exemplo, uma variável pode em um momento ser uma string e em outro um número: ```js // nenhum erro @@ -10,8 +14,6 @@ message = 123456; As linguagens de programação que permitem tais coisas são chamadas "dinamicamente tipadas", o que significa que existem tipos de dados, mas as variáveis não estão vinculadas a nenhum deles. -Há sete tipos de dados básicos em JavaScript. Aqui, vamos cobri-los em geral e nos próximos capítulos vamos falar sobre cada um deles em detalhe. - ## Um número ```js @@ -33,12 +35,11 @@ Além dos números regulares, existem os chamados "valores numéricos especiais" alert( 1 / 0 ); // Infinito ``` - Ou apenas referi-lo directamente: + Ou apenas referi-lo diretamente: ```js run alert( Infinity ); // Infinito ``` - - `NaN` representa um erro computacional. É o resultado de uma operação matemática incorreta ou indefinida, por exemplo: ```js run @@ -63,14 +64,38 @@ Os valores numéricos especiais pertencem formalmente ao tipo "número". Claro q Veremos mais sobre como trabalhar com números no capítulo . -## Uma string +## BigInt + +In JavaScript, the "number" type cannot represent integer values larger than (253-1) (that's `9007199254740991`), or less than -(253-1) for negatives. It's a technical limitation caused by their internal representation. + +For most purposes that's quite enough, but sometimes we need really big numbers, e.g. for cryptography or microsecond-precision timestamps. + +`BigInt` type was recently added to the language to represent integers of arbitrary length. + +A `BigInt` value is created by appending `n` to the end of an integer: + +```js +// the "n" at the end means it's a BigInt +const bigInt = 1234567890123456789012345678901234567890n; +``` + +As `BigInt` numbers are rarely needed, we don't cover them here, but devoted them a separate chapter . Read it when you need such big numbers. + + +```smart header="Compatibility issues" +Right now, `BigInt` is supported in Firefox/Chrome/Edge/Safari, but not in IE. +``` + +You can check [*MDN* BigInt compatibility table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) to know which versions of a browser are supported. + +## String Uma string em JavaScript deve estar entre aspas. ```js let str = "Olá"; let str2 = 'Aspas simples também são ok'; -let phrase = `pode incorporar ${str}`; +let phrase = `pode incorporar outra ${str}`; ``` Em JavaScript, existem 3 tipos de citações. @@ -79,7 +104,7 @@ Em JavaScript, existem 3 tipos de citações. 2. Aspas simples: `'Olá'`. 3. Backticks: `Olá`. -Aspas duplas e simples são citações "simples". Não há diferença entre elas em JavaScript. +Aspas duplas e simples são citações "simples". Não há praticamente diferença entre elas em JavaScript. Backticks são citações de "funcionalidade estendida". Eles nos permitem incorporar variáveis e expressões em uma string envolvendo-as em `$ {…}`, por exemplo: @@ -96,17 +121,16 @@ alert( `o resultado é *!*${1 + 2}*/!*` ); // o resultado é 3 A expressão dentro de `${…}` é avaliada e o resultado torna-se uma parte da string. Podemos colocar qualquer coisa lá: uma variável como `name` ou uma expressão aritmética como `1 + 2` ou algo mais complexo. Por favor, note que isso só pode ser feito com backticks. Outras citações não têm esta funcionalidade de incorporação! - ```js run alert( "o resultado é ${1 + 2}" ); // o resultado é ${1 + 2} (aspas duplas não fazem nada) ``` Abordaremos as strings mais detalhadamente no capítulo . -```smart header="Não há nenhum tipo de *caractere*." -Em algumas linguagens, existe um tipo especial de "caractere" para um único caractere. Por exemplo, na linguagem C e em Java é `char`. +```smart header="Não há nenhum tipo *caractere*." +Em algumas linguagens, existe um tipo especial "caractere" para um único caractere. Por exemplo, na linguagem C e em Java é chamado `char`. -Em JavaScript, não existe tal tipo. Existe apenas um tipo: `string`. Uma string pode consistir de apenas um caractere ou muitos deles. +Em JavaScript, não existe tal tipo. Existe apenas um tipo: `string`. Uma string pode consistir de zero caracteres (ser vazia), apenas um caractere ou muitos deles. ``` ## Um booleano (tipo lógico) @@ -118,7 +142,7 @@ Este tipo é comumente usado para armazenar valores de sim/não: `true` signific Por exemplo: ```js -let nameFieldChecked = true; // sim, o campo do nome é verificado +let nameFieldChecked = true; // sim, o campo nome é verificado let ageFieldChecked = false; // não, o campo idade não é verificado ``` @@ -146,7 +170,7 @@ Em JavaScript, `null` não é uma "referência a um objeto não-existente" ou um É apenas um valor especial que representa "nada", "vazio" ou "valor desconhecido". -O código acima declara que `age` é desconhecido ou vazio por alguma razão. +O código acima declara que `age` é desconhecido. ## O valor "undefined" @@ -154,33 +178,36 @@ O valor especial `undefined` também se diferencia. Faz um tipo próprio, tal co O significado de `undefined` é "o valor não é atribuído". -Se uma vaiável é declarada, mas não atribuida, então seu valor é `undefined`: +Se uma variável é declarada, mas não atribuída, então seu valor é `undefined`: ```js run -let x; +let age; alert(x); // mostra "undefined" ``` -Tecnicamente, é possível atribuir `undefined` a qualquer variável: +Tecnicamente, é possível explicitamente atribuir `undefined` a qualquer variável: ```js run -let x = 123; +let age = 100; -x = undefined; +// altera o valor para 'undefined' +age = undefined; -alert(x); // "undefined" +alert(age); // "undefined" ``` -...mas não recomendamos fazer isso. Normalmente, usamos `null` para atribuir um valor "vazio" ou "desconhecido" a uma variável, e usamos `undefined` para verificações como ver se uma variável foi atribuída. +...mas não recomendamos fazer isso. Normalmente, usamos `null` para atribuir um valor "vazio" ou "desconhecido" a uma variável, enquanto `undefined` é reservado como um valor por defeito inicial para coisas não atribuídas. ## Objetos e Símbolos O tipo `object` é especial. -Todos os outros tipos são chamados de "primitivos" porque seus valores podem conter apenas uma única coisa (seja uma string ou um número ou qualquer outro). Por outro lado, os objetos são usados para armazenar coleções de dados e entidades mais complexas. Nós vamos lidar com eles mais adiante no capítulo depois que aprendermos mais sobre primitivos. +Todos os outros tipos são chamados de "primitivos" porque seus valores podem conter apenas uma única coisa (seja ela uma string, ou um número ou qualquer outra). Por outro lado, os objetos são usados para armazenar coleções de dados e entidades mais complexas. -O tipo `symbol` é usado para criar identificadores únicos para objetos. Nós temos que mencioná-lo aqui para completude, mas é melhor estudar este tipo após os objetos. +Por serem tão importantes, os objetos merecem um tratamento especial. Nós vamos lidar com eles no capítulo , depois que aprendermos mais sobre primitivos. + +O tipo `symbol` é usado para criar identificadores únicos para objetos. Nós o temos que mencionar aqui para completude, mas também adiar os seus detalhes até sabermos sobre objetos. ## The typeof operator [#type-typeof] @@ -200,6 +227,8 @@ typeof undefined // "undefined" typeof 0 // "number" +typeof 10n // "bigint" + typeof true // "boolean" typeof "foo" // "string" @@ -221,26 +250,27 @@ typeof alert // "function" (3) As três últimas linhas podem precisar de explicações adicionais: -1. `Math` é um objeto embutido que fornece operações matemáticas. Nós o aprenderemos no capítulo . Aqui, ele serve apenas como um exemplo de um objeto. -2. O resultado de `typeof null` é `"object"`. Isso é errado. É um erro oficialmente reconhecido em `typeof`, mantido para compatibilidade. Naturalmente, `null` não é um objeto. É um valor especial com um tipo separado próprio. Assim, outra vez, este é um erro na linguagem. -3. O resultado de `typeof alert` é `"function"`, porque `alert` é uma função da linguagem. Vamos estudar as funções nos próximos capítulos onde veremos que não há nenhum tipo de "função" especial em JavaScript. As funções pertencem ao tipo de objecto. Mas o `typeof` trata-as de forma diferente. Formalmente, é incorrecto, mas muito conveniente na prática. +1. `Math` é um objeto embutido que fornece operações matemáticas. Nós o vamos aprender no capítulo . Aqui, ele serve apenas como um exemplo de um objeto. +2. O resultado de `typeof null` é `"object"`. É um erro oficialmente reconhecido no comportamento de `typeof` e mantido para compatibilidade. Naturalmente, `null` não é um objeto. É um valor especial com um tipo separado próprio. +3. O resultado de `typeof alert` é `"function"`, porque `alert` é uma função. Vamos estudar as funções nos próximos capítulos onde veremos também que não há nenhum tipo especial "função" em JavaScript. As funções pertencem ao tipo objecto. Mas o `typeof` as trata de forma diferente, retornando `"function"`. Isto, também vem dos primeiros dias do JavaScript. Tecnicamente, é incorreto, mas muito conveniente na prática. ## Resumo -Existem 7 tipos básicos em JavaScript. +Existem 8 tipos básicos em JavaScript. -- `number` para números de qualquer tipo: inteiro ou ponto flutuante. -- `string` para cordas. Uma cadeia de caracteres pode ter um ou mais caracteres, não há nenhum tipo de caractere único separado. +- `number` para números de qualquer tipo: inteiro ou ponto flutuante; inteiros estão limitados a ±(253-1). +- `bigint` é para números inteiros de comprimento arbitrário. +- `string` para cadeias-de-caracteres. Uma *string* pode ter zero ou mais caracteres, não há nenhum tipo de caractere único separado. - `boolean` para `true`/`false`. - `null` para valores desconhecidos -- um tipo autônomo que tem um único valor `null`. - `undefined` para valores não atribuídos -- um tipo autônomo que tem um único valor `undefined`. - `object` para estruturas de dados mais complexas. - `symbol` para identificadores exclusivos. -O operador `typeof` nos permite ver qual tipo é armazenado em uma variável. +O operador `typeof` nos permite ver que tipo está armazenado em uma variável. - Duas formas: `typeof x` ou `typeof(x)`. - Retorna uma string com o nome do tipo, como `"string"`. - Para `null` retorna `"object"` -- isso é um erro na linguagem, não é realmente um objeto. -Nos próximos capítulos, nos concentraremos nos valores primitivos e, uma vez familiarizados com eles, passaremos para os objetos. +Nos próximos capítulos, nos vamos concentrar nos valores primitivos e, uma vez familiarizados com eles, passaremos para os objetos. diff --git a/1-js/02-first-steps/06-alert-prompt-confirm/article.md b/1-js/02-first-steps/06-alert-prompt-confirm/article.md index 25bf72482..ef0f333cb 100644 --- a/1-js/02-first-steps/06-alert-prompt-confirm/article.md +++ b/1-js/02-first-steps/06-alert-prompt-confirm/article.md @@ -4,7 +4,7 @@ As we'll be using the browser as our demo environment, let's see a couple of fun ## alert -This one we've seen already. It shows a message and waits for the user to presses "OK". +This one we've seen already. It shows a message and waits for the user to press "OK". For example: @@ -31,7 +31,7 @@ It shows a modal window with a text message, an input field for the visitor, and : An optional second parameter, the initial value for the input field. ```smart header="The square brackets in syntax `[...]`" -The square brackets around `default` in the syntax above denote that the parameter as optional, not required. +The square brackets around `default` in the syntax above denote that the parameter is optional, not required. ``` The visitor can type something in the prompt input field and press OK. Then we get that text in the `result`. Or they can cancel the input by pressing Cancel or hitting the `key:Esc` key, then we get `null` as the `result`. diff --git a/1-js/02-first-steps/07-type-conversions/article.md b/1-js/02-first-steps/07-type-conversions/article.md index e9abb0add..cf97b3307 100644 --- a/1-js/02-first-steps/07-type-conversions/article.md +++ b/1-js/02-first-steps/07-type-conversions/article.md @@ -1,160 +1,150 @@ -# Tipo Conversões +# Type Conversions -Na maioria das vezes, os operadores e as funções convertem automaticamente os valores dados a eles para o tipo correto. +Most of the time, operators and functions automatically convert the values given to them to the right type. -Por exemplo, o `alert` converte automaticamente qualquer valor para uma string para mostrá-lo. Operações matemáticas convertem valores em números. +For example, `alert` automatically converts any value to a string to show it. Mathematical operations convert values to numbers. -Há também casos em que precisamos explicitamente converter um valor para o tipo esperado. +There are also cases when we need to explicitly convert a value to the expected type. ```smart header="Not talking about objects yet" -Neste capítulo, não cobriremos objectos. Em vez disso, estudaremos os primitivos primeiro. Mais tarde, depois de aprendermos sobre objetos, veremos como a conversão de objetos funciona no capítulo . +In this chapter, we won't cover objects. For now we'll just be talking about primitives. + +Later, after we learn about objects, in the chapter we'll see how objects fit in. ``` -## Para String +## String Conversion + +String conversion happens when we need the string form of a value. -A conversão para strings acontece quando precisamos da forma de string de um valor. +For example, `alert(value)` does it to show the value. -Por exemplo, `alert(value)` faz isso para mostrar o valor. +We can also call the `String(value)` function to convert a value to a string: -Nós também podemos chamar a função `String(value)` para converter um valor em uma string: ```js run let value = true; -alert(typeof value); // booleano +alert(typeof value); // boolean *!* -value = String(value); // agora value é uma string "true" +value = String(value); // now value is a string "true" alert(typeof value); // string */!* ``` -A conversão de strings é mais óbvia. Uma `false` torna-se `"false"`, `null` torna-se `"null"`, etc. +String conversion is mostly obvious. A `false` becomes `"false"`, `null` becomes `"null"`, etc. -## Para Número +## Numeric Conversion -A conversão numérica acontece automaticamente em funções e expressões matemáticas. +Numeric conversion happens in mathematical functions and expressions automatically. -Por exemplo, quando a divisão `/` é aplicada para não-numeros: +For example, when division `/` is applied to non-numbers: ```js run -alert( "6" / "2" ); // 3, strings são convertidas para números +alert( "6" / "2" ); // 3, strings are converted to numbers ``` -Podemos usar a função `Number(value)` para converter explicitamente um `value` para um número: +We can use the `Number(value)` function to explicitly convert a `value` to a number: ```js run let str = "123"; alert(typeof str); // string -let num = Number(str); // torna-se um número 123 - -alert(typeof num); // número +let num = Number(str); // becomes a number 123 +alert(typeof num); // number ``` -A conversão explícita é normalmente necessária quando lemos um valor de uma fonte baseada em string como um formulário de texto, mas esperamos que um número seja inserido. +Explicit conversion is usually required when we read a value from a string-based source like a text form but expect a number to be entered. -Se a cadeia não for um número válido, o resultado de tal conversão é `NaN'. Por exemplo: +If the string is not a valid number, the result of such a conversion is `NaN`. For instance: ```js run -let age = Number("uma string arbitrária em vez de um número"); +let age = Number("an arbitrary string instead of a number"); -alert(age); // NaN, conversão falhou +alert(age); // NaN, conversion failed ``` -Regras de conversão numéricas: +Numeric conversion rules: -| Valor | Torna-se... | +| Value | Becomes... | |-------|-------------| |`undefined`|`NaN`| |`null`|`0`| |true and false | `1` and `0` | -| `string` | Espaços em branco do ínicio e fim são removidos. Se a string restante estiver vazia, o resultado é `0`. Casa contrário, o número é "lido" a partir da string. Um erro dá `NaN`. | +| `string` | Whitespaces from the start and end are removed. If the remaining string is empty, the result is `0`. Otherwise, the number is "read" from the string. An error gives `NaN`. | -Exemplos: +Examples: ```js run alert( Number(" 123 ") ); // 123 -alert( Number("123z") ); // NaN (erro ao ler um número em "z") +alert( Number("123z") ); // NaN (error reading a number at "z") alert( Number(true) ); // 1 alert( Number(false) ); // 0 ``` -Por favor note que `null` e `undefined` se comportam diferente aqui: `null` torna-se zero enquanto `undefined` torna-se `NaN`. +Please note that `null` and `undefined` behave differently here: `null` becomes zero while `undefined` becomes `NaN`. -````smart header="Adição '+' concatenações de strings" -Quase todas as operações matemáticas convertem valores em números. Uma exceção notável é a adição `+`. Se um dos valores adicionados é uma string, a outra também é convertida para uma string. +Most mathematical operators also perform such conversion, we'll see that in the next chapter. -Então, ele concatena (junta-se a eles): +## Boolean Conversion -```js run -alert( 1 + '2' ); // '12' (string para a direita) -alert( '1' + 2 ); // '12' (string para a esquerda) -``` +Boolean conversion is the simplest one. -Isso só acontece quando pelo menos um dos argumentos é uma string. Caso contrário, os valores são convertidos em números. -```` +It happens in logical operations (later we'll meet condition tests and other similar things) but can also be performed explicitly with a call to `Boolean(value)`. -## Para Booleano +The conversion rule: -A conversão booleana é a mais simples. +- Values that are intuitively "empty", like `0`, an empty string, `null`, `undefined`, and `NaN`, become `false`. +- Other values become `true`. -Isso acontece em operações lógicas (mais tarde vamos encontrar testes de condição e outras coisas similares), mas também pode ser feito explicitamente com uma chamada para `Boolean(value)`. - -A regra de conversão: - -- Valores que são intuitivamente "vazios", como `0`, uma string vazia, `null`, `undefined`, e `NaN`, tornam-se `false`. -- Outros valores tornam-se `true`. - -Por exemplo: +For instance: ```js run alert( Boolean(1) ); // true alert( Boolean(0) ); // false -alert( Boolean("olá") ); // true +alert( Boolean("hello") ); // true alert( Boolean("") ); // false ``` -````warn header="Por favor note: a string com `\"0\"` é `true`" -Algumas linguagens (especificamente PHP) tratam `"0"` como `false`. Mas em JavaScript, uma string não vazia é sempre `true`. +````warn header="Please note: the string with zero `\"0\"` is `true`" +Some languages (namely PHP) treat `"0"` as `false`. But in JavaScript, a non-empty string is always `true`. ```js run alert( Boolean("0") ); // true -alert( Boolean(" ") ); // espaços, também true (qualquer string não vaiza é true) +alert( Boolean(" ") ); // spaces, also true (any non-empty string is true) ``` ```` +## Summary -## Resumo +The three most widely used type conversions are to string, to number, and to boolean. -As três conversões de tipo mais usadas são para string, para número e para booleano. +**`String Conversion`** -- Occurs when we output something. Can be performed with `String(value)`. The conversion to string is usually obvious for primitive values. -**`Para String`** -- Ocorre quando produzimos algo. Pode ser executado com `String(value)`. A conversão para string é geralmente óbvia para valores primitivos. +**`Numeric Conversion`** -- Occurs in math operations. Can be performed with `Number(value)`. -**`Para Número`** -- Ocorre em operações matemáticas. Pode ser executado com `Number(value)`. +The conversion follows the rules: -Regras de conversão numéricas: - -| Valor | Torna-se... | +| Value | Becomes... | |-------|-------------| |`undefined`|`NaN`| |`null`|`0`| -|true and false | `1` and `0` | -| `string` | Espaços em branco do ínicio e fim são removidos. Se a string restante estiver vazia, o resultado é `0`. Casa contrário, o número é "lido" a partir da string. Um erro dá `NaN`. | +|true / false | `1 / 0` | +| `string` | The string is read "as is", whitespaces from both sides are ignored. An empty string becomes `0`. An error gives `NaN`. | -**`Para Booleano`** -- Ocorre em operações lógicas. Pode ser executado com `Boolean(value)`. +**`Boolean Conversion`** -- Occurs in logical operations. Can be performed with `Boolean(value)`. -Segue as regras: +Follows the rules: -| Valor | Torna-se... | +| Value | Becomes... | |-------|-------------| |`0`, `null`, `undefined`, `NaN`, `""` |`false`| -|qualquer outro valor| `true` | +|any other value| `true` | -A maioria destas regras são fáceis de entender e memorizar. As exceções notáveis onde as pessoas normalmente cometem erros são: +Most of these rules are easy to understand and memorize. The notable exceptions where people usually make mistakes are: -- `undefined` is `NaN` como um número, não `0`. -- `"0"` e strings com espaço apenas `" "` são verdadeiras como booleanas. +- `undefined` is `NaN` as a number, not `0`. +- `"0"` and space-only strings like `" "` are true as a boolean. -Objetos não são abordados aqui. Voltaremos a eles mais tarde no capítulo que é dedicado exclusivamente a objetos, depois de aprendermos coisas mais básicas sobre JavaScript. +Objects aren't covered here. We'll return to them later in the chapter that is devoted exclusively to objects after we learn more basic things about JavaScript. diff --git a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md new file mode 100644 index 000000000..9a8411fbe --- /dev/null +++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md @@ -0,0 +1,26 @@ + +```js no-beautify +"" + 1 + 0 = "10" // (1) +"" - 1 + 0 = -1 // (2) +true + false = 1 +6 / "3" = 2 +"2" * "3" = 6 +4 + 5 + "px" = "9px" +"$" + 4 + 5 = "$45" +"4" - 2 = 2 +"4px" - 2 = NaN +7 / 0 = Infinity +" -9 " + 5 = " -9 5" // (3) +" -9 " - 5 = -14 // (4) +null + 1 = 1 // (5) +undefined + 1 = NaN // (6) +" \t \n" - 2 = -2 // (7) +``` + +1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied. +2. The subtraction `-` (like most math operations) only works with numbers, it converts an empty string `""` to `0`. +3. The addition with a string appends the number `5` to the string. +4. The subtraction always converts to numbers, so it makes `" -9 "` a number `-9` (ignoring spaces around it). +5. `null` becomes `0` after the numeric conversion. +6. `undefined` becomes `NaN` after the numeric conversion. +7. Space characters, are trimmed off string start and end when a string is converted to a number. Here the whole string consists of space characters, such as `\t`, `\n` and a "regular" space between them. So, similarly to an empty string, it becomes `0`. diff --git a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md new file mode 100644 index 000000000..930c71514 --- /dev/null +++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md @@ -0,0 +1,27 @@ +importance: 5 + +--- + +# Type conversions + +What are results of these expressions? + +```js no-beautify +"" + 1 + 0 +"" - 1 + 0 +true + false +6 / "3" +"2" * "3" +4 + 5 + "px" +"$" + 4 + 5 +"4" - 2 +"4px" - 2 +7 / 0 +" -9 " + 5 +" -9 " - 5 +null + 1 +undefined + 1 +" \t \n" - 2 +``` + +Think well, write down and then compare with the answer. diff --git a/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md b/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md new file mode 100644 index 000000000..209a0702c --- /dev/null +++ b/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md @@ -0,0 +1,32 @@ +The reason is that prompt returns user input as a string. + +So variables have values `"1"` and `"2"` respectively. + +```js run +let a = "1"; // prompt("First number?", 1); +let b = "2"; // prompt("Second number?", 2); + +alert(a + b); // 12 +``` + +What we should do is to convert strings to numbers before `+`. For example, using `Number()` or prepending them with `+`. + +For example, right before `prompt`: + +```js run +let a = +prompt("First number?", 1); +let b = +prompt("Second number?", 2); + +alert(a + b); // 3 +``` + +Or in the `alert`: + +```js run +let a = prompt("First number?", 1); +let b = prompt("Second number?", 2); + +alert(+a + +b); // 3 +``` + +Using both unary and binary `+` in the latest code. Looks funny, doesn't it? diff --git a/1-js/02-first-steps/08-operators/4-fix-prompt/task.md b/1-js/02-first-steps/08-operators/4-fix-prompt/task.md new file mode 100644 index 000000000..b3ea4a3a3 --- /dev/null +++ b/1-js/02-first-steps/08-operators/4-fix-prompt/task.md @@ -0,0 +1,18 @@ +importance: 5 + +--- + +# Fix the addition + +Here's a code that asks the user for two numbers and shows their sum. + +It works incorrectly. The output in the example below is `12` (for default prompt values). + +Why? Fix it. The result should be `3`. + +```js run +let a = prompt("First number?", 1); +let b = prompt("Second number?", 2); + +alert(a + b); // 12 +``` diff --git a/1-js/02-first-steps/08-operators/article.md b/1-js/02-first-steps/08-operators/article.md index 74b27e871..45b1f3426 100644 --- a/1-js/02-first-steps/08-operators/article.md +++ b/1-js/02-first-steps/08-operators/article.md @@ -1,8 +1,8 @@ -# Operators +# Basic operators, maths We know many operators from school. They are things like addition `+`, multiplication `*`, subtraction `-`, and so on. -In this chapter, we'll concentrate on aspects of operators that are not covered by school arithmetic. +In this chapter, we’ll start with simple operators, then concentrate on JavaScript-specific aspects, not covered by school arithmetic. ## Terms: "unary", "binary", "operand" @@ -26,11 +26,57 @@ Before we move on, let's grasp some common terminology. alert( y - x ); // 2, binary minus subtracts values ``` - Formally, we're talking about two different operators here: the unary negation (single operand: reverses the sign) and the binary subtraction (two operands: subtracts). + Formally, in the examples above we have two different operators that share the same symbol: the negation operator, a unary operator that reverses the sign, and the subtraction operator, a binary operator that subtracts one number from another. -## String concatenation, binary + +## Maths -Now, let's see special features of JavaScript operators that are beyond school arithmetics. +The following math operations are supported: + +- Addition `+`, +- Subtraction `-`, +- Multiplication `*`, +- Division `/`, +- Remainder `%`, +- Exponentiation `**`. + +The first four are straightforward, while `%` and `**` need a few words about them. + +### Remainder % + +The remainder operator `%`, despite its appearance, is not related to percents. + +The result of `a % b` is the [remainder](https://en.wikipedia.org/wiki/Remainder) of the integer division of `a` by `b`. + +For instance: + +```js run +alert( 5 % 2 ); // 1, a remainder of 5 divided by 2 +alert( 8 % 3 ); // 2, a remainder of 8 divided by 3 +``` + +### Exponentiation ** + +The exponentiation operator `a ** b` multiplies `a` by itself `b` times. + +For instance: + +```js run +alert( 2 ** 2 ); // 4 (2 multiplied by itself 2 times) +alert( 2 ** 3 ); // 8 (2 * 2 * 2, 3 times) +alert( 2 ** 4 ); // 16 (2 * 2 * 2 * 2, 4 times) +``` + +Mathematically, the exponentiation is defined for non-integer numbers as well. For example, a square root is an exponentiation by `1/2`: + +```js run +alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root) +alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root) +``` + + +## String concatenation with binary + + +Let's meet features of JavaScript operators that are beyond school arithmetics. Usually, the plus operator `+` sums numbers. @@ -41,7 +87,7 @@ let s = "my" + "string"; alert(s); // mystring ``` -Note that if one of the operands is a string, the other one is converted to a string too. +Note that if any of the operands is a string, then the other one is converted to a string too. For example: @@ -50,22 +96,28 @@ alert( '1' + 2 ); // "12" alert( 2 + '1' ); // "21" ``` -See, it doesn't matter whether the first operand is a string or the second one. The rule is simple: if either operand is a string, the other one is converted into a string as well. - -However, note that operations run from left to right. If there are two numbers followed by a string, the numbers will be added before being converted to a string: +See, it doesn't matter whether the first operand is a string or the second one. +Here's a more complex example: ```js run alert(2 + 2 + '1' ); // "41" and not "221" ``` -String concatenation and conversion is a special feature of the binary plus `+`. Other arithmetic operators work only with numbers and always convert their operands to numbers. +Here, operators work one after another. The first `+` sums two numbers, so it returns `4`, then the next `+` adds the string `1` to it, so it's like `4 + '1' = 41`. + +```js run +alert('1' + 2 + 2); // "122" and not "14" +``` +Here, the first operand is a string, the compiler treats the other two operands as strings too. The `2` gets concatenated to `'1'`, so it's like `'1' + 2 = "12"` and `"12" + 2 = "122"`. + +The binary `+` is the only operator that supports strings in such a way. Other arithmetic operators work only with numbers and always convert their operands to numbers. -For instance, subtraction and division: +Here's the demo for subtraction and division: ```js run -alert( 2 - '1' ); // 1 -alert( '6' / '2' ); // 3 +alert( 6 - '2' ); // 4, converts '2' to a number +alert( '6' / '2' ); // 3, converts both operands to numbers ``` ## Numeric conversion, unary + @@ -93,9 +145,7 @@ alert( +"" ); // 0 It actually does the same thing as `Number(...)`, but is shorter. -The need to convert strings to numbers arises very often. For example, if we are getting values from HTML form fields, they are usually strings. - -What if we want to sum them? +The need to convert strings to numbers arises very often. For example, if we are getting values from HTML form fields, they are usually strings. What if we want to sum them? The binary plus would add them as strings: @@ -127,30 +177,31 @@ Why are unary pluses applied to values before the binary ones? As we're going to ## Operator precedence -If an expression has more than one operator, the execution order is defined by their *precedence*, or, in other words, the implicit priority order of operators. +If an expression has more than one operator, the execution order is defined by their *precedence*, or, in other words, the default priority order of operators. From school, we all know that the multiplication in the expression `1 + 2 * 2` should be calculated before the addition. That's exactly the precedence thing. The multiplication is said to have *a higher precedence* than the addition. -Parentheses override any precedence, so if we're not satisfied with the implicit order, we can use them to change it. For example: `(1 + 2) * 2`. +Parentheses override any precedence, so if we're not satisfied with the default order, we can use them to change it. For example, write `(1 + 2) * 2`. There are many operators in JavaScript. Every operator has a corresponding precedence number. The one with the larger number executes first. If the precedence is the same, the execution order is from left to right. -Here's an extract from the [precedence table](https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence) (you don't need to remember this, but note that unary operators are higher than corresponding binary ones): +Here's an extract from the [precedence table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) (you don't need to remember this, but note that unary operators are higher than corresponding binary ones): | Precedence | Name | Sign | |------------|------|------| | ... | ... | ... | -| 16 | unary plus | `+` | -| 16 | unary negation | `-` | -| 14 | multiplication | `*` | -| 14 | division | `/` | +| 17 | unary plus | `+` | +| 17 | unary negation | `-` | +| 16 | exponentiation | `**` | +| 15 | multiplication | `*` | +| 15 | division | `/` | | 13 | addition | `+` | | 13 | subtraction | `-` | | ... | ... | ... | | 3 | assignment | `=` | | ... | ... | ... | -As we can see, the "unary plus" has a priority of `16` which is higher than the `13` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition. +As we can see, the "unary plus" has a priority of `17` which is higher than the `13` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition. ## Assignment @@ -164,24 +215,11 @@ let x = 2 * 2 + 1; alert( x ); // 5 ``` -It is possible to chain assignments: - -```js run -let a, b, c; - -*!* -a = b = c = 2 + 2; -*/!* - -alert( a ); // 4 -alert( b ); // 4 -alert( c ); // 4 -``` +### Assignment = returns a value -Chained assignments evaluate from right to left. First, the rightmost expression `2 + 2` is evaluated and then assigned to the variables on the left: `c`, `b` and `a`. At the end, all the variables share a single value. +The fact of `=` being an operator, not a "magical" language construct has an interesting implication. -````smart header="The assignment operator `\"=\"` returns a value" -An operator always returns a value. That's obvious for most of them like addition `+` or multiplication `*`. But the assignment operator follows this rule too. +Most operators in JavaScript return a value. That's obvious for `+` and `-`, but also true for `=`. The call `x = value` writes the `value` into `x` *and then returns it*. @@ -199,51 +237,76 @@ alert( a ); // 3 alert( c ); // 0 ``` -In the example above, the result of `(a = b + 1)` is the value which is assigned to `a` (that is `3`). It is then used to subtract from `3`. +In the example above, the result of expression `(a = b + 1)` is the value which was assigned to `a` (that is `3`). It is then used for further evaluations. -Funny code, isn't it? We should understand how it works, because sometimes we see it in 3rd-party libraries, but shouldn't write anything like that ourselves. Such tricks definitely don't make code clearer or readable. -```` +Funny code, isn't it? We should understand how it works, because sometimes we see it in JavaScript libraries. -## Remainder % +Although, please don't write the code like that. Such tricks definitely don't make code clearer or readable. -The remainder operator `%`, despite its appearance, is not related to percents. +### Chaining assignments -The result of `a % b` is the remainder of the integer division of `a` by `b`. - -For instance: +Another interesting feature is the ability to chain assignments: ```js run -alert( 5 % 2 ); // 1 is a remainder of 5 divided by 2 -alert( 8 % 3 ); // 2 is a remainder of 8 divided by 3 -alert( 6 % 3 ); // 0 is a remainder of 6 divided by 3 +let a, b, c; + +*!* +a = b = c = 2 + 2; +*/!* + +alert( a ); // 4 +alert( b ); // 4 +alert( c ); // 4 ``` -## Exponentiation ** +Chained assignments evaluate from right to left. First, the rightmost expression `2 + 2` is evaluated and then assigned to the variables on the left: `c`, `b` and `a`. At the end, all the variables share a single value. -The exponentiation operator `**` is a recent addition to the language. +Once again, for the purposes of readability it's better to split such code into few lines: -For a natural number `b`, the result of `a ** b` is `a` multiplied by itself `b` times. +```js +c = 2 + 2; +b = c; +a = c; +``` +That's easier to read, especially when eye-scanning the code fast. -For instance: +## Modify-in-place + +We often need to apply an operator to a variable and store the new result in that same variable. + +For example: + +```js +let n = 2; +n = n + 5; +n = n * 2; +``` + +This notation can be shortened using the operators `+=` and `*=`: ```js run -alert( 2 ** 2 ); // 4 (2 * 2) -alert( 2 ** 3 ); // 8 (2 * 2 * 2) -alert( 2 ** 4 ); // 16 (2 * 2 * 2 * 2) +let n = 2; +n += 5; // now n = 7 (same as n = n + 5) +n *= 2; // now n = 14 (same as n = n * 2) + +alert( n ); // 14 ``` -The operator works for non-integer numbers as well. +Short "modify-and-assign" operators exist for all arithmetical and bitwise operators: `/=`, `-=`, etc. -For instance: +Such operators have the same precedence as a normal assignment, so they run after most other calculations: ```js run -alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root, that's maths) -alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root) +let n = 2; + +n *= 3 + 5; + +alert( n ); // 16 (right part evaluated first, same as n *= 8) ``` ## Increment/decrement - + Increasing or decreasing a number by one is among the most common numerical operations. @@ -253,14 +316,14 @@ So, there are special operators for it: ```js run no-beautify let counter = 2; - counter++; // works the same as counter = counter + 1, but is shorter + counter++; // works the same as counter = counter + 1, but is shorter alert( counter ); // 3 ``` - **Decrement** `--` decreases a variable by 1: ```js run no-beautify let counter = 2; - counter--; // works the same as counter = counter - 1, but is shorter + counter--; // works the same as counter = counter - 1, but is shorter alert( counter ); // 1 ``` @@ -370,41 +433,7 @@ The list of operators: - RIGHT SHIFT ( `>>` ) - ZERO-FILL RIGHT SHIFT ( `>>>` ) -These operators are used very rarely. To understand them, we need to delve into low-level number representation and it would not be optimal to do that right now, especially since we won't need them any time soon. If you're curious, you can read the [Bitwise Operators](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) article on MDN. It would be more practical to do that when a real need arises. - -## Modify-in-place - -We often need to apply an operator to a variable and store the new result in that same variable. - -For example: - -```js -let n = 2; -n = n + 5; -n = n * 2; -``` - -This notation can be shortened using the operators `+=` and `*=`: - -```js run -let n = 2; -n += 5; // now n = 7 (same as n = n + 5) -n *= 2; // now n = 14 (same as n = n * 2) - -alert( n ); // 14 -``` - -Short "modify-and-assign" operators exist for all arithmetical and bitwise operators: `/=`, `-=`, etc. - -Such operators have the same precedence as a normal assignment, so they run after most other calculations: - -```js run -let n = 2; - -n *= 3 + 5; - -alert( n ); // 16 (right part evaluated first, same as n *= 8) -``` +These operators are used very rarely, when we need to fiddle with numbers on the very lowest (bitwise) level. 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 are useful. You can read the [Bitwise Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise) chapter on MDN when a need arises. ## Comma @@ -427,10 +456,10 @@ Here, the first expression `1 + 2` is evaluated and its result is thrown away. T ```smart header="Comma has a very low precedence" Please note that the comma operator has very low precedence, lower than `=`, so parentheses are important in the example above. -Without them: `a = 1 + 2, 3 + 4` evaluates `+` first, summing the numbers into `a = 3, 7`, then the assignment operator `=` assigns `a = 3`, and finally the number after the comma, `7`, is not processed so it's ignored. +Without them: `a = 1 + 2, 3 + 4` evaluates `+` first, summing the numbers into `a = 3, 7`, then the assignment operator `=` assigns `a = 3`, and the rest is ignored. It's like `(a = 1 + 2), 3 + 4`. ``` -Why do we need an operator that throws away everything except the last part? +Why do we need an operator that throws away everything except the last expression? Sometimes, people use it in more complex constructs to put several actions in one line. @@ -443,4 +472,4 @@ for (*!*a = 1, b = 3, c = a * b*/!*; a < 10; a++) { } ``` -Such tricks are used in many JavaScript frameworks. That's why we're mentioning them. But, usually, they don't improve code readability so we should think well before using them. +Such tricks are used in many JavaScript frameworks. That's why we're mentioning them. But usually they don't improve code readability so we should think well before using them. diff --git a/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md b/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md index 9a240459e..632b1cf4e 100644 --- a/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md +++ b/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md @@ -3,19 +3,19 @@ ```js no-beautify 5 > 4 → true "apple" > "pineapple" → false -"2" > "12" → true -undefined == null → true -undefined === null → false +"2" > "12" → true +undefined == null → true +undefined === null → false null == "\n0\n" → false -null === +"\n0\n" → false +null === +"\n0\n" → false ``` -Algumas das razões: +Some of the reasons: -1. Obviamente, *true*. -2. Comparação de dicionário, portanto, *false*. -3. Novamente, comparação de dicionário, o primeiro caractere de `"2"` é maior que o primeiro caractere de `"1"`. -4. Valores `null` e `undefined` são iguais entre si somente. -5. A igualdade estrita é rigorosa. Diferentes tipos de ambos os lados levam a *false*. -6. Veja (4). -7. Igualdade estrita de diferentes tipos. +1. Obviously, true. +2. Dictionary comparison, hence false. `"a"` is smaller than `"p"`. +3. Again, dictionary comparison, first char `"2"` is greater than the first char `"1"`. +4. Values `null` and `undefined` equal each other only. +5. Strict equality is strict. Different types from both sides lead to false. +6. Similar to `(4)`, `null` only equals `undefined`. +7. Strict equality of different types. diff --git a/1-js/02-first-steps/09-comparison/1-comparison-questions/task.md b/1-js/02-first-steps/09-comparison/1-comparison-questions/task.md index 0cbd7c304..f8c19ebf0 100644 --- a/1-js/02-first-steps/09-comparison/1-comparison-questions/task.md +++ b/1-js/02-first-steps/09-comparison/1-comparison-questions/task.md @@ -15,3 +15,4 @@ undefined === null null == "\n0\n" null === +"\n0\n" ``` + diff --git a/1-js/02-first-steps/09-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md index 02b24ac7c..ead7922ff 100644 --- a/1-js/02-first-steps/09-comparison/article.md +++ b/1-js/02-first-steps/09-comparison/article.md @@ -1,41 +1,47 @@ -# Comparações +# Comparisons -Conhecemos muitos operadores de comparação em matemática: +We know many comparison operators from maths. -- Maior/menor que: a > b, a < b. -- Maior/menor ou igual que: a >= b, a <= b. -- Igual: `a == b` (observe o sinal de igual duplo `=`; um único sinal de igual `a = b` significa uma atribuição). -- Diferente. Em matemática a notação é , mas em JavaScript é escrito como uma atribuição com um sinal de exclamação antes: a != b. +In JavaScript they are written like this: -## Booleano é o resultado +- Greater/less than: a > b, a < b. +- Greater/less than or equals: a >= b, a <= b. +- Equals: `a == b`, please note the double equality sign `==` means the equality test, while a single one `a = b` means an assignment. +- Not equals. In maths the notation is , but in JavaScript it's written as a != b. -Como todos os outros operadores, uma comparação retorna um valor. Nesse caso, o valor é um booleano. +In this article we'll learn more about different types of comparisons, how JavaScript makes them, including important peculiarities. -- `true` -- significa "sim", "correto" ou "verdadeiro". -- `false` -- significa "não", "errado" ou "falso". +At the end you'll find a good recipe to avoid "JavaScript quirks"-related issues. -Por exemplo: +## Boolean is the result + +All comparison operators return a boolean value: + +- `true` -- means "yes", "correct" or "the truth". +- `false` -- means "no", "wrong" or "not the truth". + +For example: ```js run -alert( 2 > 1 ); // true (verdadeiro) -alert( 2 == 1 ); // false (falso) -alert( 2 != 1 ); // true (verdadeiro) +alert( 2 > 1 ); // true (correct) +alert( 2 == 1 ); // false (wrong) +alert( 2 != 1 ); // true (correct) ``` -Um resultado de comparação pode ser atribuído a uma variável, assim como qualquer valor: +A comparison result can be assigned to a variable, just like any value: ```js run -let result = 5 > 4; // atribui o resultado da comparação +let result = 5 > 4; // assign the result of the comparison alert( result ); // true ``` -## Comparação de strings +## String comparison -Para ver se uma string é maior do que outra, o JavaScript usa a chamada ordem de "dicionário" ou "lexicográfica". +To see whether a string is greater than another, JavaScript uses the so-called "dictionary" or "lexicographical" order. -Em outras palavras, as strings são comparadas letra a letra. +In other words, strings are compared letter-by-letter. -Por exemplo: +For example: ```js run alert( 'Z' > 'A' ); // true @@ -43,40 +49,42 @@ alert( 'Glow' > 'Glee' ); // true alert( 'Bee' > 'Be' ); // true ``` -O algoritmo para comparar duas strings é simples: +The algorithm to compare two strings is simple: + +1. Compare the first character of both strings. +2. If the first character from the first string is greater (or less) than the other string's, then the first string is greater (or less) than the second. We're done. +3. Otherwise, if both strings' first characters are the same, compare the second characters the same way. +4. Repeat until the end of either string. +5. If both strings end at the same length, then they are equal. Otherwise, the longer string is greater. -1. Compare o primeiro caractere de ambas as strings. -2. Se o primeiro caractere da primeira string for maior (ou menor) que o da outra, a primeira string será maior (ou menor) que a segunda. Terminou. -3. Caso contrário, se os primeiros caracteres das duas sequências forem os mesmos, compare os segundos caracteres da mesma maneira. -4. Repita até o final de qualquer string. -5. Se ambas as seqüências terminarem com o mesmo comprimento, elas serão iguais. Caso contrário, a string mais longa é maior. +In the first example above, the comparison `'Z' > 'A'` gets to a result at the first step. -Nos exemplos acima, a comparação `'Z' > 'A'` chega a um resultado no primeiro passo, enquanto as strings `"Glow"` e `"Glee"`são comparadas caractere por caractere: +The second comparison `'Glow'` and `'Glee'` needs more steps as strings are compared character-by-character: -1. `G` é o mesmo que `G`. -2. `l` é o mesmo que `l`. -3. `o` é maior que `e`. Pare aqui. A primeira string é maior. +1. `G` is the same as `G`. +2. `l` is the same as `l`. +3. `o` is greater than `e`. Stop here. The first string is greater. ```smart header="Not a real dictionary, but Unicode order" -O algoritmo de comparação dado acima é aproximadamente equivalente ao usado em dicionários ou catálogos telefônicos, mas não é exatamente o mesmo. +The comparison algorithm given above is roughly equivalent to the one used in dictionaries or phone books, but it's not exactly the same. -Por exemplo, um caso importante. Uma letra maiúscula `"A"` não é igual à minúscula `"a"`. Qual delas é maior? A `"a"` minúscula. Porquê? Porque o caractere minúsculo, tem um índice maior na tabela de codificação interna que o JavaScript usa (Unicode). Voltaremos a detalhes específicos e conseqüências disso no capítulo . +For instance, case matters. A capital letter `"A"` is not equal to the lowercase `"a"`. Which one is greater? The lowercase `"a"`. Why? Because the lowercase character has a greater index in the internal encoding table JavaScript uses (Unicode). We'll get back to specific details and consequences of this in the chapter . ``` -## Comparação de diferentes tipos +## Comparison of different types -Ao comparar valores de diferentes tipos, o JavaScript converte os valores em números. +When comparing values of different types, JavaScript converts the values to numbers. -Por exemplo: +For example: ```js run -alert( '2' > 1 ); // true, a string '2' é convertida para o número 2 -alert( '01' == 1 ); // true, a string '01' é convertida para o número 1 +alert( '2' > 1 ); // true, string '2' becomes a number 2 +alert( '01' == 1 ); // true, string '01' becomes a number 1 ``` -Para valores booleanos, `true` torna-se `1`, e `false` torna-se `0`. +For boolean values, `true` becomes `1` and `false` becomes `0`. -Por exemplo: +For example: ```js run alert( true == 1 ); // true @@ -84,12 +92,12 @@ alert( false == 0 ); // true ``` ````smart header="A funny consequence" -É possível que ao mesmo tempo: +It is possible that at the same time: -- Dois valores sejam iguais. -- Um deles seja `true` como booleano, e o outro seja `false` como booleano. +- Two values are equal. +- One of them is `true` as a boolean and the other one is `false` as a boolean. -Por exemplo: +For example: ```js run let a = 0; @@ -101,67 +109,67 @@ alert( Boolean(b) ); // true alert(a == b); // true! ``` -Do ponto de vista do JavaScript, esse resultado é normal. Uma verificação de igualdade converte valores usando a conversão numérica (portanto `"0"` torna-se `0`), enquanto a conversão explícita de `Boolean` usa outro conjunto de regras. +From JavaScript's standpoint, this result is quite normal. An equality check converts values using the numeric conversion (hence `"0"` becomes `0`), while the explicit `Boolean` conversion uses another set of rules. ```` -## Igualdade estrita +## Strict equality -Uma verificação de igualdade regular `==` tem um problema. Não é possível diferenciar `0` de `false`: +A regular equality check `==` has a problem. It cannot differentiate `0` from `false`: ```js run alert( 0 == false ); // true ``` -A mesma coisa acontece com uma string vazia: +The same thing happens with an empty string: ```js run alert( '' == false ); // true ``` -Isso acontece, porque operandos de diferentes tipos são convertidos em números pelo operador de igualdade `==`. Uma string vazia, assim como `false`, se torna num zero. +This happens because operands of different types are converted to numbers by the equality operator `==`. An empty string, just like `false`, becomes a zero. -O que fazer, se quisermos diferenciar `0` de `false`? +What to do if we'd like to differentiate `0` from `false`? -**Um operador de igualdade estrita `===` verifica a igualdade sem conversão de tipo.** +**A strict equality operator `===` checks the equality without type conversion.** -Em outras palavras, se `a` e `b` forem de tipos diferentes, então `a === b` retornará imediatamente `false`, sem uma tentativa de convertê-los. +In other words, if `a` and `b` are of different types, then `a === b` immediately returns `false` without an attempt to convert them. -Vamos tentar: +Let's try it: ```js run -alert( 0 === false ); // false, porque os tipos são diferentes +alert( 0 === false ); // false, because the types are different ``` -Existe também um operador de "diferença estrita" `!==`, análogo a `!=`. +There is also a "strict non-equality" operator `!==` analogous to `!=`. -O operador de igualdade estrita é um pouco mais longo para se escrever, mas torna óbvio o que está acontecendo e deixa menos espaço para erros. +The strict equality operator is a bit longer to write, but makes it obvious what's going on and leaves less room for errors. -## Comparação com "null" e "undefined" +## Comparison with null and undefined -Vamos ver mais casos extremos. +There's a non-intuitive behavior when `null` or `undefined` are compared to other values. -Existe um comportamento não intuitivo quando `null`, ou `undefined`, são comparados com outros valores. - - -Para uma verificação de igualdade estrita `===`:
Esses valores são diferentes, porque cada um deles é de um tipo diferente. +For a strict equality check `===` +: These values are different, because each of them is a different type. ```js run alert( null === undefined ); // false ``` -Para uma verificação não estrita `==`:
Existe uma regra especial. Esses dois formam um "lindo casal": eles são iguais (no sentido de "=="), mas a nenhum outro valor. +For a non-strict check `==` +: There's a special rule. These two are a "sweet couple": they equal each other (in the sense of `==`), but not any other value. ```js run alert( null == undefined ); // true ``` -Para matemática e outras comparações `< > <= >=`:
`null/undefined` são convertidos em números: `null` torna-se `0`, enquanto `undefined` torna-se `NaN` (*Not a Number*). +For maths and other comparisons `< > <= >=` +: `null/undefined` are converted to numbers: `null` becomes `0`, while `undefined` becomes `NaN`. -Agora, vamos ver algumas coisas engraçadas que acontecem quando aplicamos essas regras. E, o que é mais importante, como não cair em uma armadilha com eles. +Now let's see some funny things that happen when we apply these rules. And, what's more important, how to not fall into a trap with them. -### Resultado estranho: "null" vs "0" +### Strange result: null vs 0 -Vamos comparar `null` com um zero: +Let's compare `null` with a zero: ```js run alert( null > 0 ); // (1) false @@ -169,15 +177,15 @@ alert( null == 0 ); // (2) false alert( null >= 0 ); // (3) *!*true*/!* ``` -Matematicamente, isso é estranho. O último resultado afirma que "`null` é maior que ou igual a zero", então em uma das comparações acima deve ser `true`, mas ambos casos são falsos. +Mathematically, that's strange. The last result states that "`null` is greater than or equal to zero", so in one of the comparisons above it must be `true`, but they are both false. -A razão é que, uma verificação de igualdade `==` e comparações `> < >= <=`, funcionam de maneira diferente. Comparações convertem `null` para um número, tratando-o como `0`. É por isso que (3) `null >= 0` é verdadeiro, e (1) `null > 0` é falso. +The reason is that an equality check `==` and comparisons `> < >= <=` work differently. Comparisons convert `null` to a number, treating it as `0`. That's why (3) `null >= 0` is true and (1) `null > 0` is false. -Por outro lado, a verificação de igualdade `==` para `undefined` (e `null`) é definida de tal forma que, sem nenhuma conversão, elas são iguais entre si e não equivalem a qualquer outra coisa. É por isso que (2) `null == 0` é falso. +On the other hand, the equality check `==` for `undefined` and `null` is defined such that, without any conversions, they equal each other and don't equal anything else. That's why (2) `null == 0` is false. -### Um incomparável "*undefined*" +### An incomparable undefined -O valor `undefined` não deve ser comparado a outros valores: +The value `undefined` shouldn't be compared to other values: ```js run alert( undefined > 0 ); // false (1) @@ -185,25 +193,24 @@ alert( undefined < 0 ); // false (2) alert( undefined == 0 ); // false (3) ``` -Por que não gosta do zero? Sempre falso! - -Obtemos estes resultados porque: +Why does it dislike zero so much? Always false! -- Comparações `(1)` e `(2)`, retornam `false` porque `undefined` é convertido para `NaN`, e `NaN` é um valor numérico especial que retorna `false` para todas as comparações. -- A verificação de igualdade `(3)`, retorna `false` porque `undefined` somente é igual a `null`, e a nenhum outro valor. +We get these results because: -### Evitar problemas +- 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. +- The equality check `(3)` returns `false` because `undefined` only equals `null`, `undefined`, and no other value. -Por que nós examinamos esses exemplos? Devemos nos lembrar dessas peculiaridades o tempo todo? Bem, na verdade não. Na verdade, essas coisas complicadas gradualmente se tornarão familiares ao longo do tempo, mas há uma maneira sólida de evitar problemas com elas: +### Avoid problems -Apenas trate qualquer comparação com `undefined / null`, exceto na igualdade estrita `===`, com cuidado excepcional. +Why did we go over these examples? Should we remember these peculiarities all the time? Well, not really. Actually, these tricky things will gradually become familiar over time, but there's a solid way to avoid problems with them: -Não use comparações `> >= < <=` com uma variável que possa ser `null / undefined`, a menos que você tenha a certeza do que está fazendo. Se uma variável puder ter esses valores, verifique-os separadamente. +- Treat any comparison with `undefined/null` except the strict equality `===` with exceptional care. +- Don't use comparisons `>= > < <=` with a variable which may be `null/undefined`, unless you're really sure of what you're doing. If a variable can have these values, check for them separately. -## Resumo +## Summary -- Operadores de comparação retornam um valor booleano. -- As strings são comparadas letra por letra, na ordem de "dicionário". -- Quando valores de diferentes tipos são comparados, eles são convertidos para números (com a exclusão de uma verificação de igualdade estrita). -- Os valores `null` e `undefined` usando `==` são iguais entre eles, e não são iguais a nenhum outro valor. -- Tenha cuidado ao usar comparações como `>` ou `<`, com variáveis que ocasionalmente possam ser 'null / undefined'. Verificar se há "null / undefined" separadamente é uma boa ideia. +- Comparison operators return a boolean value. +- Strings are compared letter-by-letter in the "dictionary" order. +- When values of different types are compared, they get converted to numbers (with the exclusion of a strict equality check). +- The values `null` and `undefined` equal `==` each other and do not equal any other value. +- Be careful when using comparisons like `>` or `<` with variables that can occasionally be `null/undefined`. Checking for `null/undefined` separately is a good idea. diff --git a/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2.svg b/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2.svg index d2ac8d760..7f9a8beec 100644 --- a/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2.svg +++ b/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2.svg @@ -1,48 +1 @@ - - - - ifelse_task2.svg - Created with sketchtool. - - - - - - - Begin - - - - - - You don't know? - “ECMAScript”! - - - - - - Right! - - - - - - - - - What's the - “official” name of - JavaScript? - - - - Other - - - - ECMAScript - - - - \ No newline at end of file +BeginYou don't know? “ECMAScript”!Right!What's the “official” name of JavaScript?OtherECMAScript diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md index 1e12fa7b5..51514062f 100644 --- a/1-js/02-first-steps/10-ifelse/article.md +++ b/1-js/02-first-steps/10-ifelse/article.md @@ -1,12 +1,12 @@ -# Conditional operators: if, '?' +# Conditional branching: if, '?' Sometimes, we need to perform different actions based on different conditions. -To do that, we use the `if` statement and the conditional (ternary) operator which we will be referring to as the “question mark” operator `?` for simplicity. +To do that, we can use the `if` statement and the conditional operator `?`, that's also called a "question mark" operator. ## The "if" statement -The `if` statement evaluates a condition and, if the condition's result is `true`, executes a block of code. +The `if(...)` statement evaluates a condition in parentheses and, if the result is `true`, executes a block of code. For example: @@ -68,7 +68,7 @@ if (cond) { ## The "else" clause -The `if` statement may contain an optional "else" block. It executes when the condition is false. +The `if` statement may contain an optional "else" block. It executes when the condition is falsy. For example: ```js run @@ -103,7 +103,7 @@ In the code above, JavaScript first checks `year < 2015`. If that is falsy, it g There can be more `else if` blocks. The final `else` is optional. -## Ternary operator '?' +## Conditional operator '?' Sometimes, we need to assign a variable depending on a condition. @@ -124,9 +124,9 @@ if (age > 18) { alert(accessAllowed); ``` -The so-called "ternary" or "question mark" operator lets us do that in a shorter and simpler way. +The so-called "conditional" or "question mark" operator lets us do that in a shorter and simpler way. -The operator is represented by a question mark `?`. The formal term "ternary" means that the operator has three operands. It is actually the one and only operator in JavaScript which has that many. +The operator is represented by a question mark `?`. Sometimes it's called "ternary", because the operator has three operands. It is actually the one and only operator in JavaScript which has that many. The syntax is: ```js @@ -141,7 +141,7 @@ For example: let accessAllowed = (age > 18) ? true : false; ``` -Technically, we can omit the parentheses around `age > 18`. The question mark operator has a low precedence, so it executes after the comparison `>`. +Technically, we can omit the parentheses around `age > 18`. The question mark operator has a low precedence, so it executes after the comparison `>`. This example will do the same thing as the previous one: @@ -216,7 +216,7 @@ Depending on the condition `company == 'Netscape'`, either the first or the seco We don't assign a result to a variable here. Instead, we execute different code depending on the condition. -**We don't recommend using the question mark operator in this way.** +**It's not recommended to use the question mark operator in this way.** The notation is shorter than the equivalent `if` statement, which appeals to some programmers. But it is less readable. diff --git a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md index 8f4d664e8..f85b56366 100644 --- a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md +++ b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md @@ -6,7 +6,7 @@ alert( alert(1) || 2 || alert(3) ); The call to `alert` does not return a value. Or, in other words, it returns `undefined`. -1. The first OR `||` evaluates it's left operand `alert(1)`. That shows the first message with `1`. +1. The first OR `||` evaluates its left operand `alert(1)`. That shows the first message with `1`. 2. The `alert` returns `undefined`, so OR goes on to the second operand searching for a truthy value. 3. The second operand `2` is truthy, so the execution is halted, `2` is returned and then shown by the outer alert. diff --git a/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md b/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md index cc00ca9fc..fc9e336c1 100644 --- a/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md +++ b/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md @@ -4,6 +4,6 @@ importance: 3 # Check the range between -Write an "if" condition to check that `age` is between `14` and `90` inclusively. +Write an `if` condition to check that `age` is between `14` and `90` inclusively. "Inclusively" means that `age` can reach the edges `14` or `90`. diff --git a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md index 7c22d6ad1..9b947d00f 100644 --- a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md +++ b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md @@ -4,6 +4,6 @@ importance: 3 # Check the range outside -Write an `if` condition to check that `age` is NOT between 14 and 90 inclusively. +Write an `if` condition to check that `age` is NOT between `14` and `90` inclusively. Create two variants: the first one using NOT `!`, the second one -- without it. diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg index f16e37a60..d875c5441 100644 --- a/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg +++ b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg @@ -1,101 +1 @@ - - - - ifelse_task.svg - Created with sketchtool. - - - - - - - - Begin - - - - - - Canceled - - - - - - Canceled - - - - - - Welcome! - - - - - - I don't know you - - - - - - Wrong password - - - - - - - - - Who's there? - - - - - - Password? - - - - - - Cancel - - - - - - Cancel - - - - - - Admin - - - - - - TheMaster - - - - - - - - Other - - - - - - Other - - - - - \ No newline at end of file +BeginCanceledCanceledWelcome!I don't know youWrong passwordWho's there?Password?CancelCancelAdminTheMasterOtherOther diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md index b535650ec..24a783cc9 100644 --- a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md +++ b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md @@ -3,11 +3,11 @@ ```js run demo let userName = prompt("Who's there?", ''); -if (userName == 'Admin') { +if (userName === 'Admin') { let pass = prompt('Password?', ''); - if (pass == 'TheMaster') { + if (pass === 'TheMaster') { alert( 'Welcome!' ); } else if (pass == '' || pass == null) { alert( 'Canceled.' ); @@ -15,7 +15,7 @@ if (userName == 'Admin') { alert( 'Wrong password' ); } -} else if (userName == '' || userName == null) { +} else if (userName === '' || userName === null) { alert( 'Canceled' ); } else { alert( "I don't know you" ); diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md index 4932020ae..caa8cdfaf 100644 --- a/1-js/02-first-steps/11-logical-operators/article.md +++ b/1-js/02-first-steps/11-logical-operators/article.md @@ -64,7 +64,7 @@ if (hour < 10 || hour > 18 || isWeekend) { } ``` -## OR finds the first truthy value +## OR "||" finds the first truthy value The logic described above is somewhat classical. Now, let's bring in the "extra" features of JavaScript. @@ -84,16 +84,16 @@ The OR `||` operator does the following: A value is returned in its original form, without the conversion. -In other words, a chain of OR `"||"` returns the first truthy value or the last one if no such value is found. +In other words, a chain of OR `||` returns the first truthy value or the last one if no truthy value is found. For instance: ```js run alert( 1 || 0 ); // 1 (1 is truthy) -alert( true || 'no matter what' ); // (true is truthy) alert( null || 1 ); // 1 (1 is the first truthy value) alert( null || 0 || 1 ); // 1 (the first truthy value) + alert( undefined || null || 0 ); // 0 (all falsy, returns the last value) ``` @@ -101,53 +101,40 @@ This leads to some interesting usage compared to a "pure, classical, boolean-onl 1. **Getting the first truthy value from a list of variables or expressions.** - Imagine we have several variables which can either contain data or be `null/undefined`. How can we find the first one with data? + For instance, we have `firstName`, `lastName` and `nickName` variables, all optional (i.e. can be undefined or have falsy values). - We can use OR `||`: + Let's use OR `||` to choose the one that has the data and show it (or `"Anonymous"` if nothing set): ```js run - let currentUser = null; - let defaultUser = "John"; + let firstName = ""; + let lastName = ""; + let nickName = "SuperCoder"; *!* - let name = currentUser || defaultUser || "unnamed"; + alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder */!* - - alert( name ); // selects "John" – the first truthy value ``` - If both `currentUser` and `defaultUser` were falsy, `"unnamed"` would be the result. -2. **Short-circuit evaluation.** - - Operands can be not only values, but arbitrary expressions. OR evaluates and tests them from left to right. The evaluation stops when a truthy value is reached, and the value is returned. This process is called "a short-circuit evaluation" because it goes as short as possible from left to right. + If all variables were falsy, `"Anonymous"` would show up. - This is clearly seen when the expression given as the second argument has a side effect like a variable assignment. +2. **Short-circuit evaluation.** - In the example below, `x` does not get assigned: + Another feature of OR `||` operator is the so-called "short-circuit" evaluation. - ```js run no-beautify - let x; + 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. - *!*true*/!* || (x = 1); + That 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 or a function call. - alert(x); // undefined, because (x = 1) not evaluated - ``` - - If, instead, the first argument is `false`, `||` evaluates the second one, thus running the assignment: + In the example below, only the second message is printed: ```js run no-beautify - let x; - - *!*false*/!* || (x = 1); - - alert(x); // 1 + *!*true*/!* || alert("not printed"); + *!*false*/!* || alert("printed"); ``` - An assignment is a simple case. Other side effects can also be involved. + In the first line, the OR `||` operator stops the evaluation immediately upon seeing `true`, so the `alert` isn't run. - As we can see, such a use case is a "shorter way of doing `if`". The first operand is converted to boolean. If it's false, the second one is evaluated. - - Most of time, it's better to use a "regular" `if` to keep the code easy to understand, but sometimes this can be handy. + Sometimes, people use this feature to execute commands only if the condition on the left part is falsy. ## && (AND) @@ -186,7 +173,7 @@ if (1 && 0) { // evaluated as true && false ``` -## AND finds the first falsy value +## AND "&&" finds the first falsy value Given multiple AND'ed values: @@ -236,7 +223,8 @@ The precedence of AND `&&` operator is higher than OR `||`. So the code `a && b || c && d` is essentially the same as if the `&&` expressions were in parentheses: `(a && b) || (c && d)`. ```` -Just like OR, the AND `&&` operator can sometimes replace `if`. +````warn header="Don't replace `if` with `||` or `&&`" +Sometimes, people use the AND `&&` operator as a "shorter way to write `if`". For instance: @@ -253,14 +241,12 @@ So we basically have an analogue for: ```js run let x = 1; -if (x > 0) { - alert( 'Greater than zero!' ); -} +if (x > 0) alert( 'Greater than zero!' ); ``` -The variant with `&&` appears shorter. But `if` is more obvious and tends to be a little bit more readable. +Although, the variant with `&&` appears shorter, `if` is more obvious and tends to be a little bit more readable. So we recommend using every construct for its purpose: use `if` if we want `if` and use `&&` if we want AND. +```` -So we recommend using every construct for its purpose: use `if` if we want if and use `&&` if we want AND. ## ! (NOT) diff --git a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md index 7392b81f8..55e0c2067 100644 --- a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md +++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md @@ -2,52 +2,92 @@ [recent browser="new"] -The nullish coalescing operator `??` provides a short syntax for selecting a first "defined" variable from the list. +Here, in this article, we'll say that an expression is "defined" when it's neither `null` nor `undefined`. + +The nullish coalescing operator is written as two question marks `??`. The result of `a ?? b` is: -- `a` if it's not `null` or `undefined`, -- `b`, otherwise. +- if `a` is defined, then `a`, +- if `a` isn't defined, then `b`. + + +In other words, `??` returns the first argument if it's not `null/undefined`. Otherwise, the second one. -So, `x = a ?? b` is a short equivalent to: +The nullish coalescing operator isn't anything completely new. It's just a nice syntax to get the first "defined" value of the two. + +We can rewrite `result = a ?? b` using the operators that we already know, like this: ```js -x = (a !== null && a !== undefined) ? a : b; +result = (a !== null && a !== undefined) ? a : b; ``` -Here's a longer example. +The common use case for `??` is to provide a default value for a potentially undefined variable. -Let's say, we have a `firstName`, `lastName` or `nickName`, all of them optional. +For example, here we show `Anonymous` if `user` isn't defined: -Let's choose the defined one and show it (or "Anonymous" if nothing is set): +```js run +let user; + +alert(user ?? "Anonymous"); // Anonymous +``` + +Of course, if `user` had any value except `null/undefined`, then we would see it instead: + +```js run +let user = "John"; + +alert(user ?? "Anonymous"); // John +``` + +We can also use a sequence of `??` to select the first value from a list that isn't `null/undefined`. + +Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be undefined, if the user decided not to enter a value. + +We'd like to display the user name using one of these variables, or show "Anonymous" if all of them are undefined. + +Let's use the `??` operator for that: ```js run let firstName = null; let lastName = null; let nickName = "Supercoder"; -// show the first not-null/undefined variable +// shows the first defined value: +*!* alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder +*/!* ``` ## Comparison with || -That's very similar to OR `||` operator. Actually, we can replace `??` with `||` in the code above and get the same result. - -The important difference is that: -- `||` returns the first *truthy* value. -- `??` returns the first *defined* value. +The OR `||` operator can be used in the same way as `??`, as it was described in the [previous chapter](info:logical-operators#or-finds-the-first-truthy-value). -This matters a lot when we'd like to treat `null/undefined` differently from `0`. +For example, in the code above we could replace `??` with `||` and still get the same result: -For example: +```js run +let firstName = null; +let lastName = null; +let nickName = "Supercoder"; -```js -height = height ?? 100; +// shows the first truthy value: +*!* +alert(firstName || lastName || nickName || "Anonymous"); // Supercoder +*/!* ``` -This sets `height` to `100` if it's not defined. But if `height` is `0`, then it remains "as is". +The OR `||` operator exists since the beginning of JavaScript, so developers were using it for such purposes for a long time. -Let's compare it with `||`: +On the other hand, the nullish coalescing operator `??` was added to JavaScript only recently, and the reason for that was that people weren't quite happy with `||`. + +The important difference between them is that: +- `||` returns the first *truthy* value. +- `??` returns the first *defined* value. + +In other words, `||` doesn't distinguish between `false`, `0`, an empty string `""` and `null/undefined`. They are all the same -- falsy values. If any of these is the first argument of `||`, then we'll get the second argument as the result. + +In practice though, we may want to use default value only when the variable is `null/undefined`. That is, when the value is really unknown/not set. + +For example, consider this: ```js run let height = 0; @@ -56,17 +96,18 @@ alert(height || 100); // 100 alert(height ?? 100); // 0 ``` -Here, `height || 100` treats zero height as unset, same as `null`, `undefined` or any other falsy value, depeding on use cases that may be incorrect. +- The `height || 100` checks `height` for being a falsy value, and it really is. + - so the result is the second argument, `100`. +- The `height ?? 100` checks `height` for being `null/undefined`, and it's not, + - so the result is `height` "as is", that is `0`. -The `height ?? 100` returns `100` only if `height` is exactly `null` or `undefined`. +If the zero height is a valid value, that shouldn't be replaced with the default, then `??` does just the right thing. ## Precedence -The precedence of the `??` operator is rather low: `7` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). +The precedence of the `??` operator is rather low: `5` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). So `??` is evaluated before `=` and `?`, but after most other operations, such as `+`, `*`. -That's lower than most operators and a bit higher than `=` and `?`. - -So if we need to use `??` in a complex expression, then consider adding parentheses: +So if we'd like to choose a value with `??` in an expression with other operators, consider adding parentheses: ```js run let height = null; @@ -78,14 +119,19 @@ let area = (height ?? 100) * (width ?? 50); alert(area); // 5000 ``` -Otherwise, if we omit parentheses, then `*` has the higher precedence and would run first. That would be the same as: +Otherwise, if we omit parentheses, then as `*` has the higher precedence than `??`, it would execute first, leading to incorrect results. ```js -// not correct +// without parentheses +let area = height ?? 100 * width ?? 50; + +// ...works the same as this (probably not what we want): let area = height ?? (100 * width) ?? 50; ``` -There's also a related language-level limitation. Due to safety reasons, it's forbidden to use `??` together with `&&` and `||` operators. +### Using ?? with && or || + +Due to safety reasons, JavaScript forbids using `??` together with `&&` and `||` operators, unless the precedence is explicitly specified with parentheses. The code below triggers a syntax error: @@ -93,18 +139,21 @@ The code below triggers a syntax error: let x = 1 && 2 ?? 3; // Syntax error ``` -The limitation is surely debatable, but for some reason it was added to the language specification. +The limitation is surely debatable, but it was added to the language specification with the purpose to avoid programming mistakes, when people start to switch to `??` from `||`. -Use explicit parentheses to fix it: +Use explicit parentheses to work around it: ```js run +*!* let x = (1 && 2) ?? 3; // Works +*/!* + alert(x); // 2 ``` ## Summary -- The nullish coalescing operator `??` provides a short way to choose a "defined" value from the list. +- The nullish coalescing operator `??` provides a short way to choose the first "defined" value from a list. It's used to assign default values to variables: @@ -113,5 +162,5 @@ alert(x); // 2 height = height ?? 100; ``` -- The operator `??` has a very low precedence, a bit higher than `?` and `=`. +- The operator `??` has a very low precedence, only a bit higher than `?` and `=`, so consider adding parentheses when using it in an expression. - It's forbidden to use it with `||` or `&&` without explicit parentheses. diff --git a/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md index 2e04a78c4..c7de5f09b 100644 --- a/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md +++ b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md @@ -10,6 +10,6 @@ do { The loop `do..while` repeats while both checks are truthy: 1. The check for `num <= 100` -- that is, the entered value is still not greater than `100`. -2. The check `&& num` is false when `num` is `null` or a empty string. Then the `while` loop stops too. +2. The check `&& num` is false when `num` is `null` or an empty string. Then the `while` loop stops too. P.S. If `num` is `null` then `num <= 100` is `true`, so without the 2nd check the loop wouldn't stop if the user clicks CANCEL. Both checks are required. diff --git a/1-js/02-first-steps/13-while-for/7-list-primes/solution.md b/1-js/02-first-steps/13-while-for/7-list-primes/solution.md index 9ff0663d7..b4b64b6fa 100644 --- a/1-js/02-first-steps/13-while-for/7-list-primes/solution.md +++ b/1-js/02-first-steps/13-while-for/7-list-primes/solution.md @@ -26,4 +26,4 @@ for (let i = 2; i <= n; i++) { // for each i... } ``` -There's a lot of space to opimize it. For instance, we could look for the divisors from `2` to square root of `i`. But anyway, if we want to be really efficient for large intervals, we need to change the approach and rely on advanced maths and complex algorithms like [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) etc. +There's a lot of space to optimize it. For instance, we could look for the divisors from `2` to square root of `i`. But anyway, if we want to be really efficient for large intervals, we need to change the approach and rely on advanced maths and complex algorithms like [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) etc. diff --git a/1-js/02-first-steps/13-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md index 6be50597d..b3e3953b8 100644 --- a/1-js/02-first-steps/13-while-for/article.md +++ b/1-js/02-first-steps/13-while-for/article.md @@ -17,7 +17,7 @@ while (condition) { } ``` -While the `condition` is `true`, the `code` from the loop body is executed. +While the `condition` is truthy, the `code` from the loop body is executed. For instance, the loop below outputs `i` while `i < 3`: @@ -47,8 +47,8 @@ while (i) { // when i becomes 0, the condition becomes falsy, and the loop stops } ``` -````smart header="Brackets are not required for a single-line body" -If the loop body has a single statement, we can omit the brackets `{…}`: +````smart header="Curly braces are not required for a single-line body" +If the loop body has a single statement, we can omit the curly braces `{…}`: ```js run let i = 3; @@ -84,7 +84,7 @@ This form of syntax should only be used when you want the body of the loop to ex ## The "for" loop -The `for` loop is the most commonly used loop. +The `for` loop is more complex, but it's also the most commonly used loop. It looks like this: @@ -108,11 +108,11 @@ Let's examine the `for` statement part-by-part: |-------|----------|----------------------------------------------------------------------------| | begin | `i = 0` | Executes once upon entering the loop. | | condition | `i < 3`| Checked before every loop iteration. If false, the loop stops. | -| step| `i++` | Executes after the body on each iteration but before the condition check. | | body | `alert(i)`| Runs again and again while the condition is truthy. | - +| step| `i++` | Executes after the body on each iteration. | The general loop algorithm works like this: + ``` Run begin → (if condition → run body and run step) @@ -121,6 +121,8 @@ Run begin → ... ``` +That is, `begin` executes once, and then it iterates: after each `condition` test, `body` and `step` are executed. + If you are new to loops, it could help to go back to the example and reproduce how it runs step-by-step on a piece of paper. Here's exactly what happens in our case: @@ -210,7 +212,7 @@ But we can force the exit at any time using the special `break` directive. For example, the loop below asks the user for a series of numbers, "breaking" when no number is entered: -```js +```js run let sum = 0; while (true) { @@ -254,7 +256,7 @@ For even values of `i`, the `continue` directive stops executing the body and pa ````smart header="The `continue` directive helps decrease nesting" A loop that shows odd values could look like this: -```js +```js run for (let i = 0; i < 10; i++) { if (i % 2) { @@ -266,7 +268,7 @@ for (let i = 0; i < 10; i++) { From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an `if` block instead of using `continue`. -But as a side-effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of`if` is longer than a few lines, that may decrease the overall readability. +But as a side-effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability. ```` ````warn header="No `break/continue` to the right side of '?'" @@ -289,8 +291,7 @@ if (i > 5) { (i > 5) ? alert(i) : *!*continue*/!*; // continue isn't allowed here ``` -...it stops working. Code like this will give a syntax error: - +...it stops working: there's a syntax error. This is just another reason not to use the question mark operator `?` instead of `if`. ```` @@ -299,7 +300,7 @@ This is just another reason not to use the question mark operator `?` instead of Sometimes we need to break out from multiple nested loops at once. -For example, in the code below we loop over `i` and `j`, prompting for the coordinates `(i, j)` from `(0,0)` to `(3,3)`: +For example, in the code below we loop over `i` and `j`, prompting for the coordinates `(i, j)` from `(0,0)` to `(2,2)`: ```js run no-beautify for (let i = 0; i < 3; i++) { @@ -357,12 +358,12 @@ for (let i = 0; i < 3; i++) { ... } The `continue` directive can also be used with a label. In this case, code execution jumps to the next iteration of the labeled loop. -````warn header="Labels are not a \"goto\"" +````warn header="Labels do not allow to \"jump\" anywhere" Labels do not allow us to jump into an arbitrary place in the code. For example, it is impossible to do this: ```js -break label; // jumps to label? No. +break label; // doesn't jumps to the label below label: for (...) ``` diff --git a/1-js/02-first-steps/14-switch/article.md b/1-js/02-first-steps/14-switch/article.md index 873699feb..314c6cef8 100644 --- a/1-js/02-first-steps/14-switch/article.md +++ b/1-js/02-first-steps/14-switch/article.md @@ -1,22 +1,22 @@ -# A instrução "switch" +# The "switch" statement -Uma instrução `switch` pode substituir muitas comparações `se`. +A `switch` statement can replace multiple `if` checks. -Ela é uma forma mais descritiva de comparar um valor com múltiplas variantes. +It gives a more descriptive way to compare a value with multiple variants. -## A sintaxe +## The syntax -O `switch` tem um ou mais blocos `case` (caso) e um `default` (padrão) opcional. +The `switch` has one or more `case` blocks and an optional default. -Tem uma apresentação similar a: +It looks like this: ```js no-beautify switch(x) { - case 'valor1': // if (x === 'valor1') + case 'value1': // if (x === 'value1') ... [break] - case 'valor2': // if (x === 'valor2') + case 'value2': // if (x === 'value2') ... [break] @@ -26,71 +26,71 @@ switch(x) { } ``` -- O valor de `x` é comparado por meio de uma igualdade exata ao valor do primeiro `case` (isto é, ao `valor1`), a seguir ao do segundo (`valor2`) e assim sucessivamente. -- Se uma igualdade é encontrada, o `switch` começa a executar o código a partir do início do `case` correspondente, até ao próximo `break` (ou até ao fim do `switch`). -- Se nenhum `case` é equiparado então o código em `default` é executado (se existir). +- The value of `x` is checked for a strict equality to the value from the first `case` (that is, `value1`) then to the second (`value2`) and so on. +- If the equality is found, `switch` starts to execute the code starting from the corresponding `case`, until the nearest `break` (or until the end of `switch`). +- If no case is matched then the `default` code is executed (if it exists). -## Um exemplo +## An example -Um exemplo de `switch` (o código executado está em destaque): +An example of `switch` (the executed code is highlighted): ```js run let a = 2 + 2; switch (a) { case 3: - alert( 'Muito baixo' ); + alert( 'Too small' ); break; *!* case 4: - alert( 'Exacto!' ); + alert( 'Exactly!' ); break; */!* case 5: - alert( 'Muito alto' ); + alert( 'Too large' ); break; default: - alert( "Não conheço tais valores" ); + alert( "I don't know such values" ); } ``` -Aqui o `switch` começa por comparar `a` à variante no primeiro `case`, que é `3`. A correspondência falha. +Here the `switch` starts to compare `a` from the first `case` variant that is `3`. The match fails. -Então a `4`. Existe uma correspondência, e assim a execução começa a partir do `case 4` até ao próximo `break`. +Then `4`. That's a match, so the execution starts from `case 4` until the nearest `break`. -**Se não existir um `break` então a execução continua pelo próximo `case` sem quaisquer verificações.** +**If there is no `break` then the execution continues with the next `case` without any checks.** -Um exemplo sem `break`: +An example without `break`: ```js run let a = 2 + 2; switch (a) { case 3: - alert( 'Muito baixo' ); + alert( 'Too small' ); *!* case 4: - alert( 'Exacto!' ); + alert( 'Exactly!' ); case 5: - alert( 'Muito alto' ); + alert( 'Too big' ); default: - alert( "Não conheço tais valores" ); + alert( "I don't know such values" ); */!* } ``` -No exemplo acima, vemos uma execução sequential de três `alert`'s: +In the example above we'll see sequential execution of three `alert`s: ```js -alert( 'Exacto!' ); -alert( 'Muito alto' ); -alert( "Não conheço tais valores" ); +alert( 'Exactly!' ); +alert( 'Too big' ); +alert( "I don't know such values" ); ``` -````smart header="Any expression can be a switch/case argument" -Ambos `switch` e `case` permitem expressões arbitrárias. +````smart header="Any expression can be a `switch/case` argument" +Both `switch` and `case` allow arbitrary expressions. -Por exemplo: +For example: ```js run let a = "1"; @@ -99,75 +99,74 @@ let b = 0; switch (+a) { *!* case b + 1: - alert("isto executa, porque +a é 1, e é exatamente igual a b+1"); + alert("this runs, because +a is 1, exactly equals b+1"); break; */!* default: - alert("isto não executa"); + alert("this doesn't run"); } ``` -Aqui `+a` dá `1`, o que é comparado a `b + 1` no `case`, e o código correspondente é executado. +Here `+a` gives `1`, that's compared with `b + 1` in `case`, and the corresponding code is executed. ```` -## Grupos de "case" +## Grouping of "case" -Múltiplas variantes de `case` que partihem o mesmo código podem ser agrupadas. +Several variants of `case` which share the same code can be grouped. -Por exemplo, se quisermos que o mesmo código corra por `case 3` e `case 5`: +For example, if we want the same code to run for `case 3` and `case 5`: ```js run no-beautify -let a = 2 + 2; +let a = 3; switch (a) { case 4: - alert('Certo!'); + alert('Right!'); break; *!* - case 3: // (*) dois cases agrupados + case 3: // (*) grouped two cases case 5: - alert('Errado!'); - alert("Porque não tem aulas de matemática?"); + alert('Wrong!'); + alert("Why don't you take a math class?"); break; */!* default: - alert('O resultado é stranho. Realmente.'); + alert('The result is strange. Really.'); } ``` -Agora ambos `3` e `5` mostram a mesma mensagem. +Now both `3` and `5` show the same message. -A habilidade para "agrupar" cases é um efeito secundário de como `switch/case` funciona sem `break`. Aqui a execução do `case 3` começa pela linha `(*)` e prossegue pelo `case 5`, por não existir `break`. +The ability to "group" cases is a side-effect of how `switch/case` works without `break`. Here the execution of `case 3` starts from the line `(*)` and goes through `case 5`, because there's no `break`. -## O tipo importa +## Type matters -Vamos emfatizar que a verificação da igualdade é sempre exata. Os valores devem também ser do mesmo tipo para existir correspondência. +Let's emphasize that the equality check is always strict. The values must be of the same type to match. -Por exemplo, consideremos o código: +For example, let's consider the code: ```js run -let arg = prompt("Insira um valor?"); +let arg = prompt("Enter a value?"); switch (arg) { case '0': case '1': - alert( 'Um ou zero' ); + alert( 'One or zero' ); break; case '2': - alert( 'Dois' ); + alert( 'Two' ); break; case 3: - alert( 'Nunca executa!' ); + alert( 'Never executes!' ); break; default: - alert( 'Um valor desconhecido' ); + alert( 'An unknown value' ); } ``` -1. Para `0`, `1`, o primeiro `alert` executa. -2. Para `2` o segundo `alert` corre. -3. Mas para `3`, o resultado do `prompt` á a string `"3"`, que não é estritamente igual `===` ao número `3`. Assim temos código não -executável em `case 3`! A variante `default` será executada. +1. For `0`, `1`, the first `alert` runs. +2. For `2` the second `alert` runs. +3. But for `3`, the result of the `prompt` is a string `"3"`, which is not strictly equal `===` to the number `3`. So we've got a dead code in `case 3`! The `default` variant will execute. diff --git a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md index 023257922..e41c80418 100644 --- a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md +++ b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md @@ -1 +1 @@ -Sem diferença. +No difference. \ No newline at end of file diff --git a/1-js/02-first-steps/15-function-basics/1-if-else-required/task.md b/1-js/02-first-steps/15-function-basics/1-if-else-required/task.md index 8557afa9c..4f69a5c8c 100644 --- a/1-js/02-first-steps/15-function-basics/1-if-else-required/task.md +++ b/1-js/02-first-steps/15-function-basics/1-if-else-required/task.md @@ -2,11 +2,11 @@ importance: 4 --- -# "else" é obrigatório? +# Is "else" required? -A função a seguir retorna `true` se o parâmetro `age` é maior que `18`. +The following function returns `true` if the parameter `age` is greater than `18`. -Caso contrário, pede uma confirmação e retorna seu resultado: +Otherwise it asks for a confirmation and returns its result: ```js function checkAge(age) { @@ -15,13 +15,13 @@ function checkAge(age) { *!* } else { // ... - return confirm('Seus pais permitiram?'); + return confirm('Did parents allow you?'); } */!* } ``` -A função funcionará diferentemente se `else` for removido? +Will the function work differently if `else` is removed? ```js function checkAge(age) { @@ -30,9 +30,9 @@ function checkAge(age) { } *!* // ... - return confirm('Seus pais permitiram?'); + return confirm('Did parents allow you?'); */!* } ``` -Existe alguma diferença no comportamento dessas duas variantes? +Is there any difference in the behavior of these two variants? diff --git a/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md index fb1cf01ae..c8ee9618f 100644 --- a/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md +++ b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md @@ -1,17 +1,17 @@ -Usando operador de interrogação `'?'`: +Using a question mark operator `'?'`: ```js function checkAge(age) { - return (age > 18) ? true : confirm('Seus pais permitiram?'); + return (age > 18) ? true : confirm('Did parents allow you?'); } ``` -Usando OR `||` (A variante mais curta): +Using OR `||` (the shortest variant): ```js function checkAge(age) { - return (age > 18) || confirm('Seus pais permitiram?'); + return (age > 18) || confirm('Did parents allow you?'); } ``` -Note que os parêntesis em volta de `age > 18` não são obrigatórios aqui. Eles existem para melhor legibilidade. +Note that the parentheses around `age > 18` are not required here. They exist for better readabilty. diff --git a/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md index f59647409..46da079c0 100644 --- a/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md +++ b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md @@ -2,25 +2,25 @@ importance: 4 --- -# Reescreva a função usando '?' ou '||' +# Rewrite the function using '?' or '||' -A função a seguir retorna `true` se o parâmetro `age` é maior que `18`. +The following function returns `true` if the parameter `age` is greater than `18`. -Caso contrário, pede por uma confirmação e retorna seu resultado. +Otherwise it asks for a confirmation and returns its result. ```js function checkAge(age) { if (age > 18) { return true; } else { - return confirm('Você tem permissão de seus pais para acessar esta página?'); + return confirm('Did parents allow you?'); } } ``` -Reescreva, para executar a mesma, mas sem `if`, em uma única linha. +Rewrite it, to perform the same, but without `if`, in a single line. -Faça duas variantes de `checkAge`: +Make two variants of `checkAge`: -1. Usando um operador de interrogação `?` -2. Usando OR `||` +1. Using a question mark operator `?` +2. Using OR `||` diff --git a/1-js/02-first-steps/15-function-basics/4-pow/task.md b/1-js/02-first-steps/15-function-basics/4-pow/task.md index f75772567..f569320c7 100644 --- a/1-js/02-first-steps/15-function-basics/4-pow/task.md +++ b/1-js/02-first-steps/15-function-basics/4-pow/task.md @@ -2,9 +2,9 @@ importance: 4 --- -# Função pow(x,n) +# Function pow(x,n) -Escreva uma função `pow(x,n)` que retorna `x` no expoente `n`. Ou, em outras palavras, multiplica `x` por si mesmo `n` vezes e retorna um resultado. +Write a function `pow(x,n)` that returns `x` in power `n`. Or, in other words, multiplies `x` by itself `n` times and returns the result. ```js pow(3, 2) = 3 * 3 = 9 @@ -12,8 +12,8 @@ pow(3, 3) = 3 * 3 * 3 = 27 pow(1, 100) = 1 * 1 * ...* 1 = 1 ``` -Crie uma página web que solicite `x` e `n`, em seguida, mostre o resultado de `pow(x,n)`. +Create a web-page that prompts for `x` and `n`, and then shows the result of `pow(x,n)`. [demo] -P.S. Nesta tarefa, a função deve suportar apenas valores naturais de `n`: inteiros acima de` 1`. +P.S. In this task the function should support only natural values of `n`: integers up from `1`. diff --git a/1-js/02-first-steps/15-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md index f13127a16..843cb43bf 100644 --- a/1-js/02-first-steps/15-function-basics/article.md +++ b/1-js/02-first-steps/15-function-basics/article.md @@ -22,7 +22,11 @@ function showMessage() { A palavra-chave `function` vem primeiro, depois vem o *nome da função*, e uma lista de *parâmetros* entre os parêntesis (vazio no exemplo acima) e finalmente o código da função, também chamado de "o corpo da função", entre chaves. -![](function_basics.png) +```js +function name(parameters) { + ...corpo... +} +``` Nossa nova função pode ser chamada pelo seu nome: `showMessage()`. @@ -101,7 +105,7 @@ showMessage(); alert( userName ); // *!*Bob*/!*, the value was modified by the function ``` -The outer variable is only used if there's no local one. So an occasional modification may happen if we forget `let`. +The outer variable is only used if there's no local one. If a same-named variable is declared inside the function then it *shadows* the outer one. For instance, in the code below the function uses the local `userName`. The outer one is ignored: @@ -128,7 +132,7 @@ Variables declared outside of any function, such as the outer `userName` in the Global variables are visible from any function (unless shadowed by locals). -Usually, a function declares all variables specific to its task. Global variables only store project-level data, and it's important that these variables are accessible from anywhere. Modern code has few or no globals. Most variables reside in their functions. +It's a good practice to minimize the use of global variables. Modern code has few or no globals. Most variables reside in their functions. Sometimes though, they can be useful to store project-level data. ``` ## Parameters @@ -205,42 +209,53 @@ function showMessage(from, text = anotherFunction()) { ``` ```smart header="Evaluation of default parameters" +In JavaScript, a default parameter is evaluated every time the function is called without the respective parameter. -In JavaScript, a default parameter is evaluated every time the function is called without the respective parameter. In the example above, `anotherFunction()` is called every time `showMessage()` is called without the `text` parameter. This is in contrast to some other languages like Python, where any default parameters are evaluated only once during the initial interpretation. - +In the example above, `anotherFunction()` is called every time `showMessage()` is called without the `text` parameter. ``` +### Alternative default parameters -````smart header="Default parameters old-style" -Old editions of JavaScript did not support default parameters. So there are alternative ways to support them, that you can find mostly in the old scripts. +Sometimes it makes sense to set default values for parameters not in the function declaration, but at a later stage, during its execution. -For instance, an explicit check for being `undefined`: +To check for an omitted parameter, we can compare it with `undefined`: -```js -function showMessage(from, text) { +```js run +function showMessage(text) { *!* if (text === undefined) { - text = 'no text given'; + text = 'empty message'; } */!* - alert( from + ": " + text ); + alert(text); } + +showMessage(); // empty message ``` -...Or the `||` operator: +...Or we could use the `||` operator: ```js -function showMessage(from, text) { - // if text is falsy then text gets the "default" value - text = text || 'no text given'; +// if text parameter is omitted or "" is passed, set it to 'empty' +function showMessage(text) { + text = text || 'empty'; ... } ``` +Modern JavaScript engines support the [nullish coalescing operator](info:nullish-coalescing-operator) `??`, it's better when falsy values, such as `0`, are considered regular: -```` +```js run +// if there's no "count" parameter, show "unknown" +function showCount(count) { + alert(count ?? "unknown"); +} +showCount(0); // 0 +showCount(null); // unknown +showCount(); // unknown +``` ## Returning a value @@ -263,7 +278,7 @@ There may be many occurrences of `return` in a single function. For instance: ```js run function checkAge(age) { - if (age > 18) { + if (age >= 18) { *!* return true; */!* @@ -335,7 +350,19 @@ That doesn't work, because JavaScript assumes a semicolon after `return`. That'l return*!*;*/!* (some + long + expression + or + whatever * f(a) + f(b)) ``` -So, it effectively becomes an empty return. We should put the value on the same line instead. + +So, it effectively becomes an empty return. + +If we want the returned expression to wrap across multiple lines, we should start it at the same line as `return`. Or at least put the opening parentheses there as follows: + +```js +return ( + some + long + expression + + or + + whatever * f(a) + f(b) + ) +``` +And it will work just as we expect it to. ```` ## Naming a function [#function-naming] @@ -376,7 +403,7 @@ A few examples of breaking this rule: - `createForm` -- would be bad if it modifies the document, adding a form to it (should only create it and return). - `checkPermission` -- would be bad if it displays the `access granted/denied` message (should only perform the check and return the result). -These examples assume common meanings of prefixes. What they mean for you is determined by you and your team. Maybe it's pretty normal for your code to behave differently. But you should have a firm understanding of what a prefix means, what a prefixed function can and cannot do. All same-prefixed functions should obey the rules. And the team should share the knowledge. +These examples assume common meanings of prefixes. You and your team are free to agree on other meanings, but usually they're not much different. In any case, you should have a firm understanding of what a prefix means, what a prefixed function can and cannot do. All same-prefixed functions should obey the rules. And the team should share the knowledge. ``` ```smart header="Ultrashort function names" diff --git a/1-js/02-first-steps/16-function-expressions/article.md b/1-js/02-first-steps/16-function-expressions/article.md index 7e03a028e..a8ccd6c6c 100644 --- a/1-js/02-first-steps/16-function-expressions/article.md +++ b/1-js/02-first-steps/16-function-expressions/article.md @@ -1,84 +1,84 @@ -# Expressões de função e Arrow functions +# Function expressions -Em JavaScript, uma função não é uma "estrutura mágica da linguagem", mas um tipo especial de valor. +In JavaScript, a function is not a "magical language structure", but a special kind of value. -A sintaxe que usámos antes é chamada de *Declaração de Função* (*Function Declaration*): +The syntax that we used before is called a *Function Declaration*: ```js function sayHi() { - alert( "Olá" ); + alert( "Hello" ); } ``` -Existe outra sintaxe para criar uma função que é chamada de *Expressão de Função* (*Function Expression*). +There is another syntax for creating a function that is called a *Function Expression*. -É similar a: +It looks like this: ```js let sayHi = function() { - alert( "Olá" ); + alert( "Hello" ); }; ``` -Aqui, a função é criada e atribuida explícitamente à variável, como qualquer outro valor. Não importa como a função é definida, é apenas um valor atribuido a uma variável `sayHi`. +Here, the function is created and assigned to the variable explicitly, like any other value. No matter how the function is defined, it's just a value stored in the variable `sayHi`. -O significado destas amostras de código é o mesmo: "crie uma função e a coloque na variável `sayHi`". +The meaning of these code samples is the same: "create a function and put it into the variable `sayHi`". -Podemos até exibir esse valor usando `alert`: +We can even print out that value using `alert`: ```js run function sayHi() { - alert( "Olá" ); + alert( "Hello" ); } *!* -alert( sayHi ); // mostra o código da função +alert( sayHi ); // shows the function code */!* ``` -Por favor, note que a última linha não executa a função, porque não existem parênteses depois de `sayHi`. Existem linguagens de programação onde qualquer menção ao nome de uma função provoca a sua execução, mas em JavaScript não é assim. +Please note that the last line does not run the function, because there are no parentheses after `sayHi`. There are programming languages where any mention of a function name causes its execution, but JavaScript is not like that. -Em JavaScript, uma função é um valor, então podemos lidar com ela como com um valor. O código acima mostra a sua representação em formato de texto (string), que é o código fonte. +In JavaScript, a function is a value, so we can deal with it as a value. The code above shows its string representation, which is the source code. -Óbviamente que é um valor especial, porque podemos invocá-lo usando `sayHi()`. +Surely, a function is a special value, in the sense that we can call it like `sayHi()`. -Mas ainda assim é um valor. Então, podemos manuseá-lo como com outros tipos de valores. +But it's still a value. So we can work with it like with other kinds of values. -Podemos copiar uma função para outra variável: +We can copy a function to another variable: ```js run no-beautify -function sayHi() { // (1) crie - alert( "Olá" ); +function sayHi() { // (1) create + alert( "Hello" ); } -let func = sayHi; // (2) copie +let func = sayHi; // (2) copy -func(); // Olá // (3) execute a cópia (funciona)! -sayHi(); // Olá // isto também ainda funciona (porque não?) +func(); // Hello // (3) run the copy (it works)! +sayHi(); // Hello // this still works too (why wouldn't it) ``` -Aqui está o que acima acontece, em detalhe: +Here's what happens above in detail: -1. A Declaração de Função `(1)` cria uma função e a coloca na variável chamada `sayHi`. -2. Na linha em `(2)` é copiada para a variável `func`. +1. The Function Declaration `(1)` creates the function and puts it into the variable named `sayHi`. +2. Line `(2)` copies it into the variable `func`. Please note again: there are no parentheses after `sayHi`. If there were, then `func = sayHi()` would write *the result of the call* `sayHi()` into `func`, not *the function* `sayHi` itself. +3. Now the function can be called as both `sayHi()` and `func()`. - Por favor, note outra vez: não existem parênteses depois de `sayHi`. Se os houvessem, então `func = sayHi()` escreveria *o resultado da chamada* `sayHi()` em `func`, não a própria *função* `sayHi`. -3. Agora, a função pode ser invocada tanto como `sayHi()` como `func()`. - -Note que poderíamos também ter uma Expressão de Função para declarar `sayHi`, na primeira linha: +Note that we could also have used a Function Expression to declare `sayHi`, in the first line: ```js -let sayHi = function() { ... }; +let sayHi = function() { + alert( "Hello" ); +}; let func = sayHi; // ... ``` -Tudo funcionaria do mesmo modo. Seria ainda mais óbvio o que se passa, não? +Everything would work the same. ````smart header="Why is there a semicolon at the end?" -Poderá perguntar-se, porque terá uma Expressão de Função um ponto-e-vírgula `;` no final, mas a Declaração de Função não: +You might wonder, why does Function Expression have a semicolon `;` at the end, but Function Declaration does not: ```js function sayHi() { @@ -90,27 +90,27 @@ let sayHi = function() { }*!*;*/!* ``` -A resposta é simples: -- Não há necessidade para um `;` no fim de blocos de código e estruturas sintáticas que os usem como `if { ... }`, `for { }`, `function f { }` etc. -- Uma Expressão de Função é usada dentro de uma instrução: `let sayHi = ...;`, tal como o é um valor. Não é um bloco de código. O ponto-e-vírgula é recomendado no final de instruções, independentemente do seu valor. Assim, o ponto-e-vírgula aqui não está relacionado à Função de Expressão em si, mas simplesmente termina a instrução. +The answer is simple: +- There's no need for `;` at the end of code blocks and syntax structures that use them like `if { ... }`, `for { }`, `function f { }` etc. +- A Function Expression is used inside the statement: `let sayHi = ...;`, as a value. It's not a code block, but rather an assignment. The semicolon `;` is recommended at the end of statements, no matter what the value is. So the semicolon here is not related to the Function Expression itself, it just terminates the statement. ```` ## Callback functions -Vejamos mais exemplos de passagem de funções como valores e de uso de expressões de função. +Let's look at more examples of passing functions as values and using function expressions. -Escreveremos uma função `ask(question, yes, no)` com três parametros: +We'll write a function `ask(question, yes, no)` with three parameters: `question` -: Texto da questão +: Text of the question `yes` -: Função a executar se a resposta for "Sim" +: Function to run if the answer is "Yes" `no` -: Função a executar se a resposta for "Não" +: Function to run if the answer is "No" -A função deverá efetuar a `question` e, dependendo da resposta do utilizador, chamar `yes()` ou `no()`: +The function should ask the `question` and, depending on the user's answer, call `yes()` or `no()`: ```js run *!* @@ -121,24 +121,24 @@ function ask(question, yes, no) { */!* function showOk() { - alert( "Você concordou." ); + alert( "You agreed." ); } function showCancel() { - alert( "Você cancelou a execução." ); + alert( "You canceled the execution." ); } -// uso: as funções showOk, showCancel são passadas como argumentos a ask -ask("Você concorda?", showOk, showCancel); +// usage: functions showOk, showCancel are passed as arguments to ask +ask("Do you agree?", showOk, showCancel); ``` -Antes de explorarmos em como poderemos escrevê-lo de uma forma mais curta, convém notar que no navegador [browser] (e em certos casos do lado do servidor [server-side]) tais funções são muito populares. A maior difereça entre uma implementação em tempo-real [real-life] e o exemplo acima, é que funções em tempo-real usam formas mais complexas de interagir com o utilizador do que um simples `confirm`. No navegador, geralmente tal função desenha uma agradável janela contendo a questão a formular. Mas isso é outra história. +In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such function usually draws a nice-looking question window. But that's another story. -**Os argumentos de `ask` são chamados de *funções de retorno de chamada* (callback functions) ou apenas *callbacks*.** +**The arguments `showOk` and `showCancel` of `ask` are called *callback functions* or just *callbacks*.** -A ideia é que nós passamos uma função e esperamos que ela seja "chamada" mais tarde se necessário. No nosso caso, `showOk` se torna na função de retorno de chamada (callback) para a resposta "yes", e `showCancel` para a resposta "no". +The idea is that we pass a function and expect it to be "called back" later if necessary. In our case, `showOk` becomes the callback for "yes" answer, and `showCancel` for "no" answer. -Podemos utilizar Expressões de Funções para escrever uma versão mais curta da mesma função: +We can use Function Expressions to write the same function much shorter: ```js run no-beautify function ask(question, yes, no) { @@ -148,330 +148,221 @@ function ask(question, yes, no) { *!* ask( - "Você concorda?", - function() { alert("Você concordou."); }, - function() { alert("Você cancelou a execução."); } + "Do you agree?", + function() { alert("You agreed."); }, + function() { alert("You canceled the execution."); } ); */!* ``` -Aqui, as funções são declaradas justamente dentro da chamada a `ask(...)`. Elas não têm nome, e por isso são chamadas de *anónimas*. Tais funções não podem ser acedidas fora de `ask` (porque não estão atribuidas a variáveis), mas é apenas o que queremos para aqui. - -Código semelhante aparece nos nossos programas (scripts) muito naturalmente, está no espírito de JavaScript. +Here, functions are declared right inside the `ask(...)` call. They have no name, and so are called *anonymous*. Such functions are not accessible outside of `ask` (because they are not assigned to variables), but that's just what we want here. +Such code appears in our scripts very naturally, it's in the spirit of JavaScript. ```smart header="A function is a value representing an \"action\"" -Valores comuns como cadeias-de-caráteres (strings) ou números representam os *dados*. +Regular values like strings or numbers represent the *data*. -Uma função pode ser tida como uma *ação*. +A function can be perceived as an *action*. -Podemos passá-la entre variáveis e executá-la quando pretendermos. +We can pass it between variables and run when we want. ``` -## Expressões de função vs Declarações de função +## Function Expression vs Function Declaration -Vamos formular diferenças chave entre Declarações de Função e Expressões. +Let's formulate the key differences between Function Declarations and Expressions. -Primeiro, a sintaxe: como verificar qual é qual no código. +First, the syntax: how to differentiate between them in the code. -- *Declaração de Função:* uma função, declarada como uma instrução em separado, no fluxo do código principal. +- *Function Declaration:* a function, declared as a separate statement, in the main code flow. ```js - // Declaração de Função + // Function Declaration function sum(a, b) { return a + b; } ``` -- *Expressão de Função:* uma função, criada dentro de uma expressão ou dentro de outra construção sintática. Aqui, a função é criada no lado direito da "expressão de atribuição" `=`: - +- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created at the right side of the "assignment expression" `=`: + ```js - // Expressão de Função + // Function Expression let sum = function(a, b) { return a + b; }; ``` -A mais subtil diferença é *quando* uma função é criada pelo interpretador de JavaScript [JavaScript engine]. +The more subtle difference is *when* a function is created by the JavaScript engine. -**Uma Expressão de Função é criada quando a execução chega até si, e é utilizável a partir daí.** +**A Function Expression is created when the execution reaches it and is usable only from that moment.** -Ao passar o fluxo de execução para o lado direito da atribuição `let sum = function…` -- aí é que é, a função é criada e pode ser utilizada (atribuida, chamada, etc.) a partir daí. +Once the execution flow passes to the right side of the assignment `let sum = function…` -- here we go, the function is created and can be used (assigned, called, etc. ) from now on. -Declarações de Função sao diferentes. +Function Declarations are different. -**Uma Declaração de Função é utilizável ao longo de todo o script/bloco de código.** +**A Function Declaration can be called earlier than it is defined.** -Por outras palavras, quando JavaScript se *prepara* para correr o programa (script) ou bloco de código, primeiro procura nele por Declarações de Função e cria as funções. Podemos pensar nisto como um "estágio de inicialização". +For example, a global Function Declaration is visible in the whole script, no matter where it is. -Após o processamento de todas as Declarações de Função, a execução prossegue. +That's due to internal algorithms. When JavaScript prepares to run the script, it first looks for global Function Declarations in it and creates the functions. We can think of it as an "initialization stage". -Como resultado, a função declarada como Declaração de Função pode ser chamada antes da sua definição no programa. +And after all Function Declarations are processed, the code is executed. So it has access to these functions. -Por exemplo, isto funciona: +For example, this works: ```js run refresh untrusted *!* -sayHi("John"); // Olá, John +sayHi("John"); // Hello, John */!* function sayHi(name) { - alert( `Olá, ${name}` ); + alert( `Hello, ${name}` ); } ``` -A Declaração de Função `sayHi` é criada quando JavaScript se prepara para iniciar o script e é visível em todo o lugar nele. +The Function Declaration `sayHi` is created when JavaScript is preparing to start the script and is visible everywhere in it. -...Se fosse uma Expressão de Função, então não funcionaria: +...If it were a Function Expression, then it wouldn't work: ```js run refresh untrusted *!* -sayHi("John"); // erro! +sayHi("John"); // error! */!* -let sayHi = function(name) { // (*) nenhuma mágica mais - alert( `Olá, ${name}` ); +let sayHi = function(name) { // (*) no magic any more + alert( `Hello, ${name}` ); }; ``` -As Expressões de Função são criadas quando a execução as alcança. O que aconteceria apenas na linha `(*)`. Tarde demais. +Function Expressions are created when the execution reaches them. That would happen only in the line `(*)`. Too late. -**Quando uma Declaração de Função é feita dentro de um bloco de código, ela é visível em todo o lugar dentro desse bloco. Mas não fora dele.** +Another special feature of Function Declarations is their block scope. -Por vezes, é prático declarar uma função local apenas necessária num dado bloco. Mas essa possibilidade também pode causar problemas. +**In strict mode, when a Function Declaration is within a code block, it's visible everywhere inside that block. But not outside of it.** -Por exemplo, imaginemos que precisamos de declarar uma função `welcome()` que dependa da variável `age` que obtemos durante o tempo de execução (runtime). E que planejamos utilizá-la algures mais tarde. +For instance, let's imagine that we need to declare a function `welcome()` depending on the `age` variable that we get during runtime. And then we plan to use it some time later. -O código abaixo não funciona: +If we use Function Declaration, it won't work as intended: ```js run -let age = prompt("Que idade tem?", 18); +let age = prompt("What is your age?", 18); -// condicionalmente declare uma função +// conditionally declare a function if (age < 18) { function welcome() { - alert("Olá!"); + alert("Hello!"); } } else { function welcome() { - alert("Saudações!"); + alert("Greetings!"); } } -// ...utilize-a mais tarde +// ...use it later *!* -welcome(); // Erro: welcome não está definida +welcome(); // Error: welcome is not defined */!* ``` -Isto porque uma Declaração de Função apenas é visível dentro do bloco de código onde reside. +That's because a Function Declaration is only visible inside the code block in which it resides. -Aqui está outro exemplo: +Here's another example: ```js run -let age = 16; // tenha 16 como um exemplo +let age = 16; // take 16 as an example if (age < 18) { *!* - welcome(); // \ (executa) + welcome(); // \ (runs) */!* // | function welcome() { // | - alert("Olá!"); // | Declaração de Função está disponível - } // | em todo o lugar no bloco onde é feita + alert("Hello!"); // | Function Declaration is available + } // | everywhere in the block where it's declared // | *!* - welcome(); // / (executa) + welcome(); // / (runs) */!* } else { - function welcome() { // para age = 16, esta "welcome" nunca é criada - alert("Saudações!"); + function welcome() { + alert("Greetings!"); } } -// Aqui estamos fora das chavetas, portanto não é -// possível ver-se uma Declaração de Função feita dentro delas. +// Here we're out of curly braces, +// so we can not see Function Declarations made inside of them. *!* -welcome(); // Erro: welcome não está definida +welcome(); // Error: welcome is not defined */!* ``` -O que poderemos fazer para tonar `welcome` visível fora do `if`? +What can we do to make `welcome` visible outside of `if`? -O correto seria empregar uma Função de Expressão e atribuir `welcome` a uma variável declarada fora do `if` e que tenha uma visibilidade adequada. +The correct approach would be to use a Function Expression and assign `welcome` to the variable that is declared outside of `if` and has the proper visibility. -Agora funciona como pretendido: +This code works as intended: ```js run -let age = prompt("Que idade tem?", 18); +let age = prompt("What is your age?", 18); let welcome; if (age < 18) { welcome = function() { - alert("Olá!"); + alert("Hello!"); }; } else { welcome = function() { - alert("Saudações!"); + alert("Greetings!"); }; } *!* -welcome(); // bem, agora +welcome(); // ok now */!* ``` -Ou poderíamos simplificar mais ainda utilizando o operador ponto-de-interrogação `?`: +Or we could simplify it even further using a question mark operator `?`: ```js run -let age = prompt("Que idade tem?", 18); +let age = prompt("What is your age?", 18); let welcome = (age < 18) ? - function() { alert("Olá!"); } : - function() { alert("Saudações!"); }; - -*!* -welcome(); // bem, agora -*/!* -``` - - -```smart header="When should you choose Function Declaration versus Function Expression?" -Como uma regra do polegar, quando precisarmos de declarar uma função, o primeiro a considerar é uma sintaxe de Declaração de Função, como utilizámos acima. Ela providencia mais liberdade para organizar o código, porque podemos chamar tais funções antes de serem declaradas. - - -Também é um pouco mais fácil procurar por `function f(…) {…}` no código do que `let f = function(…) {…}`. Declarações de Função "sobressaem" mais à vista. - -...Mas se por alguma razão uma Declaração de Função não nos for útil, (vimos um exemplo acima), então uma Expressão de Função será a escolha. -``` - - -## Arrow functions [#arrow-functions] - -Existe mais uma sintaxe muito simples e concisa para criar funções, e que frequentemente é melhor do que Expressões de Funções. É chamada de "Arrow functions", porque se assemelha a: - - -```js -let func = (arg1, arg2, ...argN) => expression -``` - -...Isto cria a função `func` com os argumentos `arg1..argN`, evalua a `expression` no lado direito utilizando os mesmos e retorna o seu resultado. - -Por outras palavras, é aproximadamente o mesmo que: - -```js -let func = function(arg1, arg2, ...argN) { - return expression; -}; -``` - -...Mas muito mais concisa. - -Vejamos um exemplo: - -```js run -let sum = (a, b) => a + b; - -/* A função seta é uma forma mais curta de: - -let sum = function(a, b) { - return a + b; -}; -*/ - -alert( sum(1, 2) ); // 3 - -``` - -Se tivermos apenas um argumento, então os parênteses podem ser omitidos, tornando-a ainda mais curta: + function() { alert("Hello!"); } : + function() { alert("Greetings!"); }; -```js run -// o mesmo que -// let double = function(n) { return n * 2 } *!* -let double = n => n * 2; +welcome(); // ok now */!* - -alert( double(3) ); // 6 -``` - -Se não houver argumentos, devem existir parênteses vazios (mas devem estar presentes): - -```js run -let sayHi = () => alert("Olá!"); - -sayHi(); -``` - -Arrow functions podem ser empregues da mesma forma que Expressões de Função. - -A exemplo, aqui re-escrito está o código com `welcome()`: - -```js run -let age = prompt("Que idade tem?", 18); - -let welcome = (age < 18) ? - () => alert('Olá') : - () => alert("Saudações!"); - -welcome(); // bem, agora ``` -Arrow functions podem parecer não familiares e não muito legíveis a princípio, mas isso rápidamente muda à medida que os olhos habituam-se à estrutura. - -Elas são muito convenientes para simples ações numa única-linha, quando estamos preguiçosos demais para escrever muitas palavras. - -```smart header="Multiline arrow functions" -Os exemplos acima tomaram argumentos à esqerda de `=>` e evaluaram a expressão à direita com eles. +```smart header="When to choose Function Declaration versus Function Expression?" +As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared. -Por vezes, precisamos de algo um pouco mais complexo, como múltiplas expressões e instruções. Também é possível, mas deveríamos envolvê-las em chavetas. Aí, usamos um `return` normal com elas. +That's also better for readability, as it's easier to look up `function f(…) {…}` in the code than `let f = function(…) {…};`. Function Declarations are more "eye-catching". -Desta forma: - -```js run -let sum = (a, b) => { // a chaveta abre uma função multi-linha - let result = a + b; -*!* - return result; // ao utilizarmos chavetas, usamos `return` para obter o resultado -*/!* -}; - -alert( sum(1, 2) ); // 3 -``` - -```smart header="More to come" -Aqui enaltecemos Arrow functions pela brevidade. Mas não é tudo! Arrow functions têm outras particulariedades interessantes. Voltaremos a elas mais adiante no capitulo . - -Por ora, podemos já usá-las para ações de única-linha e callbacks. +...But if a Function Declaration does not suit us for some reason, or we need a conditional declaration (we've just seen an example), then Function Expression should be used. ``` -## Sumário - -- Funções são valores. Elas podem ser atribuidas, copiadas ou declaradas em qualquer parte do código. -- Se a função for declarada como uma instrução separada no fluxo do código principal, é chamada de "Declaração de Função". -- Se a função for criada como parte de uma expressão, é chamada de "Expressão de função". -- Declarações de Função são processadas antes de um bloco de código ser executado. Elas são visíveis em qualquer lugar dentro do bloco. -- Expressões de função são criadas quando o fluxo de execução as alcança. - - -Na maior parte dos casos, quando precisarmos de declarar uma função, uma Declaração de Função é preferível, porque é visível antes da própria definição. Isso dá-nos mais flexibilidade para a organização do código, e geralmente é mais legível. +## Summary -Assim, deveríamos empregar uma Expressão de Função apenas quando a Declaração de Função não se adequasse à tarefa. Vimos alguns exemplos disso no capítulo, e veremos mais no futuro. +- Functions are values. They can be assigned, copied or declared in any place of the code. +- If the function is declared as a separate statement in the main code flow, that's called a "Function Declaration". +- If the function is created as a part of an expression, it's called a "Function Expression". +- Function Declarations are processed before the code block is executed. They are visible everywhere in the block. +- Function Expressions are created when the execution flow reaches them. -Arrow functions são apropriadas para ações única-linha. Elas vêm em dois sabores: +In most cases when we need to declare a function, a Function Declaration is preferable, because it is visible prior to the declaration itself. That gives us more flexibility in code organization, and is usually more readable. -1. Sem chavetas: `(...args) => expression` -- o lado direito é uma expressão: a função a evalua e retorna o resultado. -2. Com chavetas: `(...args) => { body }` -- chavetas permitem-nos escrever múltiplas instruções dentro da função, mas precisamos de um explícito `return` para retornar alguma coisa. +So we should use a Function Expression only when a Function Declaration is not fit for the task. We've seen a couple of examples of that in this chapter, and will see more in the future. diff --git a/1-js/02-first-steps/17-arrow-functions-basics/article.md b/1-js/02-first-steps/17-arrow-functions-basics/article.md index e0fb5bda5..6e896f620 100644 --- a/1-js/02-first-steps/17-arrow-functions-basics/article.md +++ b/1-js/02-first-steps/17-arrow-functions-basics/article.md @@ -1,16 +1,16 @@ -# Arrow functions, the basics +# Funções seta, o básico -There's another very simple and concise syntax for creating functions, that's often better than Function Expressions. +Existe outra sintaxe, muito simples e concisa, para criar funções, e que geralmente é melhor do que Expressões de Função. -It's called "arrow functions", because it looks like this: +É chamada de "funções seta" (*"arrow functions"*), porque tem este aspeto: ```js let func = (arg1, arg2, ...argN) => expression ``` -...This creates a function `func` that accepts arguments `arg1..argN`, then evaluates the `expression` on the right side with their use and returns its result. +...Isto, cria a função `func` com os argumentos `arg1..argN`, depois avalia a `expression` no lado direito usando os mesmos, e retorna o seu resultado. -In other words, it's the shorter version of: +Por outras palavras, é a versão mais curta de: ```js let func = function(arg1, arg2, ...argN) { @@ -18,12 +18,12 @@ let func = function(arg1, arg2, ...argN) { }; ``` -Let's see a concrete example: +Vejamos um exemplo concreto: ```js run let sum = (a, b) => a + b; -/* This arrow function is a shorter form of: +/* Esta função seta é uma forma mais curta de: let sum = function(a, b) { return a + b; @@ -33,79 +33,79 @@ let sum = function(a, b) { alert( sum(1, 2) ); // 3 ``` -As you can, see `(a, b) => a + b` means a function that accepts two arguments named `a` and `b`. Upon the execution, it evaluates the expression `a + b` and returns the result. +Como pode ver, `(a, b) => a + b` significa uma função que aceita dois argumentos, nomeadamente `a` e `b`. No momento da execução, esta avalia a expressão `a + b` e retorna o resultado. -- If we have only one argument, then parentheses around parameters can be omitted, making that even shorter. +- Se tivermos apenas um argumento, então os parênteses à sua volta podem ser omitidos, tornando ela ainda mais curta. - For example: + Por exemplo: ```js run *!* let double = n => n * 2; - // roughly the same as: let double = function(n) { return n * 2 } + // aproximadamente o mesmo que: let double = function(n) { return n * 2 } */!* alert( double(3) ); // 6 ``` -- If there are no arguments, parentheses will be empty (but they should be present): +- Se não houver argumentos, os parênteses irão estar vazios (mas devem estar presentes): ```js run - let sayHi = () => alert("Hello!"); + let sayHi = () => alert("Olá!"); sayHi(); ``` -Arrow functions can be used in the same way as Function Expressions. +Funções seta podem ser empregues da mesma forma que Expressões de Função. -For instance, to dynamically create a function: +Por exemplo, para criar dinamicamente uma função: ```js run -let age = prompt("What is your age?", 18); +let age = prompt("Que idade tem?", 18); let welcome = (age < 18) ? - () => alert('Hello') : - () => alert("Greetings!"); + () => alert('Olá') : + () => alert("Saudações!"); welcome(); ``` -Arrow functions may appear unfamiliar and not very readable at first, but that quickly changes as the eyes get used to the structure. +Funções seta podem parecer não familiares e não muito legíveis a princípio, mas isso rápidamente muda à medida que os olhos se habituam à estrutura. -They are very convenient for simple one-line actions, when we're just too lazy to write many words. +Elas são muito convenientes para ações simples numa única-linha, quando estamos preguiçosos demais para escrever muitas palavras. -## Multiline arrow functions +## Funções seta de múltiplas linhas -The examples above took arguments from the left of `=>` and evaluated the right-side expression with them. +Os exemplos acima tomaram os argumentos à esquerda de `=>` e avaliaram a expressão à direita com eles. -Sometimes we need something a little bit more complex, like multiple expressions or statements. It is also possible, but we should enclose them in curly braces. Then use a normal `return` within them. +Por vezes, precisamos de algo um pouco mais complexo, como de múltiplas expressões ou instruções. Isso também é possível, mas devemos colocar elas dentro de chavetas. Depois, usamos um `return` normal com elas. -Like this: +Desta forma: ```js run -let sum = (a, b) => { // the curly brace opens a multiline function +let sum = (a, b) => { // a chaveta abre uma função multi-linha let result = a + b; *!* - return result; // if we use curly braces, then we need an explicit "return" + return result; // se usarmos chavetas, então precisamos de um "return" explícito */!* }; alert( sum(1, 2) ); // 3 ``` -```smart header="More to come" -Here we praised arrow functions for brevity. But that's not all! +```smart header="Mais à frente" +Aqui, enaltecemos funções seta pela sua brevidade. Mas não é só! -Arrow functions have other interesting features. +Funções seta têm outras funcionalidades interessantes. -To study them in-depth, we first need to get to know some other aspects of JavaScript, so we'll return to arrow functions later in the chapter . +Para as estudar com mais detalhe, primeiro precisamos de saber alguns outros aspetos de JavaScript, e desta forma vamos retornar a funções seta mais adiante no capitulo . -For now, we can already use arrow functions for one-line actions and callbacks. +Por ora, podemos já usar funções seta para ações numa única-linha e *callbacks*. ``` -## Summary +## Resumo -Arrow functions are handy for one-liners. They come in two flavors: +Funções seta são práticas para ações numa única-linha. Elas vêm em dois sabores: -1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result. -2. With curly braces: `(...args) => { body }` -- brackets allow us to write multiple statements inside the function, but we need an explicit `return` to return something. +1. Sem chavetas: `(...args) => expression` -- o lado direito é uma expressão: a função a avalia e retorna o resultado. +2. Com chavetas: `(...args) => { body }` -- chavetas nos permitem escrever múltiplas instruções dentro da função, mas precisamos de um explícito `return` para retornar alguma coisa. diff --git a/1-js/02-first-steps/18-javascript-specials/article.md b/1-js/02-first-steps/18-javascript-specials/article.md index e266861c7..97d0457bb 100644 --- a/1-js/02-first-steps/18-javascript-specials/article.md +++ b/1-js/02-first-steps/18-javascript-specials/article.md @@ -53,7 +53,7 @@ To fully enable all features of modern JavaScript, we should start scripts with ... ``` -The directive must be at the top of a script or at the beginning of a function. +The directive must be at the top of a script or at the beginning of a function body. Without `"use strict"`, everything still works, but some features behave in the old-fashion, "compatible" way. We'd generally prefer the modern behavior. @@ -81,9 +81,10 @@ let x = 5; x = "John"; ``` -There are 7 data types: +There are 8 data types: - `number` for both floating-point and integer numbers, +- `bigint` for integer numbers of arbitrary length, - `string` for strings, - `boolean` for logical values: `true/false`, - `null` -- a type with a single value `null`, meaning "empty" or "does not exist", @@ -103,7 +104,7 @@ More in: and . We're using a browser as a working environment, so basic UI functions will be: [`prompt(question, [default])`](mdn:api/Window/prompt) -: Ask a `question`, and return either what the visitor entered or `null` if they pressed "cancel". +: Ask a `question`, and return either what the visitor entered or `null` if they clicked "cancel". [`confirm(question)`](mdn:api/Window/confirm) : Ask a `question` and suggest to choose between Ok and Cancel. The choice is returned as `true/false`. @@ -143,13 +144,16 @@ Assignments : There is a simple assignment: `a = b` and combined ones like `a *= 2`. Bitwise -: Bitwise operators work with integers on bit-level: see the [docs](mdn:/JavaScript/Reference/Operators/Bitwise_Operators) when they are needed. +: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](mdn:/JavaScript/Guide/Expressions_and_Operators#Bitwise) when they are needed. -Ternary +Conditional : The only operator with three parameters: `cond ? resultA : resultB`. If `cond` is truthy, returns `resultA`, otherwise `resultB`. Logical operators -: Logical AND `&&` and OR `||` perform short-circuit evaluation and then return the value where it stopped. Logical NOT `!` converts the operand to boolean type and returns the inverse value. +: Logical AND `&&` and OR `||` perform short-circuit evaluation and then return the value where it stopped (not necessary `true`/`false`). Logical NOT `!` converts the operand to boolean type and returns the inverse value. + +Nullish coalescing operator +: The `??` operator provides a way to choose a defined value from a list of variables. The result of `a ?? b` is `a` unless it's `null/undefined`, then `b`. Comparisons : Equality check `==` for values of different types converts them to a number (except `null` and `undefined` that equal each other and nothing else), so these are equal: @@ -161,7 +165,7 @@ Comparisons Other comparisons convert to a number as well. - The strict equality operator `===` doesn't do the conversion: different types always mean different values for it, so: + The strict equality operator `===` doesn't do the conversion: different types always mean different values for it. Values `null` and `undefined` are special: they equal `==` each other and don't equal anything else. @@ -170,7 +174,7 @@ Comparisons Other operators : There are few others, like a comma operator. -More in: , , . +More in: , , , . ## Loops @@ -212,6 +216,7 @@ let age = prompt('Your age?', 18); switch (age) { case 18: alert("Won't work"); // the result of prompt is a string, not a number + break; case "18": alert("This works!"); @@ -245,11 +250,9 @@ We covered three ways to create a function in JavaScript: let result = a + b; return result; - } + }; ``` - Function expressions can have a name, like `sum = function name(a, b)`, but that `name` is only visible inside that function. - 3. Arrow functions: ```js @@ -274,13 +277,7 @@ We covered three ways to create a function in JavaScript: - Parameters can have default values: `function sum(a = 1, b = 2) {...}`. - Functions always return something. If there's no `return` statement, then the result is `undefined`. - -| Function Declaration | Function Expression | -|----------------------|---------------------| -| visible in the whole code block | created when the execution reaches it | -| - | can have a name, visible only inside the function | - -More: see , . +Details: see , . ## More to come diff --git a/1-js/03-code-quality/01-debugging-chrome/article.md b/1-js/03-code-quality/01-debugging-chrome/article.md index 6d5bbbed3..b2d0866f5 100644 --- a/1-js/03-code-quality/01-debugging-chrome/article.md +++ b/1-js/03-code-quality/01-debugging-chrome/article.md @@ -1,183 +1,196 @@ -# Debugging in Chrome +# Depuração de erros no Chrome -Before writing more complex code, let's talk about debugging. +Antes de escrevermos código mais complexo, vamos falar de debugging (depuração de erros). -All modern browsers and most other environments support "debugging" -- a special UI in developer tools that makes finding and fixing errors much easier. +[Depuração](https://pt.wikipedia.org/wiki/Depura%C3%A7%C3%A3o) é o processo de procura e correção de erros num programa. Todos os navegadores (*browsers*) modernos e muitas outras plataformas (*environments*) suportam ferramentas de *debugging* -- uma UI (Interface de Utilizador) especial disponível nas ferramentas do desenvolvedor (*developer tools*) que torna a depuração de erros muito mais fácil. Ela também permite rastrear o código passo-a-passo para ver exatamente o que está a ser executado. -We'll be using Chrome here, because it's probably the most feature-rich in this aspect. +Aqui, vamos utilizar o Chrome porque tem muitas funcionalidades, mas a maioria dos outros navegadores possui um processo similar. -## The "sources" pane +## O painel "*Sources*" -Your Chrome version may look a little bit different, but it still should be obvious what's there. +A versão do seu Chrome pode parecer um pouco diferente, mas ainda assim deverá ser óbvio o que lá encontre. -- Open the [example page](debugging/index.html) in Chrome. -- Turn on developer tools with `key:F12` (Mac: `key:Cmd+Opt+I`). -- Select the `sources` pane. +- Abra a [página exemplo](debugging/index.html) no Chrome. +- Ative as ferramentas do desenvolvedor com `key:F12` (Mac: `key:Cmd+Opt+I`). +- Selecione o painel `Sources`. -Here's what you should see if you are doing it for the first time: +Aqui está o que poderá ver, se o estiver a fazer pela primeira vez: ![](chrome-open-sources.svg) -The toggler button opens the tab with files. +O botão de alternador abre o separador com os ficheiros. -Let's click it and select `index.html` and then `hello.js` in the tree view. Here's what should show up: +Vamos clicar nele, e selecionar `hello.js` na vista de árvore de recursos apresentada. Aqui está o que deveria ser mostrado: ![](chrome-tabs.svg) -Here we can see three zones: +O painel *Sources* possui 3 partes: -1. The **Resources zone** lists HTML, JavaScript, CSS and other files, including images that are attached to the page. Chrome extensions may appear here too. -2. The **Source zone** shows the source code. -3. The **Information and control zone** is for debugging, we'll explore it soon. +1. O painel **File Navigator**, lista ficheiros de HTML, JavaScript, CSS e outros, incluindo imagens anexadas à página. Extensões ao Chrome (*Chrome extensions*) também podem aparecer aqui. +2. O painel **Code Editor**, mostra o código-fonte. +3. O painel **JavaScript Debugging**, é para a depuração de erros; iremos explorá-lo em breve. -Now you could click the same toggler again to hide the resources list and give the code some space. +Agora, poderia clicar novamente no mesmo botão de alternador para ocultar a lista de recursos e dar ao código algum espaço. -## Console +## Consola -If we press `Esc`, then a console opens below. We can type commands there and press `key:Enter` to execute. +Se pressionarmos `key:Esc`, uma consola se abre abaixo. Podemos aí digitar comandos e pressionar `key:Enter` para os executar. -After a statement is executed, its result is shown below. +Depois de uma instrução ser executada, o seu resultado é mostrado abaixo. -For example, here `1+2` results in `3`, and `hello("debugger")` returns nothing, so the result is `undefined`: +Por exemplo, aqui `1+2` resulta em `3`, e `hello("debugger")` não retorna nada, assim o seu resultado é `undefined`: ![](chrome-sources-console.svg) ## Breakpoints -Let's examine what's going on within the code of the [example page](debugging/index.html). In `hello.js`, click at line number `4`. Yes, right on the `4` digit, not on the code. +Vamos examinar o que se passa dentro do código da [página exemplo](debugging/index.html). Em `hello.js`, clique no número de linha `4`. Sim, exatamente sobre o dígito `4`, não sobre o código. -Congratulations! You've set a breakpoint. Please also click on the number for line `8`. +Parabéns! Estabeleceu um ponto-de-interrupção (*breakpoint*). Por favor, clique também no número de linha `8`. -It should look like this (blue is where you should click): +Deveria se parecer com (a azul é onde deveria ter clicado): ![](chrome-sources-breakpoint.svg) -A *breakpoint* is a point of code where the debugger will automatically pause the JavaScript execution. +Um *breakpoint* é um ponto no código onde o *debugger* (depurador de erros) irá automáticamente efetuar uma pausa na execução do JavaScript. -While the code is paused, we can examine current variables, execute commands in the console etc. In other words, we can debug it. +Enquanto a execução do código estiver suspensa, podemos examinar variáveis correntes, executar comandos na consola, etc. Por outras palavras, podemos nele depurar erros (*debug it*). -We can always find a list of breakpoints in the right pane. That's useful when we have many breakpoints in various files. It allows us to: -- Quickly jump to the breakpoint in the code (by clicking on it in the right pane). -- Temporarily disable the breakpoint by unchecking it. -- Remove the breakpoint by right-clicking and selecting Remove. -- ...And so on. +Podemos sempre encontrar uma lista de *breakpoints* no painel à direita. É útil quando temos muitos *breakpoints* em vários ficheiros. Ela permite-nos: +- Rápidamente saltar para a linha do breakpoint no código (ao clicar sobre ele no painel à direita). +- Temporáriamente desativar o breakpoint, ao desmarcá-lo (*unchecking it*). +- Remover o breakpoint, clicando com o botão direito do rato e selecionando *Remove*. +- ...E assim por diante. -```smart header="Conditional breakpoints" -*Right click* on the line number allows to create a *conditional* breakpoint. It only triggers when the given expression is truthy. +```smart header="*Breakpoints* condicionais" +*Clicando com o botão direito do rato* sobre um número de linha permite-nos criar um *breakpoint condicional*. Apenas será ativado quando a expressão inserida for verdadeira. -That's handy when we need to stop only for a certain variable value or for certain function parameters. +É prático quando apenas precisarmos de parar para um certo valor numa variável, ou para certos parâmetros numa função. ``` -## Debugger command +## O comando *debugger* -We can also pause the code by using the `debugger` command, like this: +Podemos também suspender o código utilizando o comando `debugger`, desta forma: ```js function hello(name) { - let phrase = `Hello, ${name}!`; + let phrase = `Olá, ${name}!`; *!* - debugger; // <-- the debugger stops here + debugger; // <-- o *debugger* (depurador de erros) pára aqui */!* say(phrase); } ``` -That's very convenient when we are in a code editor and don't want to switch to the browser and look up the script in developer tools to set the breakpoint. +É muito conveniente quando estivermos num editor de código e não quisermos mudar para o navegador, e de seguida, nas ferramentas do desenvolvedor deste, procurar no programa (*script*) pelo local onde colocar o breakpoint. -## Pause and look around +## Pause e dê uma vista de olhos -In our example, `hello()` is called during the page load, so the easiest way to activate the debugger is to reload the page. So let's press `key:F5` (Windows, Linux) or `key:Cmd+R` (Mac). +No nosso exemplo, `hello()` é chamada durante o carregamento da página, assim a forma mais fácil para ativar o *debugger* (depois de termos colocado os *breakpoints*) é recarregar a página. Assim, vamos pressionar `key:F5` (Windows, Linux) ou `key:Cmd+R` (Mac). -As the breakpoint is set, the execution pauses at the 4th line: +Como o breakpoint está estabelecido, é feita uma pausa na execução na quarta linha: ![](chrome-sources-debugger-pause.svg) -Please open the informational dropdowns to the right (labeled with arrows). They allow you to examine the current code state: +Por favor, abra as secções de *dropdown* informacionais à direita (possuem etiquetas em seta). Elas permitem examinar o estado atual do código: -1. **`Watch` -- shows current values for any expressions.** +1. **`Watch` -- mostra valores correntes de expressões.** - You can click the plus `+` and input an expression. The debugger will show its value at any moment, automatically recalculating it in the process of execution. + Pode clicar no mais `+` e inserir uma expressão. O *debugger* mostrará o seu valor em qualquer altura, e ele é automáticamente recalculado ao longo do processo de execução. -2. **`Call Stack` -- shows the nested calls chain.** +2. **`Call Stack` -- mostra a sequência de chamadas de funções aninhadas.** - At the current moment the debugger is inside `hello()` call, called by a script in `index.html` (no function there, so it's called "anonymous"). + No presente momento, o *debugger* está dentro da chamada a `hello()`, invocada por código em `index.html` (não a partir de uma função, por isso o nome "*anonymous*" [anónimo]). - If you click on a stack item, the debugger jumps to the corresponding code, and all its variables can be examined as well. -3. **`Scope` -- current variables.** + Se clicar num item nessa pilha (*stack*) (por exemplo, em "*anonymous*"), o *debugger* saltará para o código correspondente, e todas as suas variáveis poderão ser igualmente examinadas. +3. **`Scope` -- variables atuais.** - `Local` shows local function variables. You can also see their values highlighted right over the source. + `Local` mostra variáveis locais de funções. Também, poderá ver os seus valores em destaque exatamente sobre o código-fonte. - `Global` has global variables (out of any functions). + `Global` possui variáveis globais (aquelas fora de qualquer função). - There's also `this` keyword there that we didn't study yet, but we'll do that soon. + Lá também existe a palavra-chave `this` que ainda não estudámos, mas o faremos em breve. -## Tracing the execution +## Rastreando a execução -Now it's time to *trace* the script. +Agora, é altura para *rastrearmos* (*trace*) o código. -There are buttons for it at the top of the right pane. Let's engage them. +Existem botões para isso no topo do painel direito. Vamos interagir com eles. + + -- "Resume": continue a execução, atalho (*hotkey*) `key:F8`. +: Retoma a execução. Se não houver *breakpoints* adicionais, a execução simplesmente prossegue e o *debugger* perde o controlo. - -- continue the execution, hotkey `key:F8`. -: Resumes the execution. If there are no additional breakpoints, then the execution just continues and the debugger loses control. - - Here's what we can see after a click on it: + Aqui está o que poderemos ver após um clique sobre ele: ![](chrome-sources-debugger-trace-1.svg) - The execution has resumed, reached another breakpoint inside `say()` and paused there. Take a look at the "Call stack" at the right. It has increased by one more call. We're inside `say()` now. + A execução prosseguiu, atingiu outro *breakpoint* dentro de `say()` e fez uma pausa lá. Dê uma vista de olhos sobre a "*Call stack*" à direita. Aumentou por mais uma chamada. Estamos dentro de `say()` agora. + + -- "Step": execute o próximo comando, atalho (*hotkey*) `key:F9`. +: Executa a próxima instrução. Se o clicarmos agora, o `alert` será mostrado. + + Continuando a clicar nele, passará por todas as instruções do programa, uma por uma. + + -- "Step over": execute o próximo comando, mas *mas não vá para dentro de uma função*, atalho `key:F10`. +: Similar ao comando "Step" anterior, mas com um comportamento diferente se a próxima instrução for uma chamada de função. Isto é: não uma incorporada (*built-in*), como `alert`, mas uma função sua. + + O comando "Step", vai para dentro dela e suspende a execução na sua primeira linha, ao contrário de "Step over" que executa essa chamada de função aninhada invisívelmente, saltando sobre o funcionamento interno da função. + + É feita uma pausa na execução imediatamente depois dessa função. + + É bom, se não estivermos interessados em ver o que acontece dentro da chamada de função. - -- make a step (run the next command), but *don't go into the function*, hotkey `key:F10`. -: If we click it now, `alert` will be shown. The important thing is that `alert` can be any function, the execution "steps over it", skipping the function internals. + -- "Step into", atalho `key:F11`. +: Similar a "Step", mas com um comportamento diferente no caso de chamadas de funções assíncronas. Se estiver a começar a aprender JavaScript, então poderá ignorar a diferença, porque ainda não temos chamadas assíncronas. - -- make a step, hotkey `key:F11`. -: The same as the previous one, but "steps into" nested functions. Clicking this will step through all script actions one by one. + Para o futuro, apenas tome nota que o comando "Step" ignora ações assíncronas, tais como `setTimeout` (chamada de função agendada), que são executadas mais tarde. O "Step into", vai para dentro dos seus códigos, esperando pela sua execução se necessário. Para mais detalhes, veja o [DevTools manual](https://developers.google.com/web/updates/2018/01/devtools#async). - -- continue the execution till the end of the current function, hotkey `key:Shift+F11`. -: The execution would stop at the very last line of the current function. That's handy when we accidentally entered a nested call using , but it does not interest us, and we want to continue to its end as soon as possible. + -- "Step out": continue a execução até ao fim da função atual, atalho `key:Shift+F11`. +: Continue a execução e a faça uma pausa na última linha da função atual. É útil quando acidentalmente entrámos para uma chamada aninhada usando , mas ela não nos interessa, e queremos prosseguir para o seu final o mais rápidamente possível. - -- enable/disable all breakpoints. -: That button does not move the execution. Just a mass on/off for breakpoints. + -- ative/desative todos os *breakpoints*. +: Esse botão não move a execução. Simplesmente liga/desliga *breakpoints* em grupo. - -- enable/disable automatic pause in case of an error. -: When enabled, and the developer tools is open, a script error automatically pauses the execution. Then we can analyze variables to see what went wrong. So if our script dies with an error, we can open debugger, enable this option and reload the page to see where it dies and what's the context at that moment. + -- ative/desative a pausa automática em caso de erro. +: Quando ativo, e as ferramentas do desenvolvedor estiverem abertas, um erro no código automáticamente suspende a sua execução. Então, poderemos analisar variáveis para ver o que ocorreu de errado. Assim, se o código falhar por um erro, pode-se abrir o *debugger*, ativar esta opção e recarregar a página, afim de se observar onde falhou e qual o contexto nesse momento. -```smart header="Continue to here" -Right click on a line of code opens the context menu with a great option called "Continue to here". +```smart header="Continue até aqui" +Ao clicar com o botão direito do rato sobre uma linha de código, abre-se o menu de contexto com uma valiosa opção com o nome "Continue até aqui" (*Continue to here*). -That's handy when we want to move multiple steps forward, but we're too lazy to set a breakpoint. +É prática quando quisermos mover adiante por múltiplos passos até essa linha, mas estamos preguiçosos demais para estabelecer um *breakpoint*. ``` ## Logging -To output something to console, there's `console.log` function. +Para mostrar na consola algo existente no código, existe a função `console.log`. -For instance, this outputs values from `0` to `4` to console: +Por exemplo, isto mostra os valores de `0` a `4` na consola: ```js run -// open console to see +// abra a consola para visualizar for (let i = 0; i < 5; i++) { - console.log("value", i); + console.log("valor,", i); } ``` -Regular users don't see that output, it is in the console. To see it, either open the Console tab of developer tools or press `key:Esc` while in another tab: that opens the console at the bottom. +Utilizadores comuns não vêm essa saída (*output*), ela estará na consola. Para a ver, abra o separador Console nas ferramentas do desenvolvedor, ou pressione `key:Esc` se estiver num outro separador - isso abre a consola abaixo nesse separador. -If we have enough logging in our code, then we can see what's going on from the records, without the debugger. +Se mostrarmos mensagens (*logging*) suficientes no nosso código, então poderemos ver o que nele se passa a partir desses registos, dispensando o *debugger*. -## Summary +## Resumo -As we can see, there are three main ways to pause a script: -1. A breakpoint. -2. The `debugger` statements. -3. An error (if dev tools are open and the button is "on"). +Como podemos ver, existem três formas principais para fazer uma pausa num *script*: +1. Um *breakpoint* (ponto-de-interrupção). +2. As instruções `debugger`. +3. Um erro (se as ferramentas do desenvolvedor [*dev tools*] estiverem abertas, e o botão estiver "ativo"). -Then we can examine variables and step on to see where the execution goes wrong. +Enquanto suspenso, podemos depurar erros - examinar variáveis e rastear o código para ver onde a sua execução contém erros. -There are many more options in developer tools than covered here. The full manual is at . +Existem muitas mais opções nas ferramentas do desenvolvedor do que as cobertas aqui. O manual completo está em . -The information from this chapter is enough to begin debugging, but later, especially if you do a lot of browser stuff, please go there and look through more advanced capabilities of developer tools. +A informação neste capítulo é suficiente para iniciar a depuração de erros (o *debugging*), mas mais tarde, especialmente se trabalhar muito com o navegador (*browser*), por favor consulte o manual e procure por capacidades mais avançadas de ferramentas do desenvolvedor. -Oh, and also you can click at various places of dev tools and just see what's showing up. That's probably the fastest route to learn dev tools. Don't forget about the right click as well! +Oh, também pode clicar em vários locais nas *dev tools* e ver o que acontece. Provávelmente, é a rota mais rápida para aprender sobre as *dev tools*. Não se esqueça de também clicar com o botão direito do rato e dos menus de contexto! diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg index dcb627c6f..1f7d21288 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg @@ -1,15 +1 @@ - - - - chrome-open-sources.svg - Created with sketchtool. - - - - - open sources - - - - - \ No newline at end of file +open sources \ No newline at end of file diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg index f19e38887..6fb4332f1 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg @@ -1,20 +1 @@ - - - - chrome-sources-breakpoint.svg - Created with sketchtool. - - - - - here's the list - - - breakpoints - - - - - - - \ No newline at end of file +here's the listbreakpoints \ No newline at end of file diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.svg index 9d84cab9d..25284d055 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.svg @@ -1,14 +1 @@ - - - - chrome-sources-console.svg - Created with sketchtool. - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.svg index af5384e65..40d9515ab 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.svg @@ -1,67 +1 @@ - - - - chrome-sources-debugger-pause.svg - Created with sketchtool. - - - 2 - - - - - - - - - 1 - - - - - - - - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - jump to the outer function - - - watch expressions - - - current variables - - - - - - - \ No newline at end of file +213see the outer call detailswatch expressionscurrent variables \ No newline at end of file diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg index c5994d047..0d5bde9c4 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg @@ -1,15 +1 @@ - - - - chrome-sources-debugger-trace-1.svg - Created with sketchtool. - - - - - nested calls - - - - - \ No newline at end of file +nested calls \ No newline at end of file diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.svg index 27ec55203..352fbcb7c 100644 --- a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.svg +++ b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.svg @@ -1,55 +1 @@ - - - - chrome-tabs.svg - Created with sketchtool. - - - 2 - - - - - - - - - 1 - - - - - - - - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +213 \ No newline at end of file diff --git a/1-js/03-code-quality/01-debugging-chrome/debugging.view/hello.js b/1-js/03-code-quality/01-debugging-chrome/debugging.view/hello.js index 4236740e8..22e46cc69 100644 --- a/1-js/03-code-quality/01-debugging-chrome/debugging.view/hello.js +++ b/1-js/03-code-quality/01-debugging-chrome/debugging.view/hello.js @@ -1,5 +1,5 @@ function hello(name) { - let phrase = `Hello, ${name}!`; + let phrase = `Olá, ${name}!`; say(phrase); } diff --git a/1-js/03-code-quality/01-debugging-chrome/debugging.view/index.html b/1-js/03-code-quality/01-debugging-chrome/debugging.view/index.html index 6c651e854..ec0accebd 100644 --- a/1-js/03-code-quality/01-debugging-chrome/debugging.view/index.html +++ b/1-js/03-code-quality/01-debugging-chrome/debugging.view/index.html @@ -4,7 +4,7 @@ - An example for debugging. + Um exemplo para depuração de erros. - + - + - +
- + diff --git a/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js b/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js index cad51d3ee..08e27c9fd 100644 --- a/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js @@ -1,12 +1,17 @@ -describe("test", function() { +describe("teste", function() { + // Mocha, geralmente espera pelos testes por 2 segundos antes de os considerar errados - before(() => alert("Testing started – before all tests")); - after(() => alert("Testing finished – after all tests")); + this.timeout(200000); // Com este código nós aumentamos esse tempo - neste caso, para 200,000 + + // Isto, por causa da função "alert", porque se você se demorar a pressionar o botão "OK" oos testes não irão passar! - beforeEach(() => alert("Before a test – enter a test")); - afterEach(() => alert("After a test – exit a test")); + before(() => alert("Testes iniciados – antes de todos os testes")); + after(() => alert("Testes terminados – depois de todos os testes")); - it('test 1', () => alert(1)); - it('test 2', () => alert(2)); + beforeEach(() => alert("antes de um teste – entrando para um teste")); + afterEach(() => alert("depois de um teste – saindo de um teste")); + + it('teste 1', () => alert(1)); + it('teste 2', () => alert(2)); }); diff --git a/1-js/03-code-quality/05-testing-mocha/index.html b/1-js/03-code-quality/05-testing-mocha/index.html index 28a2ea62b..1670c8a58 100644 --- a/1-js/03-code-quality/05-testing-mocha/index.html +++ b/1-js/03-code-quality/05-testing-mocha/index.html @@ -1,36 +1,31 @@ - + - + - + - - - + - +
- + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-1.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-1.view/index.html index e48a8d3a2..c96134b83 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-1.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-1.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -21,17 +21,17 @@ - + - +
- + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-1.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-1.view/test.js index 89ba412ed..37be633db 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-1.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/pow-1.view/test.js @@ -1,6 +1,6 @@ describe("pow", function() { - it("raises to n-th power", function() { + it("eleva à n-ésima potência", function() { assert.equal(pow(2, 3), 8); }); diff --git a/1-js/03-code-quality/05-testing-mocha/pow-2.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-2.view/index.html index e8d6be23d..adbd7a482 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-2.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-2.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -21,17 +21,17 @@ - + - +
- + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-2.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-2.view/test.js index 9a2f8fde7..e75c688d4 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-2.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/pow-2.view/test.js @@ -1,11 +1,11 @@ describe("pow", function() { - it("2 raised to power 3 is 8", function() { + it("2 elevado à potência 3 é 8", function() { assert.equal(pow(2, 3), 8); }); - it("3 raised to power 3 is 27", function() { - assert.equal(pow(3, 3), 27); + it("3 elevado à potência 4 é 81", function() { + assert.equal(pow(3, 4), 81); }); }); diff --git a/1-js/03-code-quality/05-testing-mocha/pow-3.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-3.view/index.html index c71b0d5d5..29263c61c 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-3.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-3.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -31,13 +31,13 @@ } - + - +
- + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-3.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-3.view/test.js index 8663952aa..abeec5b5e 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-3.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/pow-3.view/test.js @@ -2,7 +2,7 @@ describe("pow", function() { function makeTest(x) { let expected = x * x * x; - it(`${x} in the power 3 is ${expected}`, function() { + it(`${x} na potência 3 é ${expected}`, function() { assert.equal(pow(x, 3), expected); }); } diff --git a/1-js/03-code-quality/05-testing-mocha/pow-4.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-4.view/index.html index c71b0d5d5..29263c61c 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-4.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-4.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -31,13 +31,13 @@ } - + - +
- + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js index e5ce2ce43..04249a56b 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js @@ -1,10 +1,10 @@ describe("pow", function() { - describe("raises x to power 3", function() { + describe("eleva x à potência 3", function() { function makeTest(x) { let expected = x * x * x; - it(`${x} in the power 3 is ${expected}`, function() { + it(`${x} na potência 3 é ${expected}`, function() { assert.equal(pow(x, 3), expected); }); } @@ -15,5 +15,5 @@ describe("pow", function() { }); - // ... more tests to follow here, both describe and it can be added + // ... mais testes aqui a seguir, ambos 'describe' e 'it' podem ser adicionados }); diff --git a/1-js/03-code-quality/05-testing-mocha/pow-full.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-full.view/index.html index 076b1e5a9..9a7ae12ca 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-full.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-full.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -32,13 +32,13 @@ } - + - +
- + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-full.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-full.view/test.js index 75ff5e99f..02b18647f 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-full.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/pow-full.view/test.js @@ -1,10 +1,10 @@ describe("pow", function() { - describe("raises x to power 3", function() { + describe("eleva x à potência 3", function() { function makeTest(x) { let expected = x * x * x; - it(`${x} in the power 3 is ${expected}`, function() { + it(`${x} na potência 3 é ${expected}`, function() { assert.equal(pow(x, 3), expected); }); } @@ -15,11 +15,11 @@ describe("pow", function() { }); - it("if n is negative, the result is NaN", function() { + it("se n for negativo, o resultado será NaN", function() { assert.isNaN(pow(2, -1)); }); - it("if n is not integer, the result is NaN", function() { + it("se n não for inteiro, o resultado será NaN", function() { assert.isNaN(pow(2, 1.5)); }); diff --git a/1-js/03-code-quality/05-testing-mocha/pow-min.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-min.view/index.html index d82a79dca..9af5ba188 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-min.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-min.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -21,17 +21,17 @@ - + - +
- + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-min.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-min.view/test.js index 89ba412ed..37be633db 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-min.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/pow-min.view/test.js @@ -1,6 +1,6 @@ describe("pow", function() { - it("raises to n-th power", function() { + it("eleva à n-ésima potência", function() { assert.equal(pow(2, 3), 8); }); diff --git a/1-js/03-code-quality/05-testing-mocha/pow-nan.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-nan.view/index.html index 523ae25ec..f582f3cde 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-nan.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-nan.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -29,13 +29,13 @@ } - + - +
- + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-nan.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-nan.view/test.js index 75ff5e99f..02b18647f 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-nan.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/pow-nan.view/test.js @@ -1,10 +1,10 @@ describe("pow", function() { - describe("raises x to power 3", function() { + describe("eleva x à potência 3", function() { function makeTest(x) { let expected = x * x * x; - it(`${x} in the power 3 is ${expected}`, function() { + it(`${x} na potência 3 é ${expected}`, function() { assert.equal(pow(x, 3), expected); }); } @@ -15,11 +15,11 @@ describe("pow", function() { }); - it("if n is negative, the result is NaN", function() { + it("se n for negativo, o resultado será NaN", function() { assert.isNaN(pow(2, -1)); }); - it("if n is not integer, the result is NaN", function() { + it("se n não for inteiro, o resultado será NaN", function() { assert.isNaN(pow(2, 1.5)); }); diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md index 907730fdc..7639b9bb4 100644 --- a/1-js/03-code-quality/06-polyfills/article.md +++ b/1-js/03-code-quality/06-polyfills/article.md @@ -1,5 +1,5 @@ -# Polyfills +# Polyfills and transpilers The JavaScript language steadily evolves. New proposals to the language appear regularly, they are analyzed and, if considered worthy, are appended to the list at and then progress to the [specification](http://www.ecma-international.org/publications/standards/Ecma-262.htm). @@ -9,49 +9,84 @@ So it's quite common for an engine to implement only the part of the standard. A good page to see the current state of support for language features is (it's big, we have a lot to study yet). -## Babel +As programmers, we'd like to use most recent features. The more good stuff - the better! -When we use modern features of the language, some engines may fail to support such code. Just as said, not all features are implemented everywhere. +From the other hand, how to make out modern code work on older engines that don't understand recent features yet? -Here Babel comes to the rescue. +There are two tools for that: -[Babel](https://babeljs.io) is a [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler). It rewrites modern JavaScript code into the previous standard. +1. Transpilers. +2. Polyfills. -Actually, there are two parts in Babel: +Here, in this chapter, our purpose is to get the gist of how they work, and their place in web development. -1. First, the transpiler program, which rewrites the code. The developer runs it on their own computer. It rewrites the code into the older standard. And then the code is delivered to the website for users. Modern project build system like [webpack](http://webpack.github.io/) or [brunch](http://brunch.io/) provide means to run transpiler automatically on every code change, so that doesn't involve any time loss from our side. +## Transpilers -2. Second, the polyfill. +A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that can parse ("read and understand") modern code, and rewrite it using older syntax constructs, so that the result would be the same. - The transpiler rewrites the code, so syntax features are covered. But for new functions we need to write a special script that implements them. JavaScript is a highly dynamic language, scripts may not just add new functions, but also modify built-in ones, so that they behave according to the modern standard. +E.g. JavaScript before year 2020 didn't have the "nullish coalescing operator" `??`. So, if a visitor uses an outdated browser, it may fail to understand the code like `height = height ?? 100`. - There's a term "polyfill" for scripts that "fill in" the gap and add missing implementations. +A transpiler would analyze our code and rewrite `height ?? 100` into `(height !== undefined && height !== null) ? height : 100`. - Two interesting polyfills are: - - [babel polyfill](https://babeljs.io/docs/usage/polyfill/) that supports a lot, but is big. - - [polyfill.io](http://polyfill.io) service that allows to load/construct polyfills on-demand, depending on the features we need. +```js +// before running the transpiler +height = height ?? 100; -So, we need to setup the transpiler and add the polyfill for old engines to support modern features. +// after running the transpiler +height = (height !== undefined && height !== null) ? height : 100; +``` -If we orient towards modern engines and do not use features except those supported everywhere, then we don't need to use Babel. +Now the rewritten code is suitable for older JavaScript engines. -## Examples in the tutorial +Usually, a developer runs the transpiler on their own computer, and then deploys the transpiled code to the server. +Speaking of names, [Babel](https://babeljs.io) is one of the most prominent transpilers out there. -````online -Most examples are runnable at-place, like this: +Modern project build systems, such as [webpack](http://webpack.github.io/), provide means to run transpiler automatically on every code change, so it's very easy to integrate into development process. -```js run -alert('Press the "Play" button in the upper-right corner to run'); -``` +## Polyfills + +New language features may include not only syntax constructs and operators, but also built-in functions. + +For example, `Math.trunc(n)` is a function that "cuts off" the decimal part of a number, e.g `Math.trunc(1.23) = 1`. -Examples that use modern JS will work only if your browser supports it. -```` +In some (very outdated) JavaScript engines, there's no `Math.trunc`, so such code will fail. -```offline -As you're reading the offline version, examples are not runnable. But they usually work :) +As we're talking about new functions, not syntax changes, there's no need to transpile anything here. We just need to declare the missing function. + +A script that updates/adds new functions is called "polyfill". It "fills in" the gap and adds missing implementations. + +For this particular case, the polyfill for `Math.trunc` is a script that implements it, like this: + +```js +if (!Math.trunc) { // if no such function + // implement it + Math.trunc = function(number) { + // Math.ceil and Math.floor exist even in ancient JavaScript engines + // they are covered later in the tutorial + return number < 0 ? Math.ceil(number) : Math.floor(number); + }; +} ``` -[Chrome Canary](https://www.google.com/chrome/browser/canary.html) is good for all examples, but other modern browsers are mostly fine too. +JavaScript is a highly dynamic language, scripts may add/modify any functions, even including built-in ones. + +Two interesting libraries of polyfills are: +- [core js](https://github.com/zloirock/core-js) that supports a lot, allows to include only needed features. +- [polyfill.io](http://polyfill.io) service that provides a script with polyfills, depending on the features and user's browser. + + +## Summary + +In this chapter we'd like to motivate you to study modern and even "bleeding-edge" language features, even if they aren't yet well-supported by JavaScript engines. + +Just don't forget to use transpiler (if using modern syntax or operators) and polyfills (to add functions that may be missing). And they'll ensure that the code works. + +For example, later when you're familiar with JavaScript, you can setup a code build system based on [webpack](http://webpack.github.io/) with [babel-loader](https://github.com/babel/babel-loader) plugin. + +Good resources that show the current state of support for various features: +- - for pure JavaScript. +- - for browser-related functions. + +P.S. Google Chrome is usually the most up-to-date with language features, try it if a tutorial demo fails. Most tutorial demos work with any modern browser though. -Note that on production we can use Babel to translate the code into suitable for less recent browsers, so there will be no such limitation, the code will run everywhere. diff --git a/1-js/04-object-basics/01-object/2-hello-object/task.md b/1-js/04-object-basics/01-object/2-hello-object/task.md index 2841a058f..e726ff833 100644 --- a/1-js/04-object-basics/01-object/2-hello-object/task.md +++ b/1-js/04-object-basics/01-object/2-hello-object/task.md @@ -1,14 +1,13 @@ -importance: 5 +importância: 5 --- -# Hello, object +# Olá, objeto -Write the code, one line for each action: - -1. Create an empty object `user`. -2. Add the property `name` with the value `John`. -3. Add the property `surname` with the value `Smith`. -4. Change the value of the `name` to `Pete`. -5. Remove the property `name` from the object. +Escreva o código, uma ação por linha: +1. Crie um objeto vazio (*empty object*) `user`. +2. Adicione a propriedade `name` com o valor `John`. +3. Adicione a propriedade `surname` com o valor `Smith`. +4. Altere o valor de `name` para `Pete`. +5. Remova a propriedade `name` do objeto. diff --git a/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js b/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js index db3283e49..c6a483cfa 100644 --- a/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js +++ b/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js @@ -1,6 +1,6 @@ function isEmpty(obj) { for (let key in obj) { - // if the loop has started, there is a property + // se o laço começou, então existe uma propriedade return false; } return true; diff --git a/1-js/04-object-basics/01-object/3-is-empty/_js.view/test.js b/1-js/04-object-basics/01-object/3-is-empty/_js.view/test.js index 4db5efabe..287051f70 100644 --- a/1-js/04-object-basics/01-object/3-is-empty/_js.view/test.js +++ b/1-js/04-object-basics/01-object/3-is-empty/_js.view/test.js @@ -1,11 +1,11 @@ describe("isEmpty", function() { - it("returns true for an empty object", function() { + it("retorna verdadeiro para um objeto vazio", function() { assert.isTrue(isEmpty({})); }); - it("returns false if a property exists", function() { + it("retorna falso se uma propriedade existir", function() { assert.isFalse(isEmpty({ anything: false })); }); -}); \ No newline at end of file +}); diff --git a/1-js/04-object-basics/01-object/3-is-empty/solution.md b/1-js/04-object-basics/01-object/3-is-empty/solution.md index b876973b5..f93e4de0d 100644 --- a/1-js/04-object-basics/01-object/3-is-empty/solution.md +++ b/1-js/04-object-basics/01-object/3-is-empty/solution.md @@ -1 +1 @@ -Just loop over the object and `return false` immediately if there's at least one property. +Simplemente, percorra (*loop over*) o objeto e imediatamente `return false` se houver pelo menos uma propriedade. diff --git a/1-js/04-object-basics/01-object/3-is-empty/task.md b/1-js/04-object-basics/01-object/3-is-empty/task.md index c438d36a2..b6b03b91d 100644 --- a/1-js/04-object-basics/01-object/3-is-empty/task.md +++ b/1-js/04-object-basics/01-object/3-is-empty/task.md @@ -1,20 +1,19 @@ -importance: 5 +importância: 5 --- -# Check for emptiness +# Verifique por vazio (*emptiness*) -Write the function `isEmpty(obj)` which returns `true` if the object has no properties, `false` otherwise. +Escreva a função `isEmpty(obj)`, que retorna `true` se o objeto não tiver propriedades, e `false` caso contrário. -Should work like that: +Deve funcionar desta forma: ```js let schedule = {}; -alert( isEmpty(schedule) ); // true +alert( isEmpty(schedule) ); // verdadeiro -schedule["8:30"] = "get up"; +schedule["8:30"] = "levante-se"; -alert( isEmpty(schedule) ); // false +alert( isEmpty(schedule) ); // falso ``` - diff --git a/1-js/04-object-basics/01-object/4-const-object/solution.md b/1-js/04-object-basics/01-object/4-const-object/solution.md deleted file mode 100644 index f73c2f92b..000000000 --- a/1-js/04-object-basics/01-object/4-const-object/solution.md +++ /dev/null @@ -1,19 +0,0 @@ -Sure, it works, no problem. - -The `const` only protects the variable itself from changing. - -In other words, `user` stores a reference to the object. And it can't be changed. But the content of the object can. - -```js run -const user = { - name: "John" -}; - -*!* -// works -user.name = "Pete"; -*/!* - -// error -user = 123; -``` diff --git a/1-js/04-object-basics/01-object/4-const-object/task.md b/1-js/04-object-basics/01-object/4-const-object/task.md deleted file mode 100644 index a9aada631..000000000 --- a/1-js/04-object-basics/01-object/4-const-object/task.md +++ /dev/null @@ -1,18 +0,0 @@ -importance: 5 - ---- - -# Constant objects? - -Is it possible to change an object declared with `const`? What do you think? - -```js -const user = { - name: "John" -}; - -*!* -// does it work? -user.name = "Pete"; -*/!* -``` diff --git a/1-js/04-object-basics/01-object/5-sum-object/solution.md b/1-js/04-object-basics/01-object/5-sum-object/solution.md index 63df87849..569692290 100644 --- a/1-js/04-object-basics/01-object/5-sum-object/solution.md +++ b/1-js/04-object-basics/01-object/5-sum-object/solution.md @@ -13,4 +13,3 @@ for (let key in salaries) { alert(sum); // 390 ``` - diff --git a/1-js/04-object-basics/01-object/5-sum-object/task.md b/1-js/04-object-basics/01-object/5-sum-object/task.md index 7e3e048d0..c855904d5 100644 --- a/1-js/04-object-basics/01-object/5-sum-object/task.md +++ b/1-js/04-object-basics/01-object/5-sum-object/task.md @@ -1,10 +1,10 @@ -importance: 5 +importância: 5 --- -# Sum object properties +# Soma das propriedades de um objeto -We have an object storing salaries of our team: +Temos um objeto armazenando salários da nossa equipa: ```js let salaries = { @@ -14,6 +14,6 @@ let salaries = { } ``` -Write the code to sum all salaries and store in the variable `sum`. Should be `390` in the example above. +Escreva o código para somar todos os salários e armazenar na variável `sum`. Para o exemplo acima, deverá ser `390`. -If `salaries` is empty, then the result must be `0`. \ No newline at end of file +Se `salaries` for vazio, então o resultado deve ser `0`. diff --git a/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/source.js b/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/source.js index a02b1e1cb..04d34e81c 100644 --- a/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/source.js +++ b/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/source.js @@ -1,17 +1,16 @@ let menu = { width: 200, height: 300, - title: "My menu" + title: "O meu menu" }; function multiplyNumeric(obj) { - /* your code */ + /* o seu código */ } multiplyNumeric(menu); -alert( "menu width=" + menu.width + " height=" + menu.height + " title=" + menu.title ); - +alert( "largura do menu=" + menu.width + " altura=" + menu.height + " título=" + menu.title ); diff --git a/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/test.js b/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/test.js index 064e5414f..2ba28f769 100644 --- a/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/test.js +++ b/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/test.js @@ -1,17 +1,17 @@ describe("multiplyNumeric", function() { - it("multiplies all numeric properties by 2", function() { + it("multiplica todas as propriedades numéricas por 2", function() { let menu = { width: 200, height: 300, - title: "My menu" + title: "O meu menu" }; let result = multiplyNumeric(menu); assert.equal(menu.width, 400); assert.equal(menu.height, 600); - assert.equal(menu.title, "My menu"); + assert.equal(menu.title, "O meu menu"); }); - it("returns nothing", function() { + it("não retorna nada", function() { assert.isUndefined( multiplyNumeric({}) ); }); diff --git a/1-js/04-object-basics/01-object/8-multiply-numeric/task.md b/1-js/04-object-basics/01-object/8-multiply-numeric/task.md index 33eb89220..ff54c85b7 100644 --- a/1-js/04-object-basics/01-object/8-multiply-numeric/task.md +++ b/1-js/04-object-basics/01-object/8-multiply-numeric/task.md @@ -2,32 +2,30 @@ importance: 3 --- -# Multiply numeric properties by 2 +# Multiplica as propriedades numéricas por 2 -Create a function `multiplyNumeric(obj)` that multiplies all numeric properties of `obj` by `2`. +Crie uma função `multiplyNumeric(obj)` que multiplique todas as propriedades numéricas de `obj` por `2`. -For instance: +Por exemplo: ```js -// before the call +// antes da chamada let menu = { width: 200, height: 300, - title: "My menu" + title: "O meu menu" }; multiplyNumeric(menu); -// after the call +// depois da chamada menu = { width: 400, height: 600, - title: "My menu" + title: "O meu menu" }; ``` -Please note that `multiplyNumeric` does not need to return anything. It should modify the object in-place. - -P.S. Use `typeof` to check for a number here. - +Por favor, note que `multiplyNumeric` não precisa de retornar nada. Deve modificar o próprio objecto. +P.S. Use `typeof` aqui para verificar se é um número. diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md index 00706750c..7cb931672 100644 --- a/1-js/04-object-basics/01-object/article.md +++ b/1-js/04-object-basics/01-object/article.md @@ -1,60 +1,60 @@ -# Objects +# Objetos -As we know from the chapter , there are seven data types in JavaScript. Six of them are called "primitive", because their values contain only a single thing (be it a string or a number or whatever). +Como sabemos, pelo capítulo , existem oito tipos de dados em JavaScript. Sete deles são chamados de "primitivos", porque os seus valores apenas contêm uma única coisa (seja ela uma cadeia-de-carateres [*string*], um número, ou outra). -In contrast, objects are used to store keyed collections of various data and more complex entities. In JavaScript, objects penetrate almost every aspect of the language. So we must understand them first before going in-depth anywhere else. +Em contraste, objetos são usados para armazenar, por meio de uma chave, coleções de vários dados e entidades mais complexas. Em JavaScript, os objetos penetram em quase todos os aspetos da linguagem. Portanto, devemos primeiro os compreender antes de nos envolver com detalhe em algo mais. -An object can be created with figure brackets `{…}` with an optional list of *properties*. A property is a "key: value" pair, where `key` is a string (also called a "property name"), and `value` can be anything. +Um objeto pode ser criado por chavetas `{…}`, com uma lista opcional de *propriedades*. Uma propriedade é um par "key: value" (chave: valor), onde `key` é uma *string* (também chamada de "nome da propriedade"), e `value` pode ser qualquer coisa. -We can imagine an object as a cabinet with signed files. Every piece of data is stored in its file by the key. It's easy to find a file by its name or add/remove a file. +Podemos imaginar um objeto como um fichário com ficheiros assinados. Cada peça de informação, é armazenada no seu ficheiro por meio de uma chave. É fácil encontrar um ficheiro através do seu nome, ou adicionar/remover um ficheiro. ![](object.svg) -An empty object ("empty cabinet") can be created using one of two syntaxes: +Um objeto vazio ("fichário vazio"), pode ser criado por uma destas duas sintaxes: ```js -let user = new Object(); // "object constructor" syntax -let user = {}; // "object literal" syntax +let user = new Object(); // sintaxe de "construtor de objetos" +let user = {}; // sintaxe de "objeto literal" ``` ![](object-user-empty.svg) -Usually, the figure brackets `{...}` are used. That declaration is called an *object literal*. +Geralmente, são utilizadas as chavetas `{...}`. Essa declaração é chamada de *objeto literal*. -## Literals and properties +## Literais e propriedades -We can immediately put some properties into `{...}` as "key: value" pairs: +Podemos imediatamente colocar algumas propriedades dentro das `{...}` como pares "chave: valor": ```js -let user = { // an object - name: "John", // by key "name" store value "John" - age: 30 // by key "age" store value 30 +let user = { // um objeto + name: "John", // na chave "name" armazene o valor "John" + age: 30 // na chave "age" armazene o valor 30 }; ``` -A property has a key (also known as "name" or "identifier") before the colon `":"` and a value to the right of it. +Uma propriedade tem uma chave (também conhecida por "nome" ou "identificador") antes dos dois-pontos `":"` e um valor à sua direita. -In the `user` object, there are two properties: +No objeto `user`, existem duas propriedades: -1. The first property has the name `"name"` and the value `"John"`. -2. The second one has the name `"age"` and the value `30`. +1. A primeira, tem o nome `"name"` e o valor `"John"`. +2. A segunda, tem o nome `"age"` e o valor `30`. -The resulting `user` object can be imagined as a cabinet with two signed files labeled "name" and "age". +O objeto `user` resultante, pode ser imaginado como um fichário com dois ficheiros assinados com as etiquetas "*name*" e "*age*". ![user object](object-user.svg) -We can add, remove and read files from it any time. +Podemos adicionar, remover ou ler ficheiros dele em qualquer momento. -Property values are accessible using the dot notation: +Valores de propriedades podem ser acedidos usando a notação por ponto (*dot notation*): ```js -// get fields of the object: +// obtenha os valores das propriedades do objeto: alert( user.name ); // John alert( user.age ); // 30 ``` -The value can be of any type. Let's add a boolean one: +O valor pode ser de qualquer tipo. Vamos adicionar um booleano: ```js user.isAdmin = true; @@ -62,7 +62,7 @@ user.isAdmin = true; ![user object 2](object-user-isadmin.svg) -To remove a property, we can use `delete` operator: +Para remover uma propriedade, podemos usar o operador `delete`: ```js delete user.age; @@ -70,69 +70,70 @@ delete user.age; ![user object 3](object-user-delete.svg) -We can also use multiword property names, but then they must be quoted: +Podemos também usar nomes de propriedades com múltiplas palavras, mas aí eles têm de estar entre aspas: ```js let user = { name: "John", age: 30, - "likes birds": true // multiword property name must be quoted + "likes birds": true // o nome de propriedade com múltiplas palavras tem de estar entre aspas }; ``` ![](object-user-props.svg) +A última propriedade da lista pode terminar com uma vírgula: -The last property in the list may end with a comma: ```js let user = { name: "John", age: 30*!*,*/!* } ``` -That is called a "trailing" or "hanging" comma. Makes it easier to add/remove/move around properties, because all lines become alike. +Esta é chamada de vírgula à direita (*trailing comma*) ou "vírgula pendurada" (*hanging comma*). Ela facilita o adicionar/remover/mover propriedades, porque todas as linhas se tornam semelhantes. -## Square brackets +## Parênteses retos -For multiword properties, the dot access doesn't work: +Para propriedades com múltiplas palavras, o acesso por ponto não funciona: ```js run -// this would give a syntax error +// isto daria um erro de sintaxe user.likes birds = true ``` -That's because the dot requires the key to be a valid variable identifier. That is: no spaces and other limitations. +O JavaScript não compreende isso. Ele pensa que acedemos a `user.likes`, e depois fornece um erro de sintaxe quando encontra a inesperada `birds`. -There's an alternative "square bracket notation" that works with any string: +O ponto requere que a chave seja um identificador de variável válido. Isso implica: que não contenha espaços, não comece por um dígito e não inclua carateres especiais (`$` e `_` são permitidos). +Existe uma alternativa, a "notação por parênteses retos", que funciona com qualquer *string*: ```js run let user = {}; -// set +// cria user["likes birds"] = true; -// get -alert(user["likes birds"]); // true +// lê +alert(user["likes birds"]); // true ('verdadeiro') -// delete +// remove delete user["likes birds"]; ``` -Now everything is fine. Please note that the string inside the brackets is properly quoted (any type of quotes will do). +Agora, tudo está bem. Por favor, verifique se a *string* dentro dos parênteses retos está adequadamente encerrada entre aspas (qualquer tipo de aspas serve). -Square brackets also provide a way to obtain the property name as the result of any expression -- as opposed to a literal string -- like from a variable as follows: +Os parênteses retos também fornecem uma forma de se obter o nome de uma propriedade a partir de uma expressão -- em vez de uma *string* literal -- como por meio de uma variável, por exemplo: ```js let key = "likes birds"; -// same as user["likes birds"] = true; +// o mesmo que 'user["likes birds"] = true;' user[key] = true; ``` -Here, the variable `key` may be calculated at run-time or depend on the user input. And then we use it to access the property. That gives us a great deal of flexibility. The dot notation cannot be used in a similar way. +Aqui, a variável `key` pode ser calculada em tempo de execução (*run-time*) ou depender de uma entrada pelo utilizador (*user input*). E depois a usamos para aceder à propriedade. Isso, nos dá um grande grau de flexibilidade. -For instance: +Por exemplo: ```js run let user = { @@ -140,15 +141,13 @@ let user = { age: 30 }; -let key = prompt("What do you want to know about the user?", "name"); +let key = prompt("O que quer saber acerca do utilizador?", "name"); -// access by variable -alert( user[key] ); // John (if enter "name") +// aceda por meio da variável +alert( user[key] ); // John (se a entrada tiver sido "name") ``` -<<<<<<< HEAD -======= -The dot notation cannot be used in a similar way: +A notação por ponto não pode ser usada de forma semelhante: ```js run let user = { @@ -159,42 +158,41 @@ let user = { let key = "name"; alert( user.key ) // undefined ``` ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 -### Computed properties +### Propriedades computadas -We can use square brackets in an object literal. That's called *computed properties*. +Podemos utilizar os parênteses retos num object literal, quando criamos o objeto. Chamam-se de *propriedades computadas*. -For instance: +Por exemplo: ```js run -let fruit = prompt("Which fruit to buy?", "apple"); +let fruit = prompt("Que fruta comprar?", "apple"); let bag = { *!* - [fruit]: 5, // the name of the property is taken from the variable fruit + [fruit]: 5, // o nome da propriedade é obtido por meio da variável 'fruit' */!* }; -alert( bag.apple ); // 5 if fruit="apple" +alert( bag.apple ); // 5 se fruit="apple" ``` -The meaning of a computed property is simple: `[fruit]` means that the property name should be taken from `fruit`. +O significado de uma propriedade computada é simples: `[fruit]` diz que o nome da propriedade é o valor em `fruit`. -So, if a visitor enters `"apple"`, `bag` will become `{apple: 5}`. +Assim, se um visitante inserir `"apple"`, `bag` se tornará em `{apple: 5}`. -Essentially, that works the same as: +Essencialmente, isso é o mesmo que: ```js run -let fruit = prompt("Which fruit to buy?", "apple"); +let fruit = prompt("Que fruta comprar?", "apple"); let bag = {}; -// take property name from the fruit variable +// obtenha o nome da propriedade por meio da variável fruit bag[fruit] = 5; ``` -...But looks nicer. +...Mas, tem melhor apresentação. -We can use more complex expressions inside square brackets: +Podemos usar expressões mais complexas dentro dos parênteses retos: ```js let fruit = 'apple'; @@ -203,58 +201,22 @@ let bag = { }; ``` -Square brackets are much more powerful than the dot notation. They allow any property names and variables. But they are also more cumbersome to write. +Parênteses retos, são mais poderosos que a notação por ponto. Eles permitem quaisquer nomes de propriedades e variáveis. Mas, eles também dão mais trabalho para escrever. -So most of the time, when property names are known and simple, the dot is used. And if we need something more complex, then we switch to square brackets. +Assim, na maior parte as vezes, quando os nomes de propriedades são conhecidos e simples, o ponto é utilizado. E, se precisarmos de algo mais complexo, mudamos para os parênteses retos. +## Abreviação do valor da propriedade +Em código real, muitas vezes usamos nomes de propriedades e nomes de variáveis iguais. -````smart header="Reserved words are allowed as property names" -A variable cannot have a name equal to one of language-reserved words like "for", "let", "return" etc. - -But for an object property, there's no such restriction. Any name is fine: - -```js run -let obj = { - for: 1, - let: 2, - return: 3 -}; - -alert( obj.for + obj.let + obj.return ); // 6 -``` - -Basically, any name is allowed, but there's a special one: `"__proto__"` that gets special treatment for historical reasons. For instance, we can't set it to a non-object value: - -```js run -let obj = {}; -obj.__proto__ = 5; -alert(obj.__proto__); // [object Object], didn't work as intended -``` - -As we see from the code, the assignment to a primitive `5` is ignored. - -That can become a source of bugs and even vulnerabilities if we intend to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys. - -In that case the visitor may choose "__proto__" as the key, and the assignment logic will be ruined (as shown above). - -There is a way to make objects treat `__proto__` as a regular property, which we'll cover later, but first we need to know more about objects. -There's also another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys. -```` - - -## Property value shorthand - -In real code we often use existing variables as values for property names. - -For instance: +Por exemplo: ```js run function makeUser(name, age) { return { name: name, age: age - // ...other properties + // ...outras propriedades }; } @@ -262,103 +224,150 @@ let user = makeUser("John", 30); alert(user.name); // John ``` -In the example above, properties have the same names as variables. The use-case of making a property from a variable is so common, that there's a special *property value shorthand* to make it shorter. +No exemplo acima, as propriedades têm os mesmos nomes que as variáveis. O caso prático (*use-case*) de construir uma propriedade com base numa variável é tão comum, que existe uma especial *abreviação do valor da propriedade* (*property value shorthand*) para a tornar mais curta. -Instead of `name:name` we can just write `name`, like this: +Em vez de `name:name`, podemos simplesmente escrever `name`, como abaixo: ```js function makeUser(name, age) { *!* return { - name, // same as name: name - age // same as age: age + name, // o mesmo que name: name + age // o mesmo que age: age // ... }; */!* } ``` -We can use both normal properties and shorthands in the same object: +Podemos empregar ambas, as propriedades normais e as abreviações (*shorthands*), no mesmo objeto: ```js let user = { - name, // same as name:name + name, // o mesmo que name:name age: 30 }; ``` -## Existence check -A notable objects feature is that it's possible to access any property. There will be no error if the property doesn't exist! Accessing a non-existing property just returns `undefined`. It provides a very common way to test whether the property exists -- to get it and compare vs undefined: +## Limitações dos nomes de propriedades + +Como já sabemos, uma variável não pode ter um nome igual a uma palavra reservada da linguagem, como "for", "let", "return" etc. + +Mas, para propriedades de objetos não há tal restrição. + +```js run +// estas propriedades são válidas +let obj = { + for: 1, + let: 2, + return: 3 +}; + +alert( obj.for + obj.let + obj.return ); // 6 +``` + +Em resumo, não existem limitações para os nomes de propriedades. Eles podem ser quaisquer *strings* ou símbolos (um tipo especial de identificadores, a ser visto mais adiante). + +Outros tipos são automáticamente convertidos para *strings*. + +Por exemplo, um número `0` se torna na *string* `"0"`, quando usado como chave de propriedade: + +```js run +let obj = { + 0: "teste" // o mesmo que "0": "teste" +}; + +// ambos os 'alerts' acedem à mesma propriedade (o número 0 é convertido para a string "0") +alert( obj["0"] ); // teste +alert( obj[0] ); // teste (a mesma propriedade) +``` + +Existe um pequeno senão com uma propriedade especial chamada `__proto__`. Não pode ter um valor não-objeto. + +```js run +let obj = {}; +obj.__proto__ = 5; // atribua um número +alert(obj.__proto__); // [object Object] - o valor é um objeto, não funcionou como esperado +``` + +Como vemos pelo código, a atribuição do primitivo `5` é ignorada. + +Vamos analisar a natureza especial de `__proto__` em [subsequent chapters](info:prototype-inheritance) (capítulos subsequentes), e sugerir [ways to fix](info:prototype-methods) (formas de correção) de tal comportamento. + +## Teste de existência da propriedade, o operador "in" + +Uma particularidade notável de objetos em JavaScript, em comparação a outras linguagens, é que é possível aceder a qualquer propriedade. Não haverá erro se a propriedade não existir! + +Aceder a uma propriedade não-existente apenas retorna `undefined`. Assim, podemos fácilmente testar se uma propriedade existe: ```js run let user = {}; -alert( user.noSuchProperty === undefined ); // true means "no such property" +alert( user.noSuchProperty === undefined ); // true, significa que é uma "propriedade não existente" (no such property) ``` -There also exists a special operator `"in"` to check for the existence of a property. +Também existe o operador especial `"in"`, para isso. -The syntax is: +A sintaxe é: ```js "key" in object ``` -For instance: +Por exemplo: ```js run let user = { name: "John", age: 30 }; -alert( "age" in user ); // true, user.age exists -alert( "blabla" in user ); // false, user.blabla doesn't exist +alert( "age" in user ); // true, 'user.age' existe +alert( "blabla" in user ); // false, 'user.blabla' não existe ``` -Please note that on the left side of `in` there must be a *property name*. That's usually a quoted string. +Por favor, note que no lado esquerdo de `in` deve existir um *nome de propriedade*. Geralmente, é uma *string* entre aspas. -If we omit quotes, that would mean a variable containing the actual name will be tested. For instance: +Se omitirmos as aspas, isso terá o significado de uma variável que contém o nome a ser testado. Por exemplo: ```js run let user = { age: 30 }; let key = "age"; -alert( *!*key*/!* in user ); // true, takes the name from key and checks for such property +alert( *!*key*/!* in user ); // true, a propriedade "age" existe ``` -````smart header="Using \"in\" for properties that store `undefined`" -Usually, the strict comparison `"=== undefined"` check works fine. But there's a special case when it fails, but `"in"` works correctly. +Porque o operador `in` existe? Não é suficiente comparar a `undefined`? + +A maior parte das vezes comparar a `undefined` funciona bem. Mas há um caso especial em que falha, mas `in` funciona corretamente. -It's when an object property exists, but stores `undefined`: +É quando uma propriedade de objeto existe, mas está nela armazenado `undefined`: ```js run let obj = { test: undefined }; -alert( obj.test ); // it's undefined, so - no such property? +alert( obj.test ); // é 'undefined', então - não existe essa propriedade? -alert( "test" in obj ); // true, the property does exist! +alert( "test" in obj ); // true (verdadeiro), a propriedade realmente existe! ``` +No código acima, a propriedade `obj.test` tecnicamente existe. Assim, o operador `in` funciona corretamente. -In the code above, the property `obj.test` technically exists. So the `in` operator works right. - -Situations like this happen very rarely, because `undefined` is usually not assigned. We mostly use `null` for "unknown" or "empty" values. So the `in` operator is an exotic guest in the code. -```` +Situações como esta muito raramente ocorrem, porque `undefined` não deveria ser explicitamente atribuído. Em geral, empregamos `null` para valores "desconhecidos" ou "vazios". Assim, o operador `in` é um convidado exótico na codificação. -## The "for..in" loop +## O laço "for..in" -To walk over all keys of an object, there exists a special form of the loop: `for..in`. This is a completely different thing from the `for(;;)` construct that we studied before. +Para navegar por todas as chaves (*keys*) de um objeto, existe uma forma especial de laço (*loop*): `for..in`. Esta, é uma coisa completamente diferente da construção `for(;;)` que estudámos antes. -The syntax: +A sintaxe: ```js for (key in object) { - // executes the body for each key among object properties + // executa o corpo do ciclo, por cada chave nas propriedades do objeto } ``` -For instance, let's output all properties of `user`: +Por exemplo, vamos imprimir todas propriedades de `user`: ```js run let user = { @@ -368,33 +377,32 @@ let user = { }; for (let key in user) { - // keys - alert( key ); // name, age, isAdmin - // values for the keys + // chave + alert( key ); // 'name', 'age', isAdmin' + // valores para as chaves alert( user[key] ); // John, 30, true } ``` -Note that all "for" constructs allow us to declare the looping variable inside the loop, like `let key` here. - -Also, we could use another variable name here instead of `key`. For instance, `"for (let prop in obj)"` is also widely used. +Note, que todas as construções "for" nos permitem declarar a variável do laço dentro do *loop*, como `let key` aqui. +De igual modo, nós poderíamos usar aqui um nome de variável diferente de `key`. Por exemplo, `"for (let prop in obj)"` também é largamente utilizado. -### Ordered like an object +### Ordenado como um objeto -Are objects ordered? In other words, if we loop over an object, do we get all properties in the same order they were added? Can we rely on this? +Os objetos são ordenados? Por outras palavras, se percorrermos um objeto com um laço, será que obtemos todas as propriedades pela mesma ordem em que foram adicionadas? Poderemos confiar nisso? -The short answer is: "ordered in a special fashion": integer properties are sorted, others appear in creation order. The details follow. +A curta resposta é: "ordenados de um modo especial" - propriedades inteiras são ordenadas de forma crescente, outras aparecem na ordem em que foram criadas. Detalhes a seguir. -As an example, let's consider an object with the phone codes: +Como exemplo, vamos considerar um objeto com indicativos telefónicos de países: ```js run let codes = { - "49": "Germany", - "41": "Switzerland", - "44": "Great Britain", + "49": "Alemanha", + "41": "Suíça", + "44": "Grã Bretanha", // .., - "1": "USA" + "1": "EUA" }; *!* @@ -404,56 +412,56 @@ for (let code in codes) { */!* ``` -The object may be used to suggest a list of options to the user. If we're making a site mainly for German audience then we probably want `49` to be the first. +O objeto pode ser usado para sugerir uma lista de opções para o utilizador. Se, estivermos a construir um *site* maioritariamente para uma audiência Alemã, então provavelmente queremos `49` como o primeiro. -But if we run the code, we see a totally different picture: +Mas, ao correr o código, temos uma imagem totalmente diferente: -- USA (1) goes first -- then Switzerland (41) and so on. +- EUA (1) vem em primeiro lugar, +- depois a Suíça (41), e assim por adiante. -The phone codes go in the ascending sorted order, because they are integers. So we see `1, 41, 44, 49`. +Os indicativos telefónicos, são ordenados por ordem ascendente, porque são inteiros. Por isso, vemos `1, 41, 44, 49`. -````smart header="Integer properties? What's that?" -The "integer property" term here means a string that can be converted to-and-from an integer without a change. +````smart header="Propriedades inteiras? O que é isso?" +O termo "propriedade inteira" aqui, significa que uma *string* pode ser convertida para inteiro ('integer'), e convertida de volta sem qualquer alteração. -So, "49" is an integer property name, because when it's transformed to an integer number and back, it's still the same. But "+49" and "1.2" are not: +Assim, "49" é um nome de propriedade inteiro porque, ao ser transformado num número inteiro e reconvertido, continua o mesmo. Mas, "+49" e "1.2" não são: ```js run -// Math.trunc is a built-in function that removes the decimal part -alert( String(Math.trunc(Number("49"))) ); // "49", same, integer property -alert( String(Math.trunc(Number("+49"))) ); // "49", not same "+49" ⇒ not integer property -alert( String(Math.trunc(Number("1.2"))) ); // "1", not same "1.2" ⇒ not integer property +// Math.trunc é uma função incorporada (*built-in function*) que remove a parte decimal +alert( String(Math.trunc(Number("49"))) ); // "49", inalterado ⇒ propriedade inteira +alert( String(Math.trunc(Number("+49"))) ); // "49", não o mesmo que "+49" ⇒ não é uma propriedade inteira +alert( String(Math.trunc(Number("1.2"))) ); // "1", não o mesmo que "1.2" ⇒ não é uma propriedade inteira ``` ```` -...On the other hand, if the keys are non-integer, then they are listed in the creation order, for instance: +...Por outro lado, se as chaves forem não-inteiras, elas são listadas segundo a ordem em que foram criadas, por exemplo: ```js run let user = { name: "John", surname: "Smith" }; -user.age = 25; // add one more +user.age = 25; // adicione mais uma propriedade *!* -// non-integer properties are listed in the creation order +// propriedades não-inteiras são listadas segundo a ordem em que foram criadas */!* for (let prop in user) { - alert( prop ); // name, surname, age + alert( prop ); // 'name', 'surname', 'age' } ``` -So, to fix the issue with the phone codes, we can "cheat" by making the codes non-integer. Adding a plus `"+"` sign before each code is enough. +Portanto, para corrigir o problema dos indicativos telefónicos, podemos "enganar" tornando-os não-inteiros. Adicionar um sinal de mais `"+"` antes de cada código é o suficiente. -Like this: +Desta forma: ```js run let codes = { - "+49": "Germany", - "+41": "Switzerland", - "+44": "Great Britain", + "+49": "Alemanha", + "+41": "Suiça", + "+44": "Grã Bretanha", // .., - "+1": "USA" + "+1": "EUA" }; for (let code in codes) { @@ -461,294 +469,34 @@ for (let code in codes) { } ``` -Now it works as intended. - -## Copying by reference - -One of the fundamental differences of objects vs primitives is that they are stored and copied "by reference". - -Primitive values: strings, numbers, booleans -- are assigned/copied "as a whole value". - -For instance: - -```js -let message = "Hello!"; -let phrase = message; -``` - -As a result we have two independent variables, each one is storing the string `"Hello!"`. - -![](variable-copy-value.svg) - -Objects are not like that. - -**A variable stores not the object itself, but its "address in memory", in other words "a reference" to it.** - -Here's the picture for the object: - -```js -let user = { - name: "John" -}; -``` - -![](variable-contains-reference.svg) - -Here, the object is stored somewhere in memory. And the variable `user` has a "reference" to it. - -**When an object variable is copied -- the reference is copied, the object is not duplicated.** - -If we imagine an object as a cabinet, then a variable is a key to it. Copying a variable duplicates the key, but not the cabinet itself. - -For instance: - -```js no-beautify -let user = { name: "John" }; - -let admin = user; // copy the reference -``` - -Now we have two variables, each one with the reference to the same object: - -![](variable-copy-reference.svg) - -We can use any variable to access the cabinet and modify its contents: - -```js run -let user = { name: 'John' }; - -let admin = user; - -*!* -admin.name = 'Pete'; // changed by the "admin" reference -*/!* - -alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference -``` - -The example above demonstrates that there is only one object. As if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use the other key (`user`) we would see changes. - -### Comparison by reference - -The equality `==` and strict equality `===` operators for objects work exactly the same. - -**Two objects are equal only if they are the same object.** - -For instance, two variables reference the same object, they are equal: - -```js run -let a = {}; -let b = a; // copy the reference - -alert( a == b ); // true, both variables reference the same object -alert( a === b ); // true -``` - -And here two independent objects are not equal, even though both are empty: - -```js run -let a = {}; -let b = {}; // two independent objects - -alert( a == b ); // false -``` - -For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are necessary very rarely and usually are a result of a coding mistake. - -### Const object - -An object declared as `const` *can* be changed. - -For instance: - -```js run -const user = { - name: "John" -}; - -*!* -user.age = 25; // (*) -*/!* - -alert(user.age); // 25 -``` - -It might seem that the line `(*)` would cause an error, but no, there's totally no problem. That's because `const` fixes the value of `user` itself. And here `user` stores the reference to the same object all the time. The line `(*)` goes *inside* the object, it doesn't reassign `user`. - -The `const` would give an error if we try to set `user` to something else, for instance: - -```js run -const user = { - name: "John" -}; - -*!* -// Error (can't reassign user) -*/!* -user = { - name: "Pete" -}; -``` - -...But what if we want to make constant object properties? So that `user.age = 25` would give an error. That's possible too. We'll cover it in the chapter . - -## Cloning and merging, Object.assign - -So, copying an object variable creates one more reference to the same object. - -But what if we need to duplicate an object? Create an independent copy, a clone? - -That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. Actually, that's rarely needed. Copying by reference is good most of the time. - -But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level. - -Like this: - -```js run -let user = { - name: "John", - age: 30 -}; - -*!* -let clone = {}; // the new empty object - -// let's copy all user properties into it -for (let key in user) { - clone[key] = user[key]; -} -*/!* - -// now clone is a fully independent clone -clone.name = "Pete"; // changed the data in it - -alert( user.name ); // still John in the original object -``` - -Also we can use the method [Object.assign](mdn:js/Object/assign) for that. - -The syntax is: - -```js -Object.assign(dest, [src1, src2, src3...]) -``` - -- Arguments `dest`, and `src1, ..., srcN` (can be as many as needed) are objects. -- It copies the properties of all objects `src1, ..., srcN` into `dest`. In other words, properties of all arguments starting from the 2nd are copied into the 1st. Then it returns `dest`. - -For instance, we can use it to merge several objects into one: -```js -let user = { name: "John" }; - -let permissions1 = { canView: true }; -let permissions2 = { canEdit: true }; - -*!* -// copies all properties from permissions1 and permissions2 into user -Object.assign(user, permissions1, permissions2); -*/!* - -// now user = { name: "John", canView: true, canEdit: true } -``` - -If the receiving object (`user`) already has the same named property, it will be overwritten: - -```js -let user = { name: "John" }; - -// overwrite name, add isAdmin -Object.assign(user, { name: "Pete", isAdmin: true }); - -// now user = { name: "Pete", isAdmin: true } -``` - -We also can use `Object.assign` to replace the loop for simple cloning: - -```js -let user = { - name: "John", - age: 30 -}; - -*!* -let clone = Object.assign({}, user); -*/!* -``` - -It copies all properties of `user` into the empty object and returns it. Actually, the same as the loop, but shorter. - -Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects. What to do with them? - -Like this: -```js run -let user = { - name: "John", - sizes: { - height: 182, - width: 50 - } -}; - -alert( user.sizes.height ); // 182 -``` - -Now it's not enough to copy `clone.sizes = user.sizes`, because the `user.sizes` is an object, it will be copied by reference. So `clone` and `user` will share the same sizes: - -Like this: -```js run -let user = { - name: "John", - sizes: { - height: 182, - width: 50 - } -}; - -let clone = Object.assign({}, user); - -alert( user.sizes === clone.sizes ); // true, same object - -// user and clone share sizes -user.sizes.width++; // change a property from one place -alert(clone.sizes.width); // 51, see the result from the other one -``` - -To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning". - -There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](http://w3c.github.io/html/infrastructure.html#safe-passing-of-structured-data). In order not to reinvent the wheel, we can use a working implementation of it from the JavaScript library [lodash](https://lodash.com), the method is called [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). - - - -## Summary - -Objects are associative arrays with several special features. +Agora, funciona como pretendido. -They store properties (key-value pairs), where: -- Property keys must be strings or symbols (usually strings). -- Values can be of any type. +## Resumo -To access a property, we can use: -- The dot notation: `obj.property`. -- Square brackets notation `obj["property"]`. Square brackets allow to take the key from a variable, like `obj[varWithKey]`. +Objetos são *arrays* associativos (*associative arrays*), com várias funcionalidades especiais. -Additional operators: -- To delete a property: `delete obj.prop`. -- To check if a property with the given key exists: `"key" in obj`. -- To iterate over an object: `for (let key in obj)` loop. +Eles armazenam propriedades (pares chave-valor), onde: +- As chaves das propriedades devem ser *strings* ou símbolos (geralmente *strings*). +- Os valores podem ser de qualquer tipo. -Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object. All operations via copied references (like adding/removing properties) are performed on the same single object. +Para aceder a uma propriedade, podemos utilizar: +- A notação por ponto: `obj.property`. +- A notação por parênteses retos `obj["property"]`. Os parênteses retos permitem receber a chave a partir de uma variável, como por exemplo `obj[varWithKey]`. -To make a "real copy" (a clone) we can use `Object.assign` or [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). +Operadores adicionais: +- Para remover uma propriedade: `delete obj.prop`. +- Para verificar se uma propriedade com uma dada chave existe: `"key" in obj`. +- Para iterar sobre um objeto: o ciclo `for (let key in obj)`. -What we've studied in this chapter is called a "plain object", or just `Object`. +O que estudámos neste capítulo é o chamado "objeto simples" ("*plain object*"), ou simplesmente `Objeto`. -There are many other kinds of objects in JavaScript: +Existem muitos outros tipos de objetos em JavaScript: -- `Array` to store ordered data collections, -- `Date` to store the information about the date and time, -- `Error` to store the information about an error. -- ...And so on. +- `Array` para armazenar coleções ordenadas de dados, +- `Date` para armazenar informação sobre data e tempo, +- `Error` para armazenar informação sobre um erro. +- ...E outros mais. -They have their special features that we'll study later. Sometimes people say something like "Array type" or "Date type", but formally they are not types of their own, but belong to a single "object" data type. And they extend it in various ways. +Eles têm as suas funcionalidades especiais, que vamos estudar mais adiante. Por vezes, as pessoas dizem algo como "o tipo Array" ou "o tipo Data" (*Date*), mas formalmente eles não são própriamente tipos, eles pertencem a um único tipo de dados "objeto". E eles o estendem de várias formas. -Objects in JavaScript are very powerful. Here we've just scratched the surface of a topic that is really huge. We'll be closely working with objects and learning more about them in further parts of the tutorial. +Objetos em JavaScript são muito poderosos. Aqui, apenas analisamos a superfície de um tópico que é realmente amplo. Nós vamos, mais especificamente, trabalhar e aprender sobre objetos em futuras partes do tutorial. diff --git a/1-js/04-object-basics/01-object/object-user-delete.svg b/1-js/04-object-basics/01-object/object-user-delete.svg index 89cc86431..4bbf324b4 100644 --- a/1-js/04-object-basics/01-object/object-user-delete.svg +++ b/1-js/04-object-basics/01-object/object-user-delete.svg @@ -1,36 +1 @@ - - - - object-user-delete.svg - Created with sketchtool. - - - - - - - - - - - name - - - - - - - - - isAdmin - - - - - - user - - - - - \ No newline at end of file +nameisAdminuser \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/object-user-empty.svg b/1-js/04-object-basics/01-object/object-user-empty.svg index 2b25a0e78..5359c45cb 100644 --- a/1-js/04-object-basics/01-object/object-user-empty.svg +++ b/1-js/04-object-basics/01-object/object-user-empty.svg @@ -1,21 +1 @@ - - - - object-user-empty.svg - Created with sketchtool. - - - - - - - - empty - - - user - - - - - \ No newline at end of file +emptyuser \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/object-user-isadmin.svg b/1-js/04-object-basics/01-object/object-user-isadmin.svg index e201e7f92..f4e7b09ae 100644 --- a/1-js/04-object-basics/01-object/object-user-isadmin.svg +++ b/1-js/04-object-basics/01-object/object-user-isadmin.svg @@ -1,45 +1 @@ - - - - object-user-isadmin.svg - Created with sketchtool. - - - - - - - - - - - name - - - - - - - - - age - - - - - - - - - isAdmin - - - - - - user - - - - - \ No newline at end of file +nameageisAdminuser \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/object-user-props.svg b/1-js/04-object-basics/01-object/object-user-props.svg index adf5ee6df..92958cfbe 100644 --- a/1-js/04-object-basics/01-object/object-user-props.svg +++ b/1-js/04-object-basics/01-object/object-user-props.svg @@ -1,45 +1 @@ - - - - object-user-props.svg - Created with sketchtool. - - - - - - - - - - - name - - - - - - - - - age - - - - - - - - - likes birds - - - - - - user - - - - - \ No newline at end of file +nameagelikes birdsuser \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/object-user.svg b/1-js/04-object-basics/01-object/object-user.svg index 7309232a8..f91e48143 100644 --- a/1-js/04-object-basics/01-object/object-user.svg +++ b/1-js/04-object-basics/01-object/object-user.svg @@ -1,36 +1 @@ - - - - object-user.svg - Created with sketchtool. - - - - - - - - - - - name - - - - - - - - - age - - - - - - user - - - - - \ No newline at end of file +nameageuser \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/object.svg b/1-js/04-object-basics/01-object/object.svg index d2275b662..28582b94e 100644 --- a/1-js/04-object-basics/01-object/object.svg +++ b/1-js/04-object-basics/01-object/object.svg @@ -1,41 +1 @@ - - - - object.svg - Created with sketchtool. - - - - - - - - - - - key1 - - - - - - - - - key2 - - - - - - - - - key3 - - - - - - - \ No newline at end of file +key1key2key3 \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/variable-contains-reference.svg b/1-js/04-object-basics/01-object/variable-contains-reference.svg deleted file mode 100644 index 092efa36a..000000000 --- a/1-js/04-object-basics/01-object/variable-contains-reference.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - variable-contains-reference.svg - Created with sketchtool. - - - - - - - - - user - - - - - - - - - - - - - - - name - - - - - - - \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/variable-copy-reference.svg b/1-js/04-object-basics/01-object/variable-copy-reference.svg deleted file mode 100644 index 4dc2d89f1..000000000 --- a/1-js/04-object-basics/01-object/variable-copy-reference.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - variable-copy-reference.svg - Created with sketchtool. - - - - - - - - - - user - - - - - - - - - - - - - - - - - admin - - - - - - - - - - - - - - - - - name - - - - - - - \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/variable-copy-value.svg b/1-js/04-object-basics/01-object/variable-copy-value.svg deleted file mode 100644 index ea048d4a8..000000000 --- a/1-js/04-object-basics/01-object/variable-copy-value.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - variable-copy-value.svg - Created with sketchtool. - - - - - - - - - - "Hello!" - - - - - - message - - - - - - - - - "Hello!" - - - - - phrase - - - - - \ No newline at end of file diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md index c88872232..bf646a382 100644 --- a/1-js/04-object-basics/02-object-copy/article.md +++ b/1-js/04-object-basics/02-object-copy/article.md @@ -1,25 +1,29 @@ -# Object copying, references +# Object references and copying -One of the fundamental differences of objects vs primitives is that they are stored and copied "by reference". +One of the fundamental differences of objects versus primitives is that objects are stored and copied "by reference", whereas primitive values: strings, numbers, booleans, etc -- are always copied "as a whole value". -Primitive values: strings, numbers, booleans -- are assigned/copied "as a whole value". +That's easy to understand if we look a bit under the hood of what happens when we copy a value. -For instance: +Let's start with a primitive, such as a string. + +Here we put a copy of `message` into `phrase`: ```js let message = "Hello!"; let phrase = message; ``` -As a result we have two independent variables, each one is storing the string `"Hello!"`. +As a result we have two independent variables, each one storing the string `"Hello!"`. ![](variable-copy-value.svg) +Quite an obvious result, right? + Objects are not like that. -**A variable stores not the object itself, but its "address in memory", in other words "a reference" to it.** +**A variable assigned to an object stores not the object itself, but its "address in memory" -- in other words "a reference" to it.** -Here's the picture for the object: +Let's look at an example of such a variable: ```js let user = { @@ -27,11 +31,19 @@ let user = { }; ``` +And here's how it's actually stored in memory: + ![](variable-contains-reference.svg) -Here, the object is stored somewhere in memory. And the variable `user` has a "reference" to it. +The object is stored somewhere in memory (at the right of the picture), while the `user` variable (at the left) has a "reference" to it. + +We may think of an object variable, such as `user`, as like a sheet of paper with the address of the object on it. + +When we perform actions with the object, e.g. take a property `user.name`, the JavaScript engine looks at what's at that address and performs the operation on the actual object. -**When an object variable is copied -- the reference is copied, the object is not duplicated.** +Now here's why it's important. + +**When an object variable is copied, the reference is copied, but the object itself is not duplicated.** For instance: @@ -41,11 +53,13 @@ let user = { name: "John" }; let admin = user; // copy the reference ``` -Now we have two variables, each one with the reference to the same object: +Now we have two variables, each storing a reference to the same object: ![](variable-copy-reference.svg) -We can use any variable to access the object and modify its contents: +As you can see, there's still one object, but now with two variables that reference it. + +We can use either variable to access the object and modify its contents: ```js run let user = { name: 'John' }; @@ -59,15 +73,13 @@ admin.name = 'Pete'; // changed by the "admin" reference alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference ``` -The example above demonstrates that there is only one object. As if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use another key (`user`) we can see changes. +It's as if we had a cabinet with two keys and used one of them (`admin`) to get into it and make changes. Then, if we later use another key (`user`), we are still opening the same cabinet and can access the changed contents. ## Comparison by reference -The equality `==` and strict equality `===` operators for objects work exactly the same. - -**Two objects are equal only if they are the same object.** +Two objects are equal only if they are the same object. -Here two variables reference the same object, thus they are equal: +For instance, here `a` and `b` reference the same object, thus they are equal: ```js run let a = {}; @@ -77,7 +89,7 @@ alert( a == b ); // true, both variables reference the same object alert( a === b ); // true ``` -And here two independent objects are not equal, even though both are empty: +And here two independent objects are not equal, even though they look alike (both are empty): ```js run let a = {}; @@ -86,7 +98,7 @@ let b = {}; // two independent objects alert( a == b ); // false ``` -For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons occur very rarely, usually as a result of a coding mistake. +For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are needed very rarely -- usually they appear as a result of a programming mistake. ## Cloning and merging, Object.assign @@ -94,7 +106,7 @@ So, copying an object variable creates one more reference to the same object. But what if we need to duplicate an object? Create an independent copy, a clone? -That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. Actually, that's rarely needed. Copying by reference is good most of the time. +That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. But there is rarely a need -- copying by reference is good most of the time. But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level. @@ -213,15 +225,37 @@ user.sizes.width++; // change a property from one place alert(clone.sizes.width); // 51, see the result from the other one ``` -To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning". +To fix that, we should use a cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning". + +We can use recursion to implement it. Or, to not reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com). + +````smart header="Const objects can be modified" +An important side effect of storing objects as references is that an object declared as `const` *can* be modified. + +For instance: + +```js run +const user = { + name: "John" +}; + +*!* +user.name = "Pete"; // (*) +*/!* + +alert(user.name); // Pete +``` + +It might seem that the line `(*)` would cause an error, but it does not. The value of `user` is constant, it must always reference the same object, but properties of that object are free to change. -There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data). +In other words, the `const user` gives an error only if we try to set `user=...` as a whole. -We can use recursion to implement it. Or, not to reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com). +That said, if we really need to make constant object properties, it's also possible, but using totally different methods. We'll mention that in the chapter . +```` ## Summary -Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object. +Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object itself. All operations via copied references (like adding/removing properties) are performed on the same single object. diff --git a/1-js/04-object-basics/03-garbage-collection/article.md b/1-js/04-object-basics/03-garbage-collection/article.md index 3b385afd2..5a1b12a7e 100644 --- a/1-js/04-object-basics/03-garbage-collection/article.md +++ b/1-js/04-object-basics/03-garbage-collection/article.md @@ -23,7 +23,7 @@ Simply put, "reachable" values are those that are accessible or usable somehow. 2. Any other value is considered reachable if it's reachable from a root by a reference or by a chain of references. - For instance, if there's an object in a local variable, and that object has a property referencing another object, that object is considered reachable. And those that it references are also reachable. Detailed examples to follow. + For instance, if there's an object in a global variable, and that object has a property referencing another object, *that* object is considered reachable. And those that it references are also reachable. Detailed examples to follow. There's a background process in the JavaScript engine that is called [garbage collector](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)). It monitors all objects and removes those that have become unreachable. @@ -156,7 +156,7 @@ The following "garbage collection" steps are regularly performed: - The garbage collector takes roots and "marks" (remembers) them. - Then it visits and "marks" all references from them. - Then it visits marked objects and marks *their* references. All visited objects are remembered, so as not to visit the same object twice in the future. -- ...And so on until there are unvisited references (reachable from the roots). +- ...And so on until every reachable (from the roots) references are visited. - All objects except marked ones are removed. For instance, let our object structure look like this: @@ -181,9 +181,9 @@ Now the objects that could not be visited in the process are considered unreacha ![](garbage-collection-5.svg) -That's the concept of how garbage collection works. +We can also imagine the process as spilling a huge bucket of paint from the roots, that flows through all references and marks all reachable objects. The unmarked ones are then removed. -JavaScript engines apply many optimizations to make it run faster and not affect the execution. +That's the concept of how garbage collection works. JavaScript engines apply many optimizations to make it run faster and not affect the execution. Some of the optimizations: @@ -191,7 +191,7 @@ Some of the optimizations: - **Incremental collection** -- if there are many objects, and we try to walk and mark the whole object set at once, it may take some time and introduce visible delays in the execution. So the engine tries to split the garbage collection into pieces. Then the pieces are executed one by one, separately. That requires some extra bookkeeping between them to track changes, but we have many tiny delays instead of a big one. - **Idle-time collection** -- the garbage collector tries to run only while the CPU is idle, to reduce the possible effect on the execution. -There are other optimizations and flavours of garbage collection algorithms. As much as I'd like to describe them here, I have to hold off, because different engines implement different tweaks and techniques. And, what's even more important, things change as engines develop, so going deeper "in advance", without a real need is probably not worth that. Unless, of course, it is a matter of pure interest, then there will be some links for you below. +There exist other optimizations and flavours of garbage collection algorithms. As much as I'd like to describe them here, I have to hold off, because different engines implement different tweaks and techniques. And, what's even more important, things change as engines develop, so studying deeper "in advance", without a real need is probably not worth that. Unless, of course, it is a matter of pure interest, then there will be some links for you below. ## Summary diff --git a/1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg b/1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg index a67ffc3cc..2ae1f664c 100644 --- a/1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg +++ b/1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg @@ -1,56 +1 @@ - - - - family-delete-refs.svg - Created with sketchtool. - - - - - - <global variable> - - - - Object - - - - Object - - - wife - - - family - - - name: "John" - - - - name: "Ann" - - - mother - - - Object - - - - - - - - - - - father - - - husband - - - - \ No newline at end of file +<global variable>ObjectObjectwifefamilyname: "John"name: "Ann"motherObjectfatherhusband \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/family-no-family.svg b/1-js/04-object-basics/03-garbage-collection/family-no-family.svg index df8601215..655d1982e 100644 --- a/1-js/04-object-basics/03-garbage-collection/family-no-family.svg +++ b/1-js/04-object-basics/03-garbage-collection/family-no-family.svg @@ -1,57 +1 @@ - - - - family-no-family.svg - Created with sketchtool. - - - - - - <global> - - - - Object - - - - Object - - - father - - - wife - - - name: "John" - - - - name: "Ann" - - - mother - - - Object - - - - - husband - - - - - family: null - - - - - - - - - \ No newline at end of file +<global>ObjectObjectfatherwifename: "John"name: "Ann"motherObjecthusbandfamily: null \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg b/1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg index 502785902..11f4ada35 100644 --- a/1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg +++ b/1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg @@ -1,33 +1 @@ - - - - family-no-father-2.svg - Created with sketchtool. - - - - - Object - - - family - - - - name: "Ann" - - - mother - - - Object - - - - - - <global> - - - - \ No newline at end of file +Objectfamilyname: "Ann"motherObject<global> \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/family-no-father.svg b/1-js/04-object-basics/03-garbage-collection/family-no-father.svg index 9837ced82..b76c868e0 100644 --- a/1-js/04-object-basics/03-garbage-collection/family-no-father.svg +++ b/1-js/04-object-basics/03-garbage-collection/family-no-father.svg @@ -1,50 +1 @@ - - - - family-no-father.svg - Created with sketchtool. - - - - - Object - - - - Object - - - wife - - - family - - - name: "John" - - - - name: "Ann" - - - mother - - - Object - - - - - - - - - - - - - <global> - - - - \ No newline at end of file +ObjectObjectwifefamilyname: "John"name: "Ann"motherObject<global> \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/family.svg b/1-js/04-object-basics/03-garbage-collection/family.svg index 6c66e8569..bec2f4ddc 100644 --- a/1-js/04-object-basics/03-garbage-collection/family.svg +++ b/1-js/04-object-basics/03-garbage-collection/family.svg @@ -1,52 +1 @@ - - - - family.svg - Created with sketchtool. - - - - - - Object - - - - Object - - - father - - - wife - - - family - - - name: "John" - - - - name: "Ann" - - - mother - - - Object - - - - - - husband - - - - - <global variable> - - - - \ No newline at end of file +ObjectObjectfatherwifefamilyname: "John"name: "Ann"motherObjecthusband<global variable> \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg index d3bc5ce94..2563c8185 100644 --- a/1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg @@ -1,162 +1 @@ - - - - garbage-collection-1.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - <global> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +<global> \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg index c7311022a..acd5025e9 100644 --- a/1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg @@ -1,178 +1 @@ - - - - garbage-collection-2.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - <global> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +<global> \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg index a0ce257e3..4421ec784 100644 --- a/1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg @@ -1,190 +1 @@ - - - - garbage-collection-3.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - <global> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +<global> \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg index bc5a035c7..74adc8135 100644 --- a/1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg @@ -1,194 +1 @@ - - - - garbage-collection-4.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - <global> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +<global> \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg index 150aa9265..abb127ab2 100644 --- a/1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg +++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg @@ -1,212 +1 @@ - - - - garbage-collection-5.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <global> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - unreachables - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +<global>unreachables \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg b/1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg index bc7a23d33..dc4cce1c7 100644 --- a/1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg +++ b/1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg @@ -1,29 +1 @@ - - - - memory-user-john-admin.svg - Created with sketchtool. - - - - user - - - - name: "John" - - - Object - - - - admin - - - - - <global> - - - - \ No newline at end of file +username: "John"Objectadmin<global> \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg b/1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg index 78009e310..e75b8d465 100644 --- a/1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg +++ b/1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg @@ -1,30 +1 @@ - - - - memory-user-john-lost.svg - Created with sketchtool. - - - - - name: "John" - - - Object - - - - user: null - - - <global> - - - - - - - - - - \ No newline at end of file +name: "John"Objectuser: null<global> \ No newline at end of file diff --git a/1-js/04-object-basics/03-garbage-collection/memory-user-john.svg b/1-js/04-object-basics/03-garbage-collection/memory-user-john.svg index 45ce86ed2..0191e3f07 100644 --- a/1-js/04-object-basics/03-garbage-collection/memory-user-john.svg +++ b/1-js/04-object-basics/03-garbage-collection/memory-user-john.svg @@ -1,25 +1 @@ - - - - memory-user-john.svg - Created with sketchtool. - - - - user - - - - name: "John" - - - Object - - - - - <global> - - - - \ No newline at end of file +username: "John"Object<global> \ No newline at end of file diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md b/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md deleted file mode 100644 index e2e87de7c..000000000 --- a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md +++ /dev/null @@ -1,43 +0,0 @@ -**Error**! - -Try it: - -```js run -let user = { - name: "John", - go: function() { alert(this.name) } -} - -(user.go)() // error! -``` - -The error message in most browsers does not give understanding what went wrong. - -**The error appears because a semicolon is missing after `user = {...}`.** - -JavaScript does not assume a semicolon before a bracket `(user.go)()`, so it reads the code like: - -```js no-beautify -let user = { go:... }(user.go)() -``` - -Then we can also see that such a joint expression is syntactically a call of the object `{ go: ... }` as a function with the argument `(user.go)`. And that also happens on the same line with `let user`, so the `user` object has not yet even been defined, hence the error. - -If we insert the semicolon, all is fine: - -```js run -let user = { - name: "John", - go: function() { alert(this.name) } -}*!*;*/!* - -(user.go)() // John -``` - -Please note that brackets around `(user.go)` do nothing here. Usually they setup the order of operations, but here the dot `.` works first anyway, so there's no effect. Only the semicolon thing matters. - - - - - - diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md b/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md deleted file mode 100644 index f40d68735..000000000 --- a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md +++ /dev/null @@ -1,19 +0,0 @@ -importance: 2 - ---- - -# Syntax check - -What is the result of this code? - - -```js no-beautify -let user = { - name: "John", - go: function() { alert(this.name) } -} - -(user.go)() -``` - -P.S. There's a pitfall :) diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md b/1-js/04-object-basics/04-object-methods/3-why-this/solution.md deleted file mode 100644 index 89bc0d722..000000000 --- a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md +++ /dev/null @@ -1,22 +0,0 @@ - -Here's the explanations. - -1. That's a regular object method call. - -2. The same, brackets do not change the order of operations here, the dot is first anyway. - -3. Here we have a more complex call `(expression).method()`. The call works as if it were split into two lines: - - ```js no-beautify - f = obj.go; // calculate the expression - f(); // call what we have - ``` - - Here `f()` is executed as a function, without `this`. - -4. The similar thing as `(3)`, to the left of the dot `.` we have an expression. - -To explain the behavior of `(3)` and `(4)` we need to recall that property accessors (dot or square brackets) return a value of the Reference Type. - -Any operation on it except a method call (like assignment `=` or `||`) turns it into an ordinary value, which does not carry the information allowing to set `this`. - diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/task.md b/1-js/04-object-basics/04-object-methods/3-why-this/task.md deleted file mode 100644 index f22de29cc..000000000 --- a/1-js/04-object-basics/04-object-methods/3-why-this/task.md +++ /dev/null @@ -1,26 +0,0 @@ -importance: 3 - ---- - -# Explain the value of "this" - -In the code below we intend to call `user.go()` method 4 times in a row. - -But calls `(1)` and `(2)` works differently from `(3)` and `(4)`. Why? - -```js run no-beautify -let obj, method; - -obj = { - go: function() { alert(this); } -}; - -obj.go(); // (1) [object Object] - -(obj.go)(); // (2) [object Object] - -(method = obj.go)(); // (3) undefined - -(obj.go || obj.stop)(); // (4) undefined -``` - diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md index f5773ec2c..a839f3b14 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md @@ -7,7 +7,7 @@ function makeUser() { name: "John", ref: this }; -}; +} let user = makeUser(); @@ -22,6 +22,17 @@ And the object literal itself has no effect on `this`. The value of `this` is on So `ref: this` actually takes current `this` of the function. +We can rewrite the function and return the same `this` with `undefined` value: + +```js run +function makeUser(){ + return this; // this time there's no object literal +} + +alert( makeUser().name ); // Error: Cannot read property 'name' of undefined +``` +As you can see the result of `alert( makeUser().name )` is the same as the result of `alert( user.ref.name )` from the previous example. + Here's the opposite case: ```js run @@ -34,7 +45,7 @@ function makeUser() { } */!* }; -}; +} let user = makeUser(); diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md index 4784b082c..c6f8f9658 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md @@ -14,7 +14,7 @@ function makeUser() { name: "John", ref: this }; -}; +} let user = makeUser(); diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index 0418adee0..0d3c1f392 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -15,7 +15,7 @@ Actions are represented in JavaScript by functions in properties. ## Method examples -For the start, let's teach the `user` to say hello: +For a start, let's teach the `user` to say hello: ```js run let user = { @@ -32,11 +32,11 @@ user.sayHi = function() { user.sayHi(); // Hello! ``` -Here we've just used a Function Expression to create the function and assign it to the property `user.sayHi` of the object. +Here we've just used a Function Expression to create a function and assign it to the property `user.sayHi` of the object. -Then we can call it. The user can now speak! +Then we can call it as `user.sayHi()`. The user can now speak! -A function that is the property of an object is called its *method*. +A function that is a property of an object is called its *method*. So, here we've got a method `sayHi` of the object `user`. @@ -61,9 +61,9 @@ user.sayHi(); // Hello! ``` ```smart header="Object-oriented programming" -When we write our code using objects to represent entities, that's called an [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming), in short: "OOP". +When we write our code using objects to represent entities, that's called [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming), in short: "OOP". -OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides or "Object-Oriented Analysis and Design with Applications" by G.Booch, and more. +OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E. Gamma, R. Helm, R. Johnson, J. Vissides or "Object-Oriented Analysis and Design with Applications" by G. Booch, and more. ``` ### Method shorthand @@ -72,14 +72,14 @@ There exists a shorter syntax for methods in an object literal: ```js // these objects do the same -let user = { +user = { sayHi: function() { alert("Hello"); } }; // method shorthand looks better, right? -let user = { +user = { *!* sayHi() { // same as "sayHi: function()" */!* @@ -111,6 +111,7 @@ let user = { sayHi() { *!* + // "this" is the "current object" alert(this.name); */!* } @@ -159,16 +160,18 @@ let user = { let admin = user; user = null; // overwrite to make things obvious -admin.sayHi(); // Whoops! inside sayHi(), the old name is used! error! +*!* +admin.sayHi(); // TypeError: Cannot read property 'name' of null +*/!* ``` If we used `this.name` instead of `user.name` inside the `alert`, then the code would work. ## "this" is not bound -In JavaScript, "this" keyword behaves unlike most other programming languages. First, it can be used in any function. +In JavaScript, keyword `this` behaves unlike most other programming languages. It can be used in any function, even if it's not a method of an object. -There's no syntax error in the code like that: +There's no syntax error in the following example: ```js function sayHi() { @@ -176,9 +179,9 @@ function sayHi() { } ``` -The value of `this` is evaluated during the run-time. And it can be anything. +The value of `this` is evaluated during the run-time, depending on the context. -For instance, the same function may have different "this" when called from different objects: +For instance, here the same function is assigned to two different objects and has different "this" in the calls: ```js run let user = { name: "John" }; @@ -189,7 +192,7 @@ function sayHi() { } *!* -// use the same functions in two objects +// use the same function in two objects user.f = sayHi; admin.f = sayHi; */!* @@ -202,7 +205,10 @@ admin.f(); // Admin (this == admin) admin['f'](); // Admin (dot or square brackets access the method – doesn't matter) ``` -Actually, we can call the function without an object at all: +The rule is simple: if `obj.f()` is called, then `this` is `obj` during the call of `f`. So it's either `user` or `admin` in the example above. + +````smart header="Calling without an object: `this == undefined`" +We can even call the function without an object at all: ```js run function sayHi() { @@ -216,108 +222,19 @@ In this case `this` is `undefined` in strict mode. If we try to access `this.nam In non-strict mode the value of `this` in such case will be the *global object* (`window` in a browser, we'll get to it later in the chapter [](info:global-object)). This is a historical behavior that `"use strict"` fixes. -Please note that usually a call of a function that uses `this` without an object is not normal, but rather a programming mistake. If a function has `this`, then it is usually meant to be called in the context of an object. +Usually such call is a programming error. If there's `this` inside a function, it expects to be called in an object context. +```` ```smart header="The consequences of unbound `this`" If you come from another programming language, then you are probably used to the idea of a "bound `this`", where methods defined in an object always have `this` referencing that object. -In JavaScript `this` is "free", its value is evaluated at call-time and does not depend on where the method was declared, but rather on what's the object "before the dot". - -The concept of run-time evaluated `this` has both pluses and minuses. On the one hand, a function can be reused for different objects. On the other hand, greater flexibility opens a place for mistakes. - -Here our position is not to judge whether this language design decision is good or bad. We'll understand how to work with it, how to get benefits and evade problems. -``` - -## Internals: Reference Type - -```warn header="In-depth language feature" -This section covers an advanced topic, to understand certain edge-cases better. - -If you want to go on faster, it can be skipped or postponed. -``` - -An intricate method call can lose `this`, for instance: - -```js run -let user = { - name: "John", - hi() { alert(this.name); }, - bye() { alert("Bye"); } -}; - -user.hi(); // John (the simple call works) - -*!* -// now let's call user.hi or user.bye depending on the name -(user.name == "John" ? user.hi : user.bye)(); // Error! -*/!* -``` - -On the last line there is a ternary operator that chooses either `user.hi` or `user.bye`. In this case the result is `user.hi`. - -The method is immediately called with parentheses `()`. But it doesn't work right! +In JavaScript `this` is "free", its value is evaluated at call-time and does not depend on where the method was declared, but rather on what object is "before the dot". -You can see that the call results in an error, because the value of `"this"` inside the call becomes `undefined`. +The concept of run-time evaluated `this` has both pluses and minuses. On the one hand, a function can be reused for different objects. On the other hand, the greater flexibility creates more possibilities for mistakes. -This works (object dot method): -```js -user.hi(); +Here our position is not to judge whether this language design decision is good or bad. We'll understand how to work with it, how to get benefits and avoid problems. ``` -This doesn't (evaluated method): -```js -(user.name == "John" ? user.hi : user.bye)(); // Error! -``` - -Why? If we want to understand why it happens, let's get under the hood of how `obj.method()` call works. - -Looking closely, we may notice two operations in `obj.method()` statement: - -1. First, the dot `'.'` retrieves the property `obj.method`. -2. Then parentheses `()` execute it. - -So, how does the information about `this` get passed from the first part to the second one? - -If we put these operations on separate lines, then `this` will be lost for sure: - -```js run -let user = { - name: "John", - hi() { alert(this.name); } -} - -*!* -// split getting and calling the method in two lines -let hi = user.hi; -hi(); // Error, because this is undefined -*/!* -``` - -Here `hi = user.hi` puts the function into the variable, and then on the last line it is completely standalone, and so there's no `this`. - -**To make `user.hi()` calls work, JavaScript uses a trick -- the dot `'.'` returns not a function, but a value of the special [Reference Type](https://tc39.github.io/ecma262/#sec-reference-specification-type).** - -The Reference Type is a "specification type". We can't explicitly use it, but it is used internally by the language. - -The value of Reference Type is a three-value combination `(base, name, strict)`, where: - -- `base` is the object. -- `name` is the property. -- `strict` is true if `use strict` is in effect. - -The result of a property access `user.hi` is not a function, but a value of Reference Type. For `user.hi` in strict mode it is: - -```js -// Reference Type value -(user, "hi", true) -``` - -When parentheses `()` are called on the Reference Type, they receive the full information about the object and its method, and can set the right `this` (`=user` in this case). - -Any other operation like assignment `hi = user.hi` discards the reference type as a whole, takes the value of `user.hi` (a function) and passes it on. So any further operation "loses" `this`. - -So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj['method']()` syntax (they do the same here). Later in this tutorial, we will learn various ways to solve this problem such as [func.bind()](/bind#solution-2-bind). - ## Arrow functions have no "this" Arrow functions are special: they don't have their "own" `this`. If we reference `this` from such a function, it's taken from the outer "normal" function. @@ -347,7 +264,7 @@ That's a special feature of arrow functions, it's useful when we actually do not The value of `this` is defined at run-time. - When a function is declared, it may use `this`, but that `this` has no value until the function is called. -- That function can be copied between objects. +- A function can be copied between objects. - When a function is called in the "method" syntax: `object.method()`, the value of `this` during the call is `object`. Please note that arrow functions are special: they have no `this`. When `this` is accessed inside an arrow function, it is taken from outside. diff --git a/1-js/04-object-basics/06-constructor-new/article.md b/1-js/04-object-basics/06-constructor-new/article.md index eb452f2f3..e224354a2 100644 --- a/1-js/04-object-basics/06-constructor-new/article.md +++ b/1-js/04-object-basics/06-constructor-new/article.md @@ -27,7 +27,7 @@ alert(user.name); // Jack alert(user.isAdmin); // false ``` -When a function is executed as `new User(...)`, it does the following steps: +When a function is executed with `new`, it does the following steps: 1. A new empty object is created and assigned to `this`. 2. The function body executes. Usually it modifies `this`, adds new properties to it. @@ -51,7 +51,7 @@ function User(name) { } ``` -So the result of `new User("Jack")` is the same object as: +So `let user = new User("Jack")` gives the same result as: ```js let user = { @@ -134,7 +134,7 @@ Usually, constructors do not have a `return` statement. Their task is to write a But if there is a `return` statement, then the rule is simple: -- If `return` is called with object, then it is returned instead of `this`. +- If `return` is called with an object, then the object is returned instead of `this`. - If `return` is called with a primitive, it's ignored. In other words, `return` with an object returns that object, in all other cases `this` is returned. @@ -146,10 +146,10 @@ function BigUser() { this.name = "John"; - return { name: "Godzilla" }; // <-- returns an object + return { name: "Godzilla" }; // <-- returns this object } -alert( new BigUser().name ); // Godzilla, got that object ^^ +alert( new BigUser().name ); // Godzilla, got that object ``` And here's an example with an empty `return` (or we could place a primitive after it, doesn't matter): @@ -159,10 +159,7 @@ function SmallUser() { this.name = "John"; - return; // finishes the execution, returns this - - // ... - + return; // <-- returns this } alert( new SmallUser().name ); // John diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md index f136b957c..deb0e5a8f 100644 --- a/1-js/04-object-basics/07-optional-chaining/article.md +++ b/1-js/04-object-basics/07-optional-chaining/article.md @@ -3,47 +3,86 @@ [recent browser="new"] -The optional chaining `?.` is an error-proof way to access nested object properties, even if an intermediate property doesn't exist. +The optional chaining `?.` is a safe way to access nested object properties, even if an intermediate property doesn't exist. -## The problem +## The "non-existing property" problem If you've just started to read the tutorial and learn JavaScript, maybe the problem hasn't touched you yet, but it's quite common. -For example, some of our users have addresses, but few did not provide them. Then we can't safely read `user.address.street`: +As an example, let's say we have `user` objects that hold the information about our users. + +Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them. + +In such case, when we attempt to get `user.address.street`, and the user happens to be without an address, we get an error: ```js run -let user = {}; // the user happens to be without address +let user = {}; // a user without "address" property alert(user.address.street); // Error! ``` -Or, in the web development, we'd like to get an information about an element on the page, but it may not exist: +That's the expected result. JavaScript works like this. As `user.address` is `undefined`, an attempt to get `user.address.street` fails with an error. + +In many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street"). + +...And another example. In the web development, we can get an object that corresponds to a web page element using a special method call, such as `document.querySelector('.elem')`, and it returns `null` when there's no such element. ```js run -// Error if the result of querySelector(...) is null -let html = document.querySelector('.my-element').innerHTML; +// document.querySelector('.elem') is null if there's no element +let html = document.querySelector('.elem').innerHTML; // error if it's null ``` -Before `?.` appeared in the language, the `&&` operator was used to work around that. +Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result. -For example: +How can we do this? + +The obvious solution would be to check the value using `if` or the conditional operator `?`, before accessing its property, like this: + +```js +let user = {}; + +alert(user.address ? user.address.street : undefined); +``` + +It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code. For more deeply nested properties, that becomes a problem as more repetitions are required. + +E.g. let's try getting `user.address.street.name`. + +We need to check both `user.address` and `user.address.street`: + +```js +let user = {}; // user has no address + +alert(user.address ? user.address.street ? user.address.street.name : null : null); +``` + +That's just awful, one may even have problems understanding such code. + +Don't even care to, as there's a better way to write it, using the `&&` operator: ```js run let user = {}; // user has no address -alert( user && user.address && user.address.street ); // undefined (no error) +alert( user.address && user.address.street && user.address.street.name ); // undefined (no error) ``` -AND'ing the whole path to the property ensures that all components exist, but is cumbersome to write. +AND'ing the whole path to the property ensures that all components exist (if not, the evaluation stops), but also isn't ideal. + +As you can see, property names are still duplicated in the code. E.g. in the code above, `user.address` appears three times. + +That's why the optional chaining `?.` was added to the language. To solve this problem once and for all! ## Optional chaining -The optional chaining `?.` stops the evaluation and returns `undefined` if the part before `?.` is `undefined` or `null`. +The optional chaining `?.` stops the evaluation if the part before `?.` is `undefined` or `null` and returns that part. -Further in this article, for brevity, we'll be saying that something "exists" if it's not `null` and not `undefined`. +**Further in this article, for brevity, we'll be saying that something "exists" if it's not `null` and not `undefined`.** +In other words, `value?.prop`: +- is the same as `value.prop` if `value` exists, +- otherwise (when `value` is `undefined/null`) it returns `undefined`. -Here's the safe way to access `user.address.street`: +Here's the safe way to access `user.address.street` using `?.`: ```js run let user = {}; // user has no address @@ -51,55 +90,57 @@ let user = {}; // user has no address alert( user?.address?.street ); // undefined (no error) ``` +The code is short and clean, there's no duplication at all. + Reading the address with `user?.address` works even if `user` object doesn't exist: ```js run let user = null; alert( user?.address ); // undefined - alert( user?.address.street ); // undefined -alert( user?.address.street.anything ); // undefined ``` -Please note: the `?.` syntax works exactly where it's placed, not any further. +Please note: the `?.` syntax makes optional the value before it, but not any further. -In the last two lines the evaluation stops immediately after `user?.`, never accessing further properties. But if the `user` actually exists, then the further intermediate properties, such as `user.address` must exist. +E.g. in `user?.address.street.name` the `?.` allows `user` to be `null/undefined`, but it's all it does. Further properties are accessed in a regular way. If we want some of them to be optional, then we'll need to replace more `.` with `?.`. ```warn header="Don't overuse the optional chaining" We should use `?.` only where it's ok that something doesn't exist. -For example, if according to our coding logic `user` object must be there, but `address` is optional, then `user.address?.street` would be better. +For example, if according to our coding logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`. -So, if `user` happens to be undefined due to a mistake, we'll know about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug. +So, if `user` happens to be undefined due to a mistake, we'll see a programming error about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug. ``` -````warn header="The variable before `?.` must exist" -If there's no variable `user`, then `user?.anything` triggers an error: +````warn header="The variable before `?.` must be declared" +If there's no variable `user` at all, then `user?.anything` triggers an error: ```js run // ReferenceError: user is not defined user?.address; ``` -The optional chaining only tests for `null/undefined`, doesn't interfere with any other language mechanics. +The variable must be declared (e.g. `let/const/var user` or as a function parameter). The optional chaining works only for declared variables. ```` ## Short-circuiting As it was said before, the `?.` immediately stops ("short-circuits") the evaluation if the left part doesn't exist. -So, if there are any further function calls or side effects, they don't occur: +So, if there are any further function calls or side effects, they don't occur. + +For instance: ```js run let user = null; let x = 0; -user?.sayHi(x++); // nothing happens +user?.sayHi(x++); // no "sayHi", so the execution doesn't reach x++ alert(x); // 0, value not incremented ``` -## Other cases: ?.(), ?.[] +## Other variants: ?.(), ?.[] The optional chaining `?.` is not an operator, but a special syntax construct, that also works with functions and square brackets. @@ -108,23 +149,26 @@ For example, `?.()` is used to call a function that may not exist. In the code below, some of our users have `admin` method, and some don't: ```js run -let user1 = { +let userAdmin = { admin() { alert("I am admin"); } -} +}; -let user2 = {}; +let userGuest = {}; *!* -user1.admin?.(); // I am admin -user2.admin?.(); +userAdmin.admin?.(); // I am admin +*/!* + +*!* +userGuest.admin?.(); // nothing (no such method) */!* ``` -Here, in both lines we first use the dot `.` to get `admin` property, because the user object must exist, so it's safe read from it. +Here, in both lines we first use the dot (`user1.admin`) to get `admin` property, because the user object must exist, so it's safe read from it. -Then `?.()` checks the left part: if the user exists, then it runs (for `user1`). Otherwise (for `user2`) the evaluation stops without errors. +Then `?.()` checks the left part: if the admin function exists, then it runs (that's so for `user1`). Otherwise (for `user2`) the evaluation stops without errors. The `?.[]` syntax also works, if we'd like to use brackets `[]` to access properties instead of dot `.`. Similar to previous cases, it allows to safely read a property from an object that may not exist. @@ -149,28 +193,30 @@ Also we can use `?.` with `delete`: delete user?.name; // delete user.name if user exists ``` -```warn header="We can use `?.` for safe reading and deleting, but not writing" -The optional chaining `?.` has no use at the left side of an assignment: +````warn header="We can use `?.` for safe reading and deleting, but not writing" +The optional chaining `?.` has no use at the left side of an assignment. +For example: ```js run -// the idea of the code below is to write user.name, if user exists +let user = null; user?.name = "John"; // Error, doesn't work // because it evaluates to undefined = "John" ``` +It's just not that smart. +```` + ## Summary -The `?.` syntax has three forms: +The optional chaining `?.` syntax has three forms: 1. `obj?.prop` -- returns `obj.prop` if `obj` exists, otherwise `undefined`. 2. `obj?.[prop]` -- returns `obj[prop]` if `obj` exists, otherwise `undefined`. -3. `obj?.method()` -- calls `obj.method()` if `obj` exists, otherwise returns `undefined`. +3. `obj.method?.()` -- calls `obj.method()` if `obj.method` exists, otherwise returns `undefined`. As we can see, all of them are straightforward and simple to use. The `?.` checks the left part for `null/undefined` and allows the evaluation to proceed if it's not so. A chain of `?.` allows to safely access nested properties. -Still, we should apply `?.` carefully, only where it's ok that the left part doesn't to exist. - -So that it won't hide programming errors from us, if they occur. +Still, we should apply `?.` carefully, only where it's acceptable that the left part doesn't to exist. So that it won't hide programming errors from us, if they occur. diff --git a/1-js/04-object-basics/08-symbol/article.md b/1-js/04-object-basics/08-symbol/article.md index 55599cccb..17e73ba50 100644 --- a/1-js/04-object-basics/08-symbol/article.md +++ b/1-js/04-object-basics/08-symbol/article.md @@ -18,7 +18,7 @@ let id = Symbol(); We can also give symbol a description (also called a symbol name), mostly useful for debugging purposes: -```js run +```js // id is a symbol with the description "id" let id = Symbol("id"); ``` @@ -50,7 +50,7 @@ alert(id); // TypeError: Cannot convert a Symbol value to a string */!* ``` -That's a "language guard" against messing up, because strings and symbols are fundamentally different and should not occasionally convert one into another. +That's a "language guard" against messing up, because strings and symbols are fundamentally different and should not accidentally convert one into another. If we really want to show a symbol, we need to explicitly call `.toString()` on it, like here: ```js run @@ -72,15 +72,11 @@ alert(id.description); // id ## "Hidden" properties -Symbols allow us to create "hidden" properties of an object, that no other part of code can occasionally access or overwrite. +Symbols allow us to create "hidden" properties of an object, that no other part of code can accidentally access or overwrite. -<<<<<<< HEAD -For instance, if we want to store an "identifier" for the object `user`, we can use a symbol as a key for it: -======= For instance, if we're working with `user` objects, that belong to a third-party code. We'd like to add identifiers to them. Let's use a symbol key for it: ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 ```js run let user = { // belongs to another code @@ -96,7 +92,7 @@ alert( user[id] ); // we can access the data using the symbol as the key What's the benefit of using `Symbol("id")` over a string `"id"`? -Let's make the example a bit deeper to see that. +As `user` objects belongs to another code, and that code also works with them, we shouldn't just add any fields to it. That's unsafe. But a symbol cannot be accessed accidentally, the third-party code probably won't even see it, so it's probably all right to do. Imagine that another script wants to have its own "id" property inside `user`, for its own purposes. That may be another JavaScript library, so the scripts are completely unaware of each other. @@ -125,7 +121,7 @@ user.id = "Their id value" // Boom! overwritten by another script! ``` -### Symbols in a literal +### Symbols in an object literal If we want to use a symbol in an object literal, we need square brackets. @@ -137,7 +133,7 @@ let id = Symbol("id"); let user = { name: "John", *!* - [id]: 123 // not "id: 123" + [id]: 123 // not "id": 123 */!* }; ``` @@ -182,22 +178,6 @@ alert( clone[id] ); // 123 There's no paradox here. That's by design. The idea is that when we clone an object or merge objects, we usually want *all* properties to be copied (including symbols like `id`). -````smart header="Property keys of other types are coerced to strings" -We can only use strings or symbols as keys in objects. Other types are converted to strings. - -For instance, a number `0` becomes a string `"0"` when used as a property key: - -```js run -let obj = { - 0: "test" // same as "0": "test" -}; - -// both alerts access the same property (the number 0 is converted to string "0") -alert( obj["0"] ); // test -alert( obj[0] ); // test (same property) -``` -```` - ## Global symbols As we've seen, usually all symbols are different, even if they have the same names. But sometimes we want same-named symbols to be same entities. @@ -246,7 +226,7 @@ alert( Symbol.keyFor(sym) ); // name alert( Symbol.keyFor(sym2) ); // id ``` -The `Symbol.keyFor` internally uses the global symbol registry to look up the key for the symbol. So it doesn't work for non-global symbols. If the symbol is not global, it won't be able to find it and return `undefined`. +The `Symbol.keyFor` internally uses the global symbol registry to look up the key for the symbol. So it doesn't work for non-global symbols. If the symbol is not global, it won't be able to find it and returns `undefined`. For instance: @@ -283,7 +263,7 @@ Symbols are always different values, even if they have the same name. If we want Symbols have two main use cases: 1. "Hidden" object properties. - If we want to add a property into an object that "belongs" to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear in `for..in`, so it won't be occasionally listed. Also it won't be accessed directly, because another script does not have our symbol, so it will not occasionally intervene into its actions. + If we want to add a property into an object that "belongs" to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear in `for..in`, so it won't be accidentally processed together with other properties. Also it won't be accessed directly, because another script does not have our symbol. So the property will be protected from accidental use or overwrite. So we can "covertly" hide something into objects that we need, but others should not see, using symbolic properties. diff --git a/1-js/04-object-basics/09-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md index a44cf4f4d..18348ab92 100644 --- a/1-js/04-object-basics/09-object-toprimitive/article.md +++ b/1-js/04-object-basics/09-object-toprimitive/article.md @@ -52,21 +52,27 @@ There are three variants: `"default"` : Occurs in rare cases when the operator is "not sure" what type to expect. - For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them), so both strings and numbers would do. Or when an object is compared using `==` with a string, number or a symbol. + For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them), so both strings and numbers would do. So if a binary plus gets an object as an argument, it uses the `"default"` hint to convert it. + + Also, if an object is compared using `==` with a string, number or a symbol, it's also unclear which conversion should be done, so the `"default"` hint is used. ```js - // binary plus - let total = car1 + car2; + // binary plus uses the "default" hint + let total = obj1 + obj2; - // obj == string/number/symbol + // obj == number uses the "default" hint if (user == 1) { ... }; ``` - The greater/less operator `<>` can work with both strings and numbers too. Still, it uses "number" hint, not "default". That's for historical reasons. + The greater and less comparison operators, such as `<` `>`, can work with both strings and numbers too. Still, they use the `"number"` hint, not `"default"`. That's for historical reasons. + + In practice though, we don't need to remember these peculiar details, because all built-in objects except for one case (`Date` object, we'll learn it later) implement `"default"` conversion the same way as `"number"`. And we can do the same. - In practice, all built-in objects except for one case (`Date` object, we'll learn it later) implement `"default"` conversion the same way as `"number"`. And probably we should do the same. +```smart header="No `\"boolean\"` hint" +Please note -- there are only three hints. It's that simple. -Please note -- there are only three hints. It's that simple. There is no "boolean" hint (all objects are `true` in boolean context) or anything else. And if we treat `"default"` and `"number"` the same, like most built-ins do, then there are only two conversions. +There is no "boolean" hint (all objects are `true` in boolean context) or anything else. And if we treat `"default"` and `"number"` the same, like most built-ins do, then there are only two conversions. +``` **To do the conversion, JavaScript tries to find and call three object methods:** @@ -118,7 +124,29 @@ If there's no `Symbol.toPrimitive` then JavaScript tries to find them and try in - `toString -> valueOf` for "string" hint. - `valueOf -> toString` otherwise. -For instance, here `user` does the same as above using a combination of `toString` and `valueOf`: +These methods must return a primitive value. If `toString` or `valueOf` returns an object, then it's ignored (same as if there were no method). + +By default, a plain object has following `toString` and `valueOf` methods: + +- The `toString` method returns a string `"[object Object]"`. +- The `valueOf` method returns the object itself. + +Here's the demo: + +```js run +let user = {name: "John"}; + +alert(user); // [object Object] +alert(user.valueOf() === user); // true +``` + +So if we try to use an object as a string, like in an `alert` or so, then by default we see `[object Object]`. + +And the default `valueOf` is mentioned here only for the sake of completeness, to avoid any confusion. As you can see, it returns the object itself, and so is ignored. Don't ask me why, that's for historical reasons. So we can assume it doesn't exist. + +Let's implement these methods. + +For instance, here `user` does the same as above using a combination of `toString` and `valueOf` instead of `Symbol.toPrimitive`: ```js run let user = { @@ -164,7 +192,7 @@ In the absence of `Symbol.toPrimitive` and `valueOf`, `toString` will handle all The important thing to know about all primitive-conversion methods is that they do not necessarily return the "hinted" primitive. -There is no control whether `toString()` returns exactly a string, or whether `Symbol.toPrimitive` method returns a number for a hint "number". +There is no control whether `toString` returns exactly a string, or whether `Symbol.toPrimitive` method returns a number for a hint `"number"`. **The only mandatory thing: these methods must return a primitive.** @@ -172,41 +200,42 @@ An operation that initiated the conversion gets that primitive, and then continu For instance: -- Mathematical operations (except binary plus) perform `ToNumber` conversion: +## Further conversions - ```js run - let obj = { - toString() { // toString handles all conversions in the absence of other methods - return "2"; - } - }; +As we know already, many operators and functions perform type conversions, e.g. multiplication `*` converts operands to numbers. + +If we pass an object as an argument, then there are two stages: +1. The object is converted to a primitive (using the rules described above). +2. If the resulting primitive isn't of the right type, it's converted. alert(obj * 2); // 4, ToPrimitive gives "2", then it becomes 2 ``` -- Binary plus checks the primitive -- if it's a string, then it does concatenation, otherwise it performs `ToNumber` and works with numbers. +```js run +let obj = { + // toString handles all conversions in the absence of other methods + toString() { + return "2"; + } +}; - String example: - ```js run - let obj = { - toString() { - return "2"; - } - }; +alert(obj * 2); // 4, object converted to primitive "2", then multiplication made it a number +``` - alert(obj + 2); // 22 (ToPrimitive returned string => concatenation) - ``` +1. The multiplication `obj * 2` first converts the object to primitive (that's a string `"2"`). +2. Then `"2" * 2` becomes `2 * 2` (the string is converted to number). - Number example: - ```js run - let obj = { - toString() { - return true; - } - }; +Binary plus will concatenate strings in the same situation, as it gladly accepts a string: - alert(obj + 2); // 3 (ToPrimitive returned boolean, not string => ToNumber) - ``` +```js run +let obj = { + toString() { + return "2"; + } +}; + +alert(obj + 2); // 22 ("2" + 2), conversion to primitive returned a string => concatenation +``` ```smart header="Historical notes" For historical reasons, methods `toString` or `valueOf` *should* return a primitive: if any of them returns an object, then there's no error, but that object is ignored (like if the method didn't exist). diff --git a/1-js/05-data-types/01-primitives-methods/article.md b/1-js/05-data-types/01-primitives-methods/article.md index 65372c478..0c3a78299 100644 --- a/1-js/05-data-types/01-primitives-methods/article.md +++ b/1-js/05-data-types/01-primitives-methods/article.md @@ -9,7 +9,7 @@ Vejamos as principais diferenças entre primitivos e objetos. Um primitivo - É um valor de um tipo primitivo. -- Existem 6 tipos primitivos: `string`, `number`, `boolean`, `symbol`, `null` e `undefined`. +- Existem 7 tipos primitivos: `string`, `number`, `bigint`, `boolean`, `symbol`, `null` e `undefined`. Um objeto @@ -52,7 +52,7 @@ A solução parece um pouco estranha, mas aqui está: Os "invólucros de objeto" são diferentes para cada tipo primitivo e são chamados: `String`, `Number`, `Boolean` e `Symbol`. Assim, eles fornecem diferentes conjuntos de métodos. -Por exemplo, existe um método [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) que retorna uma string em letras maiúsculas. +Por exemplo, existe um método para *strings* [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) que retorna `str` em letras maiúsculas. Veja como isso funciona: diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md index 7ca012c27..6df188712 100644 --- a/1-js/05-data-types/02-number/article.md +++ b/1-js/05-data-types/02-number/article.md @@ -1,8 +1,12 @@ # Numbers -All numbers in JavaScript are stored in 64-bit format [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985), also known as "double precision". +In modern JavaScript, there are two types of numbers: -Let's recap and expand upon what we currently know about them. +1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter. + +2. BigInt numbers, to represent integers of arbitrary length. They are sometimes needed, because a regular number can't exceed 253 or be less than -253. As bigints are used in few special areas, we devote them a special chapter . + +So here we'll talk about regular numbers. Let's expand our knowledge of them. ## More ways to write a number @@ -29,14 +33,13 @@ In other words, `"e"` multiplies the number by `1` with the given zeroes count. 1.23e6 = 1.23 * 1000000 ``` - Now let's write something very small. Say, 1 microsecond (one millionth of a second): ```js let ms = 0.000001; ``` -Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could say: +Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could say the same as: ```js let ms = 1e-6; // six zeroes to the left from 1 @@ -145,7 +148,7 @@ There are two ways to do so: 1. Multiply-and-divide. - For example, to round the number to the 2nd digit after the decimal, we can multiply the number by `100`, call the rounding function and then divide it back. + For example, to round the number to the 2nd digit after the decimal, we can multiply the number by `100` (or a bigger power of 10), call the rounding function and then divide it back. ```js run let num = 1.23456; @@ -201,7 +204,7 @@ Strange! What is it then if not `0.3`? alert( 0.1 + 0.2 ); // 0.30000000000000004 ``` -Ouch! There are more consequences than an incorrect comparison here. Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their chart. The order total will be `$0.30000000000000004`. That would surprise anyone. +Ouch! There are more consequences than an incorrect comparison here. Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their cart. The order total will be `$0.30000000000000004`. That would surprise anyone. But why does this happen? @@ -271,13 +274,11 @@ JavaScript doesn't trigger an error in such events. It does its best to fit the ```smart header="Two zeroes" Another funny consequence of the internal representation of numbers is the existence of two zeroes: `0` and `-0`. -That's because a sign is represented by a single bit, so every number can be positive or negative, including a zero. +That's because a sign is represented by a single bit, so it can be set or not set for any number including a zero. In most cases the distinction is unnoticeable, because operators are suited to treat them as the same. ``` - - ## Tests: isFinite and isNaN Remember these two special numeric values? @@ -323,7 +324,7 @@ Please note that an empty or a space-only string is treated as `0` in all numeri ```smart header="Compare with `Object.is`" -There is a special built-in method [Object.is](mdn:js/Object/is) that compares values like `===`, but is more reliable for two edge cases: +There is a special built-in method [`Object.is`](mdn:js/Object/is) that compares values like `===`, but is more reliable for two edge cases: 1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing. 2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, it rarely matters, but these values technically are different. @@ -405,19 +406,19 @@ A few examples: alert( Math.pow(2, 10) ); // 2 in power 10 = 1024 ``` -There are more functions and constants in `Math` object, including trigonometry, which you can find in the [docs for the Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object. +There are more functions and constants in `Math` object, including trigonometry, which you can find in the [docs for the Math object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math). ## Summary -To write big numbers: +To write numbers with many zeroes: -- Append `"e"` with the zeroes count to the number. Like: `123e6` is `123` with 6 zeroes. -- A negative number after `"e"` causes the number to be divided by 1 with given zeroes. That's for one-millionth or such. +- Append `"e"` with the zeroes count to the number. Like: `123e6` is the same as `123` with 6 zeroes `123000000`. +- A negative number after `"e"` causes the number to be divided by 1 with given zeroes. E.g. `123e-6` means `0.000123` (`123` millionths). For different numeral systems: -- Can write numbers directly in hex (`0x`), octal (`0o`) and binary (`0b`) systems -- `parseInt(str, base)` parses an integer from any numeral system with base: `2 ≤ base ≤ 36`. +- Can write numbers directly in hex (`0x`), octal (`0o`) and binary (`0b`) systems. +- `parseInt(str, base)` parses the string `str` into an integer in numeral system with given `base`, `2 ≤ base ≤ 36`. - `num.toString(base)` converts a number to a string in the numeral system with the given `base`. For converting values like `12pt` and `100px` to a number: diff --git a/1-js/05-data-types/03-string/3-truncate/solution.md b/1-js/05-data-types/03-string/3-truncate/solution.md index 5546c47ee..d51672ae6 100644 --- a/1-js/05-data-types/03-string/3-truncate/solution.md +++ b/1-js/05-data-types/03-string/3-truncate/solution.md @@ -1,6 +1,6 @@ The maximal length must be `maxlength`, so we need to cut it a little shorter, to give space for the ellipsis. -Note that there is actually a single unicode character for an ellipsis. That's not three dots. +Note that there is actually a single Unicode character for an ellipsis. That's not three dots. ```js run demo function truncate(str, maxlength) { diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md index b7e619188..4b8e8aa8a 100644 --- a/1-js/05-data-types/03-string/article.md +++ b/1-js/05-data-types/03-string/article.md @@ -17,7 +17,7 @@ let double = "double-quoted"; let backticks = `backticks`; ``` -Single and double quotes are essentially the same. Backticks, however, allow us to embed any expression into the string, including function calls: +Single and double quotes are essentially the same. Backticks, however, allow us to embed any expression into the string, by wrapping it in `${…}`: ```js run function sum(a, b) { @@ -39,20 +39,22 @@ let guestList = `Guests: alert(guestList); // a list of guests, multiple lines ``` -If we try to use single or double quotes in the same way, there will be an error: +Looks natural, right? But single or double quotes do not work this way. + +If we use them and try to use multiple lines, there'll be an error: + ```js run -let guestList = "Guests: // Error: Unexpected token ILLEGAL +let guestList = "Guests: // Error: Unexpected token ILLEGAL * John"; ``` Single and double quotes come from ancient times of language creation when the need for multiline strings was not taken into account. Backticks appeared much later and thus are more versatile. -Backticks also allow us to specify a "template function" before the first backtick. The syntax is: func`string`. The function `func` is called automatically, receives the string and embedded expressions and can process them. You can read more about it in the [docs](mdn:/JavaScript/Reference/Template_literals#Tagged_template_literals). This is called "tagged templates". This feature makes it easier to wrap strings into custom templating or other functionality, but it is rarely used. - +Backticks also allow us to specify a "template function" before the first backtick. The syntax is: func`string`. The function `func` is called automatically, receives the string and embedded expressions and can process them. This is called "tagged templates". This feature makes it easier to implement custom templating, but is rarely used in practice. You can read more about it in the [manual](mdn:/JavaScript/Reference/Template_literals#Tagged_templates). ## Special characters -It is still possible to create multiline strings with single quotes by using a so-called "newline character", written as `\n`, which denotes a line break: +It is still possible to create multiline strings with single and double quotes by using a so-called "newline character", written as `\n`, which denotes a line break: ```js run let guestList = "Guests:\n * John\n * Pete\n * Mary"; @@ -60,39 +62,45 @@ let guestList = "Guests:\n * John\n * Pete\n * Mary"; alert(guestList); // a multiline list of guests ``` -For example, these two lines describe the same: +For example, these two lines are equal, just written differently: ```js run -alert( "Hello\nWorld" ); // two lines using a "newline symbol" +let str1 = "Hello\nWorld"; // two lines using a "newline symbol" // two lines using a normal newline and backticks -alert( `Hello -World` ); +let str2 = `Hello +World`; + +alert(str1 == str2); // true ``` -There are other, less common "special" characters as well. Here's the list: +There are other, less common "special" characters. + +Here's the full list: | Character | Description | |-----------|-------------| -|`\b`|Backspace| -|`\f`|Form feed| |`\n`|New line| -|`\r`|Carriage return| +|`\r`|Carriage return: not used alone. Windows text files use a combination of two characters `\r\n` to represent a line break. | +|`\'`, `\"`|Quotes| +|`\\`|Backslash| |`\t`|Tab| -|`\uNNNN`|A unicode symbol with the hex code `NNNN`, for instance `\u00A9` -- is a unicode for the copyright symbol `©`. It must be exactly 4 hex digits. | -|`\u{NNNNNNNN}`|Some rare characters are encoded with two unicode symbols, taking up to 4 bytes. This long unicode requires braces around it.| +|`\b`, `\f`, `\v`| Backspace, Form Feed, Vertical Tab -- kept for compatibility, not used nowadays. | +|`\xXX`|Unicode character with the given hexadecimal Unicode `XX`, e.g. `'\x7A'` is the same as `'z'`.| +|`\uXXXX`|A Unicode symbol with the hex code `XXXX` in UTF-16 encoding, for instance `\u00A9` -- is a Unicode for the copyright symbol `©`. It must be exactly 4 hex digits. | +|`\u{X…XXXXXX}` (1 to 6 hex characters)|A Unicode symbol with the given UTF-32 encoding. Some rare characters are encoded with two Unicode symbols, taking 4 bytes. This way we can insert long codes. | -Examples with unicode: +Examples with Unicode: ```js run alert( "\u00A9" ); // © -alert( "\u{20331}" ); // 佫, a rare chinese hieroglyph (long unicode) -alert( "\u{1F60D}" ); // 😍, a smiling face symbol (another long unicode) +alert( "\u{20331}" ); // 佫, a rare Chinese hieroglyph (long Unicode) +alert( "\u{1F60D}" ); // 😍, a smiling face symbol (another long Unicode) ``` All special characters start with a backslash character `\`. It is also called an "escape character". -We would also use it if we want to insert a quote into the string. +We might also use it if we wanted to insert a quote into the string. For instance: @@ -102,7 +110,7 @@ alert( 'I*!*\'*/!*m the Walrus!' ); // *!*I'm*/!* the Walrus! As you can see, we have to prepend the inner quote by the backslash `\'`, because otherwise it would indicate the string end. -Of course, that refers only to the quotes that are same as the enclosing ones. So, as a more elegant solution, we could switch to double quotes or backticks instead: +Of course, only the quotes that are the same as the enclosing ones need to be escaped. So, as a more elegant solution, we could switch to double quotes or backticks instead: ```js run alert( `I'm the Walrus!` ); // I'm the Walrus! @@ -120,7 +128,6 @@ alert( `The backslash: \\` ); // The backslash: \ ## String length - The `length` property has the string length: ```js run @@ -189,7 +196,7 @@ For instance: ```js run let str = 'Hi'; -str = 'h' + str[1]; // replace the string +str = 'h' + str[1]; // replace the string alert( str ); // hi ``` @@ -232,7 +239,7 @@ alert( str.indexOf('widget') ); // -1, not found, the search is case-sensitive alert( str.indexOf("id") ); // 1, "id" is found at the position 1 (..idget with id) ``` -The optional second parameter allows us to search starting from the given position. +The optional second parameter allows us to start searching from a given position. For instance, the first occurrence of `"id"` is at position `1`. To look for the next occurrence, let's start the search from position `2`: @@ -242,10 +249,8 @@ let str = 'Widget with id'; alert( str.indexOf('id', 2) ) // 12 ``` - If we're interested in all occurrences, we can run `indexOf` in a loop. Every new call is made with the position after the previous match: - ```js run let str = 'As sly as a fox, as strong as an ox'; @@ -305,10 +310,11 @@ if (str.indexOf("Widget") != -1) { } ``` -````smart header="The bitwise NOT trick" -One of the old tricks used here is the [bitwise NOT](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) `~` operator. It converts the number to a 32-bit integer (removes the decimal part if exists) and then reverses all bits in its binary representation. +#### The bitwise NOT trick + +One of the old tricks used here is the [bitwise NOT](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT) `~` operator. It converts the number to a 32-bit integer (removes the decimal part if exists) and then reverses all bits in its binary representation. -For 32-bit integers the call `~n` means exactly the same as `-(n+1)` (due to IEEE-754 format). +In practice, that means a simple thing: for 32-bit integers `~n` equals `-(n+1)`. For instance: @@ -321,9 +327,9 @@ alert( ~-1 ); // 0, the same as -(-1+1) */!* ``` -As we can see, `~n` is zero only if `n == -1`. +As we can see, `~n` is zero only if `n == -1` (that's for any 32-bit signed integer `n`). -So, the test `if ( ~str.indexOf("...") )` is truthy that the result of `indexOf` is not `-1`. In other words, when there is a match. +So, the test `if ( ~str.indexOf("...") )` is truthy only if the result of `indexOf` is not `-1`. In other words, when there is a match. People use it to shorten `indexOf` checks: @@ -338,7 +344,10 @@ if (~str.indexOf("Widget")) { It is usually not recommended to use language features in a non-obvious way, but this particular trick is widely used in old code, so we should understand it. Just remember: `if (~str.indexOf(...))` reads as "if found". -```` + +To be precise though, as big numbers are truncated to 32 bits by `~` operator, there exist other numbers that give `0`, the smallest is `~4294967295=0`. That makes such check correct only if a string is not that long. + +Right now we can see this trick only in the old code, as modern JavaScript provides `.includes` method (see below). ### includes, startsWith, endsWith @@ -363,7 +372,7 @@ The methods [str.startsWith](mdn:js/String/startsWith) and [str.endsWith](mdn:js ```js run alert( "Widget".startsWith("Wid") ); // true, "Widget" starts with "Wid" -alert( "Widget".endsWith("get") ); // true, "Widget" ends with "get" +alert( "Widget".endsWith("get") ); // true, "Widget" ends with "get" ``` ## Getting a substring @@ -385,7 +394,7 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and ```js run let str = "st*!*ringify*/!*"; - alert( str.slice(2) ); // ringify, from the 2nd position till the end + alert( str.slice(2) ); // 'ringify', from the 2nd position till the end ``` Negative values for `start/end` are also possible. They mean the position is counted from the string end: @@ -394,10 +403,9 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and let str = "strin*!*gif*/!*y"; // start at the 4th position from the right, end at the 1st from the right - alert( str.slice(-4, -1) ); // gif + alert( str.slice(-4, -1) ); // 'gif' ``` - `str.substring(start [, end])` : Returns the part of the string *between* `start` and `end`. @@ -405,7 +413,6 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and For instance: - ```js run let str = "st*!*ring*/!*ify"; @@ -421,7 +428,6 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and Negative arguments are (unlike slice) not supported, they are treated as `0`. - `str.substr(start [, length])` : Returns the part of the string from `start`, with the given `length`. @@ -429,14 +435,14 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and ```js run let str = "st*!*ring*/!*ify"; - alert( str.substr(2, 4) ); // ring, from the 2nd position get 4 characters + alert( str.substr(2, 4) ); // 'ring', from the 2nd position get 4 characters ``` The first argument may be negative, to count from the end: ```js run let str = "strin*!*gi*/!*fy"; - alert( str.substr(-4, 2) ); // gi, from the 4th position get 2 characters + alert( str.substr(-4, 2) ); // 'gi', from the 4th position get 2 characters ``` Let's recap these methods to avoid any confusion: @@ -447,11 +453,10 @@ Let's recap these methods to avoid any confusion: | `substring(start, end)` | between `start` and `end` | negative values mean `0` | | `substr(start, length)` | from `start` get `length` characters | allows negative `start` | - ```smart header="Which one to choose?" All of them can do the job. Formally, `substr` has a minor drawback: it is described not in the core JavaScript specification, but in Annex B, which covers browser-only features that exist mainly for historical reasons. So, non-browser environments may fail to support it. But in practice it works everywhere. -The author finds themself using `slice` almost all the time. +Of the other two variants, `slice` is a little bit more flexible, it allows negative arguments and shorter to write. So, it's enough to remember solely `slice` of these three methods. ``` ## Comparing strings @@ -494,7 +499,7 @@ All strings are encoded using [UTF-16](https://en.wikipedia.org/wiki/UTF-16). Th alert( String.fromCodePoint(90) ); // Z ``` - We can also add unicode characters by their codes using `\u` followed by the hex code: + We can also add Unicode characters by their codes using `\u` followed by the hex code: ```js run // 90 is 5a in hexadecimal system @@ -514,7 +519,7 @@ alert( str ); // ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜ ``` -See? Capital characters go first, then a few special ones, then lowercase characters. +See? Capital characters go first, then a few special ones, then lowercase characters, and `Ö` near the end of the output. Now it becomes obvious why `a > Z`. @@ -523,22 +528,21 @@ The characters are compared by their numeric code. The greater code means that t - All lowercase letters go after uppercase letters because their codes are greater. - Some letters like `Ö` stand apart from the main alphabet. Here, it's code is greater than anything from `a` to `z`. - ### Correct comparisons -The "right" algorithm to do string comparisons is more complex than it may seem, because alphabets are different for different languages. The same-looking letter may be located differently in different alphabets. +The "right" algorithm to do string comparisons is more complex than it may seem, because alphabets are different for different languages. So, the browser needs to know the language to compare. -Luckily, all modern browsers (IE10- requires the additional library [Intl.JS](https://github.com/andyearnshaw/Intl.js/)) support the internationalization standard [ECMA 402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf). +Luckily, all modern browsers (IE10- requires the additional library [Intl.js](https://github.com/andyearnshaw/Intl.js/)) support the internationalization standard [ECMA-402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf). It provides a special method to compare strings in different languages, following their rules. -The call [str.localeCompare(str2)](mdn:js/String/localeCompare): +The call [str.localeCompare(str2)](mdn:js/String/localeCompare) returns an integer indicating whether `str` is less, equal or greater than `str2` according to the language rules: -- Returns `1` if `str` is greater than `str2` according to the language rules. -- Returns `-1` if `str` is less than `str2`. -- Returns `0` if they are equal. +- Returns a negative number if `str` is less than `str2`. +- Returns a positive number if `str` is greater than `str2`. +- Returns `0` if they are equivalent. For instance: @@ -546,7 +550,7 @@ For instance: alert( 'Österreich'.localeCompare('Zealand') ); // -1 ``` -This method actually has two additional arguments specified in [the documentation](mdn:js/String/localeCompare), which allows it to specify the language (by default taken from the environment) and setup additional rules like case sensitivity or should `"a"` and `"á"` be treated as the same etc. +This method actually has two additional arguments specified in [the documentation](mdn:js/String/localeCompare), which allows it to specify the language (by default taken from the environment, letter order depends on the language) and setup additional rules like case sensitivity or should `"a"` and `"á"` be treated as the same etc. ## Internals, Unicode @@ -558,7 +562,7 @@ You can skip the section if you don't plan to support them. ### Surrogate pairs -Most symbols have a 2-byte code. Letters in most european languages, numbers, and even most hieroglyphs, have a 2-byte representation. +All frequently used characters have 2-byte codes. Letters in most european languages, numbers, and even most hieroglyphs, have a 2-byte representation. But 2 bytes only allow 65536 combinations and that's not enough for every possible symbol. So rare symbols are encoded with a pair of 2-byte characters called "a surrogate pair". @@ -567,7 +571,7 @@ The length of such symbols is `2`: ```js run alert( '𝒳'.length ); // 2, MATHEMATICAL SCRIPT CAPITAL X alert( '😂'.length ); // 2, FACE WITH TEARS OF JOY -alert( '𩷶'.length ); // 2, a rare chinese hieroglyph +alert( '𩷶'.length ); // 2, a rare Chinese hieroglyph ``` Note that surrogate pairs did not exist at the time when JavaScript was created, and thus are not correctly processed by the language! @@ -576,7 +580,7 @@ We actually have a single symbol in each of the strings above, but the `length` `String.fromCodePoint` and `str.codePointAt` are few rare methods that deal with surrogate pairs right. They recently appeared in the language. Before them, there were only [String.fromCharCode](mdn:js/String/fromCharCode) and [str.charCodeAt](mdn:js/String/charCodeAt). These methods are actually the same as `fromCodePoint/codePointAt`, but don't work with surrogate pairs. -But, for instance, getting a symbol can be tricky, because surrogate pairs are treated as two characters: +Getting a symbol can be tricky, because surrogate pairs are treated as two characters: ```js run alert( '𝒳'[0] ); // strange symbols... @@ -604,7 +608,7 @@ In many languages there are symbols that are composed of the base character with For instance, the letter `a` can be the base character for: `àáâäãåā`. Most common "composite" character have their own code in the UTF-16 table. But not all of them, because there are too many possible combinations. -To support arbitrary compositions, UTF-16 allows us to use several unicode characters. The base character and one or many "mark" characters that "decorate" it. +To support arbitrary compositions, UTF-16 allows us to use several Unicode characters: the base character followed by one or many "mark" characters that "decorate" it. For instance, if we have `S` followed by the special "dot above" character (code `\u0307`), it is shown as Ṡ. @@ -622,18 +626,20 @@ For example: alert( 'S\u0307\u0323' ); // Ṩ ``` -This provides great flexibility, but also an interesting problem: two characters may visually look the same, but be represented with different unicode compositions. +This provides great flexibility, but also an interesting problem: two characters may visually look the same, but be represented with different Unicode compositions. For instance: ```js run -alert( 'S\u0307\u0323' ); // Ṩ, S + dot above + dot below -alert( 'S\u0323\u0307' ); // Ṩ, S + dot below + dot above +let s1 = 'S\u0307\u0323'; // Ṩ, S + dot above + dot below +let s2 = 'S\u0323\u0307'; // Ṩ, S + dot below + dot above -alert( 'S\u0307\u0323' == 'S\u0323\u0307' ); // false +alert( `s1: ${s1}, s2: ${s2}` ); + +alert( s1 == s2 ); // false though the characters look identical (?!) ``` -To solve this, there exists a "unicode normalization" algorithm that brings each string to the single "normal" form. +To solve this, there exists a "Unicode normalization" algorithm that brings each string to the single "normal" form. It is implemented by [str.normalize()](mdn:js/String/normalize). @@ -649,16 +655,15 @@ alert( "S\u0307\u0323".normalize().length ); // 1 alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true ``` -In reality, this is not always the case. The reason being that the symbol `Ṩ` is "common enough", so UTF-16 creators included it in the main table and gave it the code. +In reality, this is not always the case. The reason being that the symbol `Ṩ` is "common enough", so UTF-16 creators included it in the main table and gave it the code. If you want to learn more about normalization rules and variants -- they are described in the appendix of the Unicode standard: [Unicode Normalization Forms](http://www.unicode.org/reports/tr15/), but for most practical purposes the information from this section is enough. - ## Summary -- There are 3 types of quotes. Backticks allow a string to span multiple lines and embed expressions. +- There are 3 types of quotes. Backticks allow a string to span multiple lines and embed expressions `${…}`. - Strings in JavaScript are encoded using UTF-16. -- We can use special characters like `\n` and insert letters by their unicode using `\u...`. +- We can use special characters like `\n` and insert letters by their Unicode using `\u...`. - To get a character, use: `[]`. - To get a substring, use: `slice` or `substring`. - To lowercase/uppercase a string, use: `toLowerCase/toUpperCase`. @@ -669,6 +674,6 @@ There are several other helpful methods in strings: - `str.trim()` -- removes ("trims") spaces from the beginning and end of the string. - `str.repeat(n)` -- repeats the string `n` times. -- ...and more. See the [manual](mdn:js/String) for details. +- ...and more to be found in the [manual](mdn:js/String). -Strings also have methods for doing search/replace with regular expressions. But that topic deserves a separate chapter, so we'll return to that later. +Strings also have methods for doing search/replace with regular expressions. But that's big topic, so it's explained in a separate tutorial section . diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md index daadf494b..befd80296 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md @@ -57,7 +57,7 @@ alert( getMaxSubSum([1, 2, 3]) ); // 6 alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100 ``` -The solution has a time complexety of [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation). In other words, if we increase the array size 2 times, the algorithm will work 4 times longer. +The solution has a time complexity of [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation). In other words, if we increase the array size 2 times, the algorithm will work 4 times longer. For big arrays (1000, 10000 or more items) such algorithms can lead to a serious sluggishness. diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/task.md b/1-js/05-data-types/04-array/10-maximal-subarray/task.md index e63c4e625..f1a1d9f95 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/task.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/task.md @@ -10,15 +10,15 @@ The task is: find the contiguous subarray of `arr` with the maximal sum of items Write the function `getMaxSubSum(arr)` that will return that sum. -For instance: +For instance: ```js -getMaxSubSum([-1, *!*2, 3*/!*, -9]) = 5 (the sum of highlighted items) -getMaxSubSum([*!*2, -1, 2, 3*/!*, -9]) = 6 -getMaxSubSum([-1, 2, 3, -9, *!*11*/!*]) = 11 -getMaxSubSum([-2, -1, *!*1, 2*/!*]) = 3 -getMaxSubSum([*!*100*/!*, -9, 2, -3, 5]) = 100 -getMaxSubSum([*!*1, 2, 3*/!*]) = 6 (take all) +getMaxSubSum([-1, *!*2, 3*/!*, -9]) == 5 (the sum of highlighted items) +getMaxSubSum([*!*2, -1, 2, 3*/!*, -9]) == 6 +getMaxSubSum([-1, 2, 3, -9, *!*11*/!*]) == 11 +getMaxSubSum([-2, -1, *!*1, 2*/!*]) == 3 +getMaxSubSum([*!*100*/!*, -9, 2, -3, 5]) == 100 +getMaxSubSum([*!*1, 2, 3*/!*]) == 6 (take all) ``` If all items are negative, it means that we take none (the subarray is empty), so the sum is zero: diff --git a/1-js/05-data-types/04-array/3-call-array-this/solution.md b/1-js/05-data-types/04-array/3-call-array-this/solution.md index e994ae078..3cb0317cf 100644 --- a/1-js/05-data-types/04-array/3-call-array-this/solution.md +++ b/1-js/05-data-types/04-array/3-call-array-this/solution.md @@ -9,7 +9,7 @@ arr.push(function() { alert( this ); }) -arr[2](); // "a","b",function +arr[2](); // a,b,function(){...} ``` The array has 3 values: initially it had two, plus the function. diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index aead164f5..1fdc57a47 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -1,12 +1,12 @@ -# Arrays +# Arrays Objects allow you to store keyed collections of values. That's fine. -But quite often we find that we need an *ordered collection*, where we have a 1st, a 2nd, a 3rd element and so on. For example, we need that to store a list of something: users, goods, HTML elements etc. +But quite often we find that we need an *ordered collection*, where we have a 1st, a 2nd, a 3rd element and so on. For example, we need that to store a list of something: users, goods, HTML elements etc. It is not convenient to use an object here, because it provides no methods to manage the order of elements. We can’t insert a new property “between” the existing ones. Objects are just not meant for such use. -There exists a special data structure named `Array`, to store ordered collections. +There exists a special data structure named `Array`, to store ordered collections. ## Declaration @@ -81,10 +81,10 @@ arr[3](); // hello ````smart header="Trailing comma" An array, just like an object, may end with a comma: -```js +```js let fruits = [ - "Apple", - "Orange", + "Apple", + "Orange", "Plum"*!*,*/!* ]; ``` @@ -95,7 +95,7 @@ The "trailing comma" style makes it easier to insert/remove items, because all l ## Methods pop/push, shift/unshift -A [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) is one of most common uses of an array. In computer science, this means an ordered collection of elements which supports two operations: +A [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) is one of the most common uses of an array. In computer science, this means an ordered collection of elements which supports two operations: - `push` appends an element to the end. - `shift` get an element from the beginning, advancing the queue, so that the 2nd element becomes the 1st. @@ -106,7 +106,7 @@ Arrays support both operations. In practice we need it very often. For example, a queue of messages that need to be shown on-screen. -There's another use case for arrays -- the data structure named [stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)). +There's another use case for arrays -- the data structure named [stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)). It supports two operations: @@ -121,9 +121,9 @@ A stack is usually illustrated as a pack of cards: new cards are added to the to For stacks, the latest pushed item is received first, that's also called LIFO (Last-In-First-Out) principle. For queues, we have FIFO (First-In-First-Out). -Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements both to/from the beginning or the end. +Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements both to/from the beginning or the end. -In computer science the data structure that allows it is called [deque](https://en.wikipedia.org/wiki/Double-ended_queue). +In computer science the data structure that allows this, is called [deque](https://en.wikipedia.org/wiki/Double-ended_queue). **Methods that work with the end of the array:** @@ -156,7 +156,7 @@ In computer science the data structure that allows it is called [deque](https:// `shift` : Extracts the first element of the array and returns it: - ```js + ```js run let fruits = ["Apple", "Orange", "Pear"]; alert( fruits.shift() ); // remove Apple and alert it @@ -167,7 +167,7 @@ In computer science the data structure that allows it is called [deque](https:// `unshift` : Add the element to the beginning of the array: - ```js + ```js run let fruits = ["Orange", "Pear"]; fruits.unshift('Apple'); @@ -189,11 +189,11 @@ alert( fruits ); ## Internals -An array is a special kind of object. The square brackets used to access a property `arr[0]` actually come from the object syntax. Numbers are used as keys. +An array is a special kind of object. The square brackets used to access a property `arr[0]` actually come from the object syntax. That's essentially the same as `obj[key]`, where `arr` is the object, while numbers are used as keys. They extend objects providing special methods to work with ordered collections of data and also the `length` property. But at the core it's still an object. -Remember, there are only 7 basic types in JavaScript. Array is an object and thus behaves like an object. +Remember, there are only eight basic data types in JavaScript (see the [Data types](info:types) chapter for more info). Array is an object and thus behaves like an object. For instance, it is copied by reference: @@ -203,13 +203,13 @@ let fruits = ["Banana"] let arr = fruits; // copy by reference (two variables reference the same array) alert( arr === fruits ); // true - + arr.push("Pear"); // modify the array by reference alert( fruits ); // Banana, Pear - 2 items now ``` -...But what makes arrays really special is their internal representation. The engine tries to store its elements in the contiguous memory area, one after another, just as depicted on the illustrations in this chapter, and there are other optimizations as well, to make arrays work really fast. +...But what makes arrays really special is their internal representation. The engine tries to store its elements in the contiguous memory area, one after another, just as depicted on the illustrations in this chapter, and there are other optimizations as well, to make arrays work really fast. But they all break if we quit working with an array as with an "ordered collection" and start working with it as if it were a regular object. @@ -229,7 +229,7 @@ But the engine will see that we're working with the array as with a regular obje The ways to misuse an array: -- Add a non-numeric property like `arr.test = 5`. +- Add a non-numeric property like `arr.test = 5`. - Make holes, like: add `arr[0]` and then `arr[1000]` (and nothing between them). - Fill the array in the reverse order, like `arr[1000]`, `arr[999]` and so on. @@ -296,7 +296,7 @@ let fruits = ["Apple", "Orange", "Plum"]; // iterates over array elements for (let fruit of fruits) { - alert( fruit ); + alert( fruit ); } ``` @@ -320,7 +320,7 @@ But that's actually a bad idea. There are potential problems with it: There are so-called "array-like" objects in the browser and in other environments, that *look like arrays*. That is, they have `length` and indexes properties, but they may also have other non-numeric properties and methods, which we usually don't need. The `for..in` loop will list them though. So if we need to work with array-like objects, then these "extra" properties can become a problem. -2. The `for..in` loop is optimized for generic objects, not arrays, and thus is 10-100 times slower. Of course, it's still very fast. The speedup may only matter in bottlenecks or seem irrelevant. But still we should be aware of the difference. +2. The `for..in` loop is optimized for generic objects, not arrays, and thus is 10-100 times slower. Of course, it's still very fast. The speedup may only matter in bottlenecks. But still we should be aware of the difference. Generally, we shouldn't use `for..in` for arrays. @@ -338,7 +338,7 @@ fruits[123] = "Apple"; alert( fruits.length ); // 124 ``` -Note that we usually don't use arrays like that. +Note that we usually don't use arrays like that. Another interesting thing about the `length` property is that it's writable. @@ -385,7 +385,7 @@ To evade such surprises, we usually use square brackets, unless we really know w ## Multidimensional arrays -Arrays can have items that are also arrays. We can use it for multidimensional arrays, to store matrices: +Arrays can have items that are also arrays. We can use it for multidimensional arrays, for example to store matrices: ```js run let matrix = [ @@ -394,7 +394,7 @@ let matrix = [ [7, 8, 9] ]; -alert( matrix[1][1] ); // the central element +alert( matrix[1][1] ); // 5, the central element ``` ## toString @@ -429,6 +429,53 @@ alert( "1" + 1 ); // "11" alert( "1,2" + 1 ); // "1,21" ``` +## Don't compare arrays with == + +Arrays in JavaScript, unlike some other programming languages, shouldn't be compared with operator `==`. + +This operator has no special treatment for arrays, it works with them as with any objects. + +Let's recall the rules: + +- Two objects are equal `==` only if they're references to the same object. +- If one of arguments of `==` is an object, and the other one is a primitive, then the object gets converted to primitive, as explained in the chapter . +- ...With an exception of `null` and `undefined` that equal `==` each other and nothing else. + +The strict comparison `===` is even simpler, as it doesn't convert types. + +So, if we compare arrays with `==`, they are never the same, unless we compare two variables that reference exactly the same array. + +For example: +```js run +alert( [] == [] ); // false +alert( [0] == [0] ); // false +``` + +These arrays are technically different objects. So they aren't equal. The `==` operator doesn't do item-by-item comparison. + +Comparison with primitives may give seemingly strange results as well: + +```js run +alert( 0 == [] ); // true + +alert('0' == [] ); // false +``` + +Here, in both cases, we compare a primitive with an array object. So the array `[]` gets converted to primitive for the purpose of comparison and becomes an empty string `''`. + +Then the comparison process goes on with the primitives, as described in the chapter : + +```js run +// after [] was converted to '' +alert( 0 == '' ); // true, as '' becomes converted to number 0 + +alert('0' == '' ); // false, no type conversion, different strings +``` + +So, how to compare arrays? + +That's simple: don't use the `==` operator. Instead, compare them item-by-item in a loop or using iteration methods explained in the next chapter. + ## Summary Array is a special kind of object, suited to storing and managing ordered data items. @@ -445,7 +492,7 @@ Array is a special kind of object, suited to storing and managing ordered data i The call to `new Array(number)` creates an array with the given length, but without elements. -- The `length` property is the array length or, to be precise, its last numeric index plus one. It is auto-adjusted by array methods. +- The `length` property is the array length or, to be precise, its last numeric index plus one. It is auto-adjusted by array methods. - If we shorten `length` manually, the array is truncated. We can use an array as a deque with the following operations: @@ -453,12 +500,15 @@ We can use an array as a deque with the following operations: - `push(...items)` adds `items` to the end. - `pop()` removes the element from the end and returns it. - `shift()` removes the element from the beginning and returns it. -- `unshift(...items)` adds items to the beginning. +- `unshift(...items)` adds `items` to the beginning. To loop over the elements of the array: - `for (let i=0; i. +To compare arrays, don't use the `==` operator (as well as `>`, `<` and others), as they have no special treatment for arrays. They handle them as any objects, and it's not what we usually want. + +Instead you can use `for..of` loop to compare arrays item-by-item. +We will continue with arrays and study more methods to add, remove, extract elements and sort arrays in the next chapter . diff --git a/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/solution.js b/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/solution.js new file mode 100644 index 000000000..8dea23a06 --- /dev/null +++ b/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/solution.js @@ -0,0 +1,6 @@ +function groupById(array) { + return array.reduce((obj, value) => { + obj[value.id] = value; + return obj; + }, {}) +} diff --git a/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/test.js b/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/test.js new file mode 100644 index 000000000..e48ba138d --- /dev/null +++ b/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/test.js @@ -0,0 +1,21 @@ +describe("groupById", function() { + + it("creates an object grouped by id", function() { + let users = [ + {id: 'john', name: "John Smith", age: 20}, + {id: 'ann', name: "Ann Smith", age: 24}, + {id: 'pete', name: "Pete Peterson", age: 31}, + ]; + + assert.deepEqual(groupById(users), { + john: {id: 'john', name: "John Smith", age: 20}, + ann: {id: 'ann', name: "Ann Smith", age: 24}, + pete: {id: 'pete', name: "Pete Peterson", age: 31}, + }); + }); + + it("works with an empty array", function() { + users = []; + assert.deepEqual(groupById(users), {}); + }); +}); diff --git a/1-js/11-async/01-callbacks/01-animate-circle-callback/solution.md b/1-js/05-data-types/05-array-methods/12-reduce-object/solution.md similarity index 100% rename from 1-js/11-async/01-callbacks/01-animate-circle-callback/solution.md rename to 1-js/05-data-types/05-array-methods/12-reduce-object/solution.md diff --git a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md new file mode 100644 index 000000000..d3c8f8eb1 --- /dev/null +++ b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md @@ -0,0 +1,37 @@ +importance: 4 + +--- + +# Create keyed object from array + +Let's say we received an array of users in the form `{id:..., name:..., age... }`. + +Create a function `groupById(arr)` that creates an object from it, with `id` as the key, and array items as values. + +For example: + +```js +let users = [ + {id: 'john', name: "John Smith", age: 20}, + {id: 'ann', name: "Ann Smith", age: 24}, + {id: 'pete', name: "Pete Peterson", age: 31}, +]; + +let usersById = groupById(users); + +/* +// after the call we should have: + +usersById = { + john: {id: 'john', name: "John Smith", age: 20}, + ann: {id: 'ann', name: "Ann Smith", age: 24}, + pete: {id: 'pete', name: "Pete Peterson", age: 31}, +} +*/ +``` + +Such function is really handy when working with server data. + +In this task we assume that `id` is unique. There may be no two array items with the same `id`. + +Please use array `.reduce` method in the solution. diff --git a/1-js/05-data-types/05-array-methods/2-filter-range/task.md b/1-js/05-data-types/05-array-methods/2-filter-range/task.md index 18b2c1d9b..46e47c93d 100644 --- a/1-js/05-data-types/05-array-methods/2-filter-range/task.md +++ b/1-js/05-data-types/05-array-methods/2-filter-range/task.md @@ -4,7 +4,7 @@ importance: 4 # Filter range -Write a function `filterRange(arr, a, b)` that gets an array `arr`, looks for elements between `a` and `b` in it and returns an array of them. +Write a function `filterRange(arr, a, b)` that gets an array `arr`, looks for elements with values higher or equal to `a` and lower or equal to `b` and return a result as an array. The function should not modify the array. It should return the new array. diff --git a/1-js/05-data-types/05-array-methods/4-sort-back/task.md b/1-js/05-data-types/05-array-methods/4-sort-back/task.md index 05a08aad0..0e3eeab76 100644 --- a/1-js/05-data-types/05-array-methods/4-sort-back/task.md +++ b/1-js/05-data-types/05-array-methods/4-sort-back/task.md @@ -2,12 +2,12 @@ importance: 4 --- -# Sort in the reverse order +# Sort in decreasing order ```js let arr = [5, 2, 1, -10, 8]; -// ... your code to sort it in the reverse order +// ... your code to sort it in decreasing order alert( arr ); // 8, 5, 2, 1, -10 ``` diff --git a/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js b/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js index 50c40e804..f62452a5f 100644 --- a/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js +++ b/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js @@ -1,6 +1,6 @@ function Calculator() { - let methods = { + this.methods = { "-": (a, b) => a - b, "+": (a, b) => a + b }; @@ -10,16 +10,16 @@ function Calculator() { let split = str.split(' '), a = +split[0], op = split[1], - b = +split[2] + b = +split[2]; - if (!methods[op] || isNaN(a) || isNaN(b)) { + if (!this.methods[op] || isNaN(a) || isNaN(b)) { return NaN; } - return methods[op](a, b); - } + return this.methods[op](a, b); + }; this.addMethod = function(name, func) { - methods[name] = func; + this.methods[name] = func; }; } diff --git a/1-js/05-data-types/05-array-methods/6-calculator-extendable/solution.md b/1-js/05-data-types/05-array-methods/6-calculator-extendable/solution.md index 41178663d..ebe0714cf 100644 --- a/1-js/05-data-types/05-array-methods/6-calculator-extendable/solution.md +++ b/1-js/05-data-types/05-array-methods/6-calculator-extendable/solution.md @@ -1,3 +1,3 @@ -- Please note how methods are stored. They are simply added to the internal object. +- Please note how methods are stored. They are simply added to `this.methods` property. - All tests and numeric conversions are done in the `calculate` method. In future it may be extended to support more complex expressions. diff --git a/1-js/05-data-types/05-array-methods/6-calculator-extendable/task.md b/1-js/05-data-types/05-array-methods/6-calculator-extendable/task.md index cc5453ceb..e0d302f4c 100644 --- a/1-js/05-data-types/05-array-methods/6-calculator-extendable/task.md +++ b/1-js/05-data-types/05-array-methods/6-calculator-extendable/task.md @@ -31,6 +31,6 @@ The task consists of two parts. alert( result ); // 8 ``` -- No brackets or complex expressions in this task. +- No parentheses or complex expressions in this task. - The numbers and the operator are delimited with exactly one space. - There may be error handling if you'd like to add it. diff --git a/1-js/05-data-types/05-array-methods/7-map-objects/solution.md b/1-js/05-data-types/05-array-methods/7-map-objects/solution.md index 5d8bf4a13..2d8d4fb0e 100644 --- a/1-js/05-data-types/05-array-methods/7-map-objects/solution.md +++ b/1-js/05-data-types/05-array-methods/7-map-objects/solution.md @@ -25,7 +25,7 @@ alert( usersMapped[0].id ); // 1 alert( usersMapped[0].fullName ); // John Smith ``` -Please note that in for the arrow functions we need to use additional brackets. +Please note that in the arrow functions we need to use additional brackets. We can't write like this: ```js diff --git a/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md b/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md index 9f1ade707..cfaf9761a 100644 --- a/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md +++ b/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md @@ -1,6 +1,6 @@ ```js run no-beautify function sortByAge(arr) { - arr.sort((a, b) => a.age > b.age ? 1 : -1); + arr.sort((a, b) => a.age - b.age); } let john = { name: "John", age: 25 }; diff --git a/1-js/05-data-types/05-array-methods/article.md b/1-js/05-data-types/05-array-methods/article.md index a661b73b9..b14e9a0be 100644 --- a/1-js/05-data-types/05-array-methods/article.md +++ b/1-js/05-data-types/05-array-methods/article.md @@ -11,7 +11,7 @@ We already know methods that add and remove items from the beginning or the end: - `arr.shift()` -- extracts an item from the beginning, - `arr.unshift(...items)` -- adds items to the beginning. -Here are few others. +Here are a few others. ### splice @@ -36,15 +36,15 @@ That's natural, because `delete obj.key` removes a value by the `key`. It's all So, special methods should be used. -The [arr.splice(str)](mdn:js/Array/splice) method is a swiss army knife for arrays. It can do everything: add, remove and insert elements. +The [arr.splice](mdn:js/Array/splice) method is a swiss army knife for arrays. It can do everything: insert, remove and replace elements. The syntax is: ```js -arr.splice(index[, deleteCount, elem1, ..., elemN]) +arr.splice(start[, deleteCount, elem1, ..., elemN]) ``` -It starts from the position `index`: removes `deleteCount` elements and then inserts `elem1, ..., elemN` at their place. Returns the array of removed elements. +It modifies `arr` starting from the index `start`: removes `deleteCount` elements and then inserts `elem1, ..., elemN` at their place. Returns the array of removed elements. This method is easy to grasp by examples. @@ -119,29 +119,28 @@ The method [arr.slice](mdn:js/Array/slice) is much simpler than similar-looking The syntax is: ```js -arr.slice(start, end) +arr.slice([start], [end]) ``` -It returns a new array containing all items from index `"start"` to `"end"` (not including `"end"`). Both `start` and `end` can be negative, in that case position from array end is assumed. +It returns a new array copying to it all items from index `start` to `end` (not including `end`). Both `start` and `end` can be negative, in that case position from array end is assumed. -It works like `str.slice`, but makes subarrays instead of substrings. +It's similar to a string method `str.slice`, but instead of substrings it makes subarrays. For instance: ```js run -let str = "test"; let arr = ["t", "e", "s", "t"]; -alert( str.slice(1, 3) ); // es -alert( arr.slice(1, 3) ); // e,s +alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3) -alert( str.slice(-2) ); // st -alert( arr.slice(-2) ); // s,t +alert( arr.slice(-2) ); // s,t (copy from -2 till the end) ``` +We can also call it without arguments: `arr.slice()` creates a copy of `arr`. That's often used to obtain a copy for further transformations that should not affect the original array. + ### concat -The method [arr.concat](mdn:js/Array/concat) joins the array with other arrays and/or items. +The method [arr.concat](mdn:js/Array/concat) creates a new array that includes values from other arrays and additional items. The syntax is: @@ -153,24 +152,24 @@ It accepts any number of arguments -- either arrays or values. The result is a new array containing items from `arr`, then `arg1`, `arg2` etc. -If an argument is an array or has `Symbol.isConcatSpreadable` property, then all its elements are copied. Otherwise, the argument itself is copied. +If an argument `argN` is an array, then all its elements are copied. Otherwise, the argument itself is copied. For instance: ```js run let arr = [1, 2]; -// merge arr with [3,4] -alert( arr.concat([3, 4])); // 1,2,3,4 +// create an array from: arr and [3,4] +alert( arr.concat([3, 4]) ); // 1,2,3,4 -// merge arr with [3,4] and [5,6] -alert( arr.concat([3, 4], [5, 6])); // 1,2,3,4,5,6 +// create an array from: arr and [3,4] and [5,6] +alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6 -// merge arr with [3,4], then add values 5 and 6 -alert( arr.concat([3, 4], 5, 6)); // 1,2,3,4,5,6 +// create an array from: arr and [3,4], then add values 5 and 6 +alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6 ``` -Normally, it only copies elements from arrays ("spreads" them). Other objects, even if they look like arrays, added as a whole: +Normally, it only copies elements from arrays. Other objects, even if they look like arrays, are added as a whole: ```js run let arr = [1, 2]; @@ -181,10 +180,9 @@ let arrayLike = { }; alert( arr.concat(arrayLike) ); // 1,2,[object Object] -//[1, 2, arrayLike] ``` -...But if an array-like object has `Symbol.isConcatSpreadable` property, then its elements are added instead: +...But if an array-like object has a special `Symbol.isConcatSpreadable` property, then it's treated as an array by `concat`: its elements are added instead: ```js run let arr = [1, 2]; @@ -232,14 +230,14 @@ The result of the function (if it returns any) is thrown away and ignored. ## Searching in array -These are methods to search for something in an array. +Now let's cover methods that search in an array. ### indexOf/lastIndexOf and includes The methods [arr.indexOf](mdn:js/Array/indexOf), [arr.lastIndexOf](mdn:js/Array/lastIndexOf) and [arr.includes](mdn:js/Array/includes) have the same syntax and do essentially the same as their string counterparts, but operate on items instead of characters: -- `arr.indexOf(item, from)` looks for `item` starting from index `from`, and returns the index where it was found, otherwise `-1`. -- `arr.lastIndexOf(item, from)` -- same, but looks from right to left. +- `arr.indexOf(item, from)` -- looks for `item` starting from index `from`, and returns the index where it was found, otherwise `-1`. +- `arr.lastIndexOf(item, from)` -- same, but looks for from right to left. - `arr.includes(item, from)` -- looks for `item` starting from index `from`, returns `true` if found. For instance: @@ -270,7 +268,7 @@ alert( arr.includes(NaN) );// true (correct) Imagine we have an array of objects. How do we find an object with the specific condition? -Here the [arr.find](mdn:js/Array/find) method comes in handy. +Here the [arr.find(fn)](mdn:js/Array/find) method comes in handy. The syntax is: ```js @@ -280,7 +278,7 @@ let result = arr.find(function(item, index, array) { }); ``` -The function is called repetitively for each element of the array: +The function is called for elements of the array, one after another: - `item` is the element. - `index` is its index. @@ -304,7 +302,7 @@ alert(user.name); // John In real life arrays of objects is a common thing, so the `find` method is very useful. -Note that in the example we provide to `find` the function `item => item.id == 1` with one argument. Other arguments of this function are rarely used. +Note that in the example we provide to `find` the function `item => item.id == 1` with one argument. That's typical, other arguments of this function are rarely used. The [arr.findIndex](mdn:js/Array/findIndex) method is essentially the same, but it returns the index where the element was found instead of the element itself and `-1` is returned when nothing is found. @@ -314,12 +312,12 @@ The `find` method looks for a single (first) element that makes the function ret If there may be many, we can use [arr.filter(fn)](mdn:js/Array/filter). -The syntax is similar to `find`, but filter continues to iterate for all array elements even if `true` is already returned: +The syntax is similar to `find`, but `filter` returns an array of all matching elements: ```js let results = arr.filter(function(item, index, array) { - // if true item is pushed to results and iteration continues - // returns empty array for complete falsy scenario + // if true item is pushed to results and the iteration continues + // returns empty array if nothing found }); ``` @@ -340,23 +338,22 @@ alert(someUsers.length); // 2 ## Transform an array -This section is about the methods transforming or reordering the array. - +Let's move on to methods that transform and reorder an array. ### map The [arr.map](mdn:js/Array/map) method is one of the most useful and often used. +It calls the function for each element of the array and returns the array of results. + The syntax is: ```js let result = arr.map(function(item, index, array) { // returns the new value instead of item -}) +}); ``` -It calls the function for each element of the array and returns the array of results. - For instance, here we transform each element into its length: ```js run @@ -366,14 +363,16 @@ alert(lengths); // 5,7,6 ### sort(fn) -The method [arr.sort](mdn:js/Array/sort) sorts the array *in place*. +The call to [arr.sort()](mdn:js/Array/sort) sorts the array *in place*, changing its element order. + +It also returns the sorted array, but the returned value is usually ignored, as `arr` itself is modified. For instance: ```js run let arr = [ 1, 2, 15 ]; -// the method reorders the content of arr (and returns it) +// the method reorders the content of arr arr.sort(); alert( arr ); // *!*1, 15, 2*/!* @@ -385,20 +384,20 @@ The order became `1, 15, 2`. Incorrect. But why? **The items are sorted as strings by default.** -Literally, all elements are converted to strings and then compared. So, the lexicographic ordering is applied and indeed `"2" > "15"`. +Literally, all elements are converted to strings for comparisons. For strings, lexicographic ordering is applied and indeed `"2" > "15"`. -To use our own sorting order, we need to supply a function of two arguments as the argument of `arr.sort()`. +To use our own sorting order, we need to supply a function as the argument of `arr.sort()`. -The function should work like this: +The function should compare two arbitrary values and return: ```js function compare(a, b) { - if (a > b) return 1; - if (a == b) return 0; - if (a < b) return -1; + if (a > b) return 1; // if the first value is greater than the second + if (a == b) return 0; // if values are equal + if (a < b) return -1; // if the first value is less than the second } ``` -For instance: +For instance, to sort as numbers: ```js run function compareNumeric(a, b) { @@ -418,20 +417,20 @@ alert(arr); // *!*1, 2, 15*/!* Now it works as intended. -Let's step aside and think what's happening. The `arr` can be array of anything, right? It may contain numbers or strings or html elements or whatever. We have a set of *something*. To sort it, we need an *ordering function* that knows how to compare its elements. The default is a string order. +Let's step aside and think what's happening. The `arr` can be array of anything, right? It may contain numbers or strings or objects or whatever. We have a set of *some items*. To sort it, we need an *ordering function* that knows how to compare its elements. The default is a string order. -The `arr.sort(fn)` method has a built-in implementation of sorting algorithm. We don't need to care how it exactly works (an optimized [quicksort](https://en.wikipedia.org/wiki/Quicksort) most of the time). It will walk the array, compare its elements using the provided function and reorder them, all we need is to provide the `fn` which does the comparison. +The `arr.sort(fn)` method implements a generic sorting algorithm. We don't need to care how it internally works (an optimized [quicksort](https://en.wikipedia.org/wiki/Quicksort) or [Timsort](https://en.wikipedia.org/wiki/Timsort) most of the time). It will walk the array, compare its elements using the provided function and reorder them, all we need is to provide the `fn` which does the comparison. By the way, if we ever want to know which elements are compared -- nothing prevents from alerting them: ```js run [1, -2, 15, 2, 0, 8].sort(function(a, b) { alert( a + " <> " + b ); + return a - b; }); ``` -The algorithm may compare an element multiple times in the process, but it tries to make as few comparisons as possible. - +The algorithm may compare an element with multiple others in the process, but it tries to make as few comparisons as possible. ````smart header="A comparison function may return any number" Actually, a comparison function is only required to return a positive number to say "greater" and a negative number to say "less". @@ -448,13 +447,29 @@ alert(arr); // *!*1, 2, 15*/!* ```` ````smart header="Arrow functions for the best" -Remember [arrow functions](info:function-expressions-arrows#arrow-functions)? We can use them here for neater sorting: +Remember [arrow functions](info:arrow-functions-basics)? We can use them here for neater sorting: ```js arr.sort( (a, b) => a - b ); ``` -This works exactly the same as the other, longer, version above. +This works exactly the same as the longer version above. +```` + +````smart header="Use `localeCompare` for strings" +Remember [strings](info:string#correct-comparisons) comparison algorithm? It compares letters by their codes by default. + +For many alphabets, it's better to use `str.localeCompare` method to correctly sort letters, such as `Ö`. + +For example, let's sort a few countries in German: + +```js run +let countries = ['Österreich', 'Andorra', 'Vietnam']; + +alert( countries.sort( (a, b) => a > b ? 1 : -1) ); // Andorra, Vietnam, Österreich (wrong) + +alert( countries.sort( (a, b) => a.localeCompare(b) ) ); // Andorra,Österreich,Vietnam (correct!) +``` ```` ### reverse @@ -474,7 +489,7 @@ It also returns the array `arr` after the reversal. ### split and join -Here's the situation from the real life. We are writing a messaging app, and the person enters the comma-delimited list of receivers: `John, Pete, Mary`. But for us an array of names would be much more comfortable than a single string. How to get it? +Here's the situation from real life. We are writing a messaging app, and the person enters the comma-delimited list of receivers: `John, Pete, Mary`. But for us an array of names would be much more comfortable than a single string. How to get it? The [str.split(delim)](mdn:js/String/split) method does exactly that. It splits the string into an array by the given delimiter `delim`. @@ -508,14 +523,14 @@ alert( str.split('') ); // t,e,s,t ``` ```` -The call [arr.join(separator)](mdn:js/Array/join) does the reverse to `split`. It creates a string of `arr` items glued by `separator` between them. +The call [arr.join(glue)](mdn:js/Array/join) does the reverse to `split`. It creates a string of `arr` items joined by `glue` between them. For instance: ```js run let arr = ['Bilbo', 'Gandalf', 'Nazgul']; -let str = arr.join(';'); +let str = arr.join(';'); // glue the array into a string using ; alert( str ); // Bilbo;Gandalf;Nazgul ``` @@ -531,24 +546,29 @@ The methods [arr.reduce](mdn:js/Array/reduce) and [arr.reduceRight](mdn:js/Array The syntax is: ```js -let value = arr.reduce(function(previousValue, item, index, array) { +let value = arr.reduce(function(accumulator, item, index, array) { // ... -}, initial); +}, [initial]); ``` -The function is applied to the elements. You may notice the familiar arguments, starting from the 2nd: +The function is applied to all array elements one after another and "carries on" its result to the next call. + +Arguments: +- `accumulator` -- is the result of the previous function call, equals `initial` the first time (if `initial` is provided). - `item` -- is the current array item. - `index` -- is its position. - `array` -- is the array. -So far, like `forEach/map`. But there's one more argument: +As function is applied, the result of the previous function call is passed to the next one as the first argument. -- `previousValue` -- is the result of the previous function call, `initial` for the first call. +So, the first argument is essentially the accumulator that stores the combined result of all previous executions. And at the end it becomes the result of `reduce`. + +Sounds complicated? The easiest way to grasp that is by example. -Here we get a sum of array in one line: +Here we get a sum of an array in one line: ```js run let arr = [1, 2, 3, 4, 5]; @@ -558,11 +578,11 @@ let result = arr.reduce((sum, current) => sum + current, 0); alert(result); // 15 ``` -Here we used the most common variant of `reduce` which uses only 2 arguments. +The function passed to `reduce` uses only 2 arguments, that's typically enough. Let's see the details of what's going on. -1. On the first run, `sum` is the initial value (the last argument of `reduce`), equals `0`, and `current` is the first array element, equals `1`. So the result is `1`. +1. On the first run, `sum` is the `initial` value (the last argument of `reduce`), equals `0`, and `current` is the first array element, equals `1`. So the function result is `1`. 2. On the second run, `sum = 1`, we add the second array element (`2`) to it and return. 3. On the 3rd run, `sum = 3` and we add one more element to it, and so on... @@ -572,7 +592,7 @@ The calculation flow: Or in the form of a table, where each row represents a function call on the next array element: -| |`sum`|`current`|`result`| +| |`sum`|`current`|result| |---|-----|---------|---------| |the first call|`0`|`1`|`1`| |the second call|`1`|`2`|`3`| @@ -580,8 +600,7 @@ Or in the form of a table, where each row represents a function call on the next |the fourth call|`6`|`4`|`10`| |the fifth call|`10`|`5`|`15`| - -As we can see, the result of the previous call becomes the first argument of the next one. +Here we can clearly see how the result of the previous call becomes the first argument of the next one. We also can omit the initial value: @@ -610,7 +629,6 @@ let arr = []; arr.reduce((sum, current) => sum + current); ``` - So it's advised to always specify the initial value. The method [arr.reduceRight](mdn:js/Array/reduceRight) does the same, but goes from right to left. @@ -653,43 +671,49 @@ arr.map(func, thisArg); The value of `thisArg` parameter becomes `this` for `func`. -For instance, here we use an object method as a filter and `thisArg` comes in handy: +For example, here we use a method of `army` object as a filter, and `thisArg` passes the context: ```js run -let user = { - age: 18, - younger(otherUser) { - return otherUser.age < this.age; +let army = { + minAge: 18, + maxAge: 27, + canJoin(user) { + return user.age >= this.minAge && user.age < this.maxAge; } }; let users = [ - {age: 12}, {age: 16}, - {age: 32} + {age: 20}, + {age: 23}, + {age: 30} ]; *!* -// find all users younger than user -let youngerUsers = users.filter(user.younger, user); +// find users, for who army.canJoin returns true +let soldiers = users.filter(army.canJoin, army); */!* -alert(youngerUsers.length); // 2 +alert(soldiers.length); // 2 +alert(soldiers[0].age); // 20 +alert(soldiers[1].age); // 23 ``` -In the call above, we use `user.younger` as a filter and also provide `user` as the context for it. If we didn't provide the context, `users.filter(user.younger)` would call `user.younger` as a standalone function, with `this=undefined`. That would mean an instant error. +If in the example above we used `users.filter(army.canJoin)`, then `army.canJoin` would be called as a standalone function, with `this=undefined`, thus leading to an instant error. + +A call to `users.filter(army.canJoin, army)` can be replaced with `users.filter(user => army.canJoin(user))`, that does the same. The latter is used more often, as it's a bit easier to understand for most people. ## Summary -A cheatsheet of array methods: +A cheat sheet of array methods: - To add/remove elements: - `push(...items)` -- adds items to the end, - `pop()` -- extracts an item from the end, - `shift()` -- extracts an item from the beginning, - `unshift(...items)` -- adds items to the beginning. - - `splice(pos, deleteCount, ...items)` -- at index `pos` delete `deleteCount` elements and insert `items`. - - `slice(start, end)` -- creates a new array, copies elements from position `start` till `end` (not inclusive) into it. + - `splice(pos, deleteCount, ...items)` -- at index `pos` deletes `deleteCount` elements and inserts `items`. + - `slice(start, end)` -- creates a new array, copies elements from index `start` till `end` (not inclusive) into it. - `concat(...items)` -- returns a new array: copies all members of the current one and adds `items` to it. If any of `items` is an array, then its elements are taken. - To search among elements: @@ -697,7 +721,7 @@ A cheatsheet of array methods: - `includes(value)` -- returns `true` if the array has `value`, otherwise `false`. - `find/filter(func)` -- filter elements through the function, return first/all values that make it return `true`. - `findIndex` is like `find`, but returns the index instead of a value. - + - To iterate over elements: - `forEach(func)` -- calls `func` for every element, does not return anything. @@ -706,7 +730,7 @@ A cheatsheet of array methods: - `sort(func)` -- sorts the array in-place, then returns it. - `reverse()` -- reverses the array in-place, then returns it. - `split/join` -- convert a string to array and back. - - `reduce(func, initial)` -- calculate a single value over the array by calling `func` for each element and passing an intermediate result between the calls. + - `reduce/reduceRight(func, initial)` -- calculate a single value over the array by calling `func` for each element and passing an intermediate result between the calls. - Additionally: - `Array.isArray(arr)` checks `arr` for being an array. @@ -715,18 +739,31 @@ Please note that methods `sort`, `reverse` and `splice` modify the array itself. These methods are the most used ones, they cover 99% of use cases. But there are few others: -- [arr.some(fn)](mdn:js/Array/some)/[arr.every(fn)](mdn:js/Array/every) checks the array. +- [arr.some(fn)](mdn:js/Array/some)/[arr.every(fn)](mdn:js/Array/every) check the array. The function `fn` is called on each element of the array similar to `map`. If any/all results are `true`, returns `true`, otherwise `false`. + These methods behave sort of like `||` and `&&` operators: if `fn` returns a truthy value, `arr.some()` immediately returns `true` and stops iterating over the rest of items; if `fn` returns a falsy value, `arr.every()` immediately returns `false` and stops iterating over the rest of items as well. + + We can use `every` to compare arrays: + ```js run + function arraysEqual(arr1, arr2) { + return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]); + } + + alert( arraysEqual([1, 2], [1, 2])); // true + ``` + - [arr.fill(value, start, end)](mdn:js/Array/fill) -- fills the array with repeating `value` from index `start` to `end`. - [arr.copyWithin(target, start, end)](mdn:js/Array/copyWithin) -- copies its elements from position `start` till position `end` into *itself*, at position `target` (overwrites existing). +- [arr.flat(depth)](mdn:js/Array/flat)/[arr.flatMap(fn)](mdn:js/Array/flatMap) create a new flat array from a multidimensional array. + For the full list, see the [manual](mdn:js/Array). -From the first sight it may seem that there are so many methods, quite difficult to remember. But actually that's much easier than it seems. +From the first sight it may seem that there are so many methods, quite difficult to remember. But actually that's much easier. -Look through the cheatsheet just to be aware of them. Then solve the tasks of this chapter to practice, so that you have experience with array methods. +Look through the cheat sheet just to be aware of them. Then solve the tasks of this chapter to practice, so that you have experience with array methods. -Afterwards whenever you need to do something with an array, and you don't know how -- come here, look at the cheatsheet and find the right method. Examples will help you to write it correctly. Soon you'll automatically remember the methods, without specific efforts from your side. +Afterwards whenever you need to do something with an array, and you don't know how -- come here, look at the cheat sheet and find the right method. Examples will help you to write it correctly. Soon you'll automatically remember the methods, without specific efforts from your side. diff --git a/1-js/05-data-types/05-array-methods/reduce.svg b/1-js/05-data-types/05-array-methods/reduce.svg index f77f156cc..fcac711cb 100644 --- a/1-js/05-data-types/05-array-methods/reduce.svg +++ b/1-js/05-data-types/05-array-methods/reduce.svg @@ -1,64 +1 @@ - - - - reduce.svg - Created with sketchtool. - - - - - 1 - - - sum - 0 - current - 1 - - - - 2 - - - sum - 0+1 - current - 2 - - - - 3 - - - sum - 0+1+2 - current - 3 - - - - 4 - - - sum - 0+1+2+3 - current - 4 - - - - 5 - - - sum - 0+1+2+3+4 - current - 5 - - - - 0+1+2+3+4+5 = 15 - - - - \ No newline at end of file +1sum 0 current 12sum 0+1 current 23sum 0+1+2 current 34sum 0+1+2+3 current 45sum 0+1+2+3+4 current 50+1+2+3+4+5 = 15 \ No newline at end of file diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 7f72f5caf..782bf14b0 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -1,7 +1,7 @@ # Iterables -*Iterable* objects is a generalization of arrays. That's a concept that allows to make any object useable in a `for..of` loop. +*Iterable* objects are a generalization of arrays. That's a concept that allows us to make any object useable in a `for..of` loop. Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, Strings are iterable also. As we'll see, many built-in operators and methods rely on them. @@ -12,7 +12,7 @@ If an object represents a collection (list, set) of something, then `for..of` is We can easily grasp the concept of iterables by making one of our own. -For instance, we have an object, that is not an array, but looks suitable for `for..of`. +For instance, we have an object that is not an array, but looks suitable for `for..of`. Like a `range` object that represents an interval of numbers: @@ -26,7 +26,7 @@ let range = { // for(let num of range) ... num=1,2,3,4,5 ``` -To make the `range` iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that). +To make the `range` object iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that). 1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`. 2. Onward, `for..of` works *only with that returned object*. @@ -140,11 +140,9 @@ for (let char of str) { ## Calling an iterator explicitly -Normally, internals of iterables are hidden from the external code. There's a `for..of` loop, that works, that's all it needs to know. +For deeper understanding, let's see how to use an iterator explicitly. -But to understand things a little bit deeper let's see how to create an iterator explicitly. - -We'll iterate over a string the same way as `for..of`, but with direct calls. This code gets a string iterator and calls it "manually": +We'll iterate over a string in exactly the same way as `for..of`, but with direct calls. This code creates a string iterator and gets values from it "manually": ```js run let str = "Hello"; @@ -152,7 +150,9 @@ let str = "Hello"; // does the same as // for (let char of str) alert(char); +*!* let iterator = str[Symbol.iterator](); +*/!* while (true) { let result = iterator.next(); @@ -165,14 +165,16 @@ That is rarely needed, but gives us more control over the process than `for..of` ## Iterables and array-likes [#array-like] -There are two official terms that look similar, but are very different. Please make sure you understand them well to avoid the confusion. +Two official terms look similar, but are very different. Please make sure you understand them well to avoid the confusion. - *Iterables* are objects that implement the `Symbol.iterator` method, as described above. - *Array-likes* are objects that have indexes and `length`, so they look like arrays. -Naturally, these properties can combine. For instance, strings are both iterable (`for..of` works on them) and array-like (they have numeric indexes and `length`). +When we use JavaScript for practical tasks in a browser or any other environment, we may meet objects that are iterables or array-likes, or both. + +For instance, strings are both iterable (`for..of` works on them) and array-like (they have numeric indexes and `length`). -But an iterable may be not array-like. And vice versa an array-like may be not iterable. +But an iterable may not be array-like. And vice versa an array-like may not be iterable. For example, the `range` in the example above is iterable, but not array-like, because it does not have indexed properties and `length`. @@ -212,7 +214,7 @@ let arr = Array.from(arrayLike); // (*) alert(arr.pop()); // World (method works) ``` -`Array.from` at the line `(*)` takes the object, examines it for being an iterable or array-like, then makes a new array and copies there all items. +`Array.from` at the line `(*)` takes the object, examines it for being an iterable or array-like, then makes a new array and copies all items to it. The same happens for an iterable: @@ -222,12 +224,12 @@ let arr = Array.from(range); alert(arr); // 1,2,3,4,5 (array toString conversion works) ``` -The full syntax for `Array.from` allows to provide an optional "mapping" function: +The full syntax for `Array.from` also allows us to provide an optional "mapping" function: ```js Array.from(obj[, mapFn, thisArg]) ``` -The second argument `mapFn` should be the function to apply to each element before adding to the array, and `thisArg` allows to set `this` for it. +The optional second argument `mapFn` can be a function that will be applied to each element before adding it to the array, and `thisArg` allows us to set `this` for it. For instance: @@ -268,7 +270,7 @@ for (let char of str) { alert(chars); ``` -...But is shorter. +...But it is shorter. We can even build surrogate-aware `slice` on it: @@ -291,8 +293,8 @@ alert( str.slice(1, 3) ); // garbage (two pieces from different surrogate pairs) Objects that can be used in `for..of` are called *iterable*. - Technically, iterables must implement the method named `Symbol.iterator`. - - The result of `obj[Symbol.iterator]` is called an *iterator*. It handles the further iteration process. - - An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the iteration end, otherwise the `value` is the next value. + - The result of `obj[Symbol.iterator]()` is called an *iterator*. It handles further iteration process. + - An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the end of the iteration process, otherwise the `value` is the next value. - The `Symbol.iterator` method is called automatically by `for..of`, but we also can do it directly. - Built-in iterables like strings or arrays, also implement `Symbol.iterator`. - String iterator knows about surrogate pairs. @@ -302,4 +304,4 @@ Objects that have indexed properties and `length` are called *array-like*. Such If we look inside the specification -- we'll see that most built-in methods assume that they work with iterables or array-likes instead of "real" arrays, because that's more abstract. -`Array.from(obj[, mapFn, thisArg])` makes a real `Array` of an iterable or array-like `obj`, and we can then use array methods on it. The optional arguments `mapFn` and `thisArg` allow us to apply a function to each item. +`Array.from(obj[, mapFn, thisArg])` makes a real `Array` from an iterable or array-like `obj`, and we can then use array methods on it. The optional arguments `mapFn` and `thisArg` allow us to apply a function to each item. diff --git a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md index 25c74bfc2..81507647f 100644 --- a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md +++ b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md @@ -4,7 +4,7 @@ importance: 5 # Iterable keys -We'd like to get an array of `map.keys()` in a variable and then do apply array-specific methods to it, e.g. `.push`. +We'd like to get an array of `map.keys()` in a variable and then apply array-specific methods to it, e.g. `.push`. But that doesn't work: diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index aaed5b454..bd6cad562 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -1,10 +1,10 @@ # Map and Set -Now we've learned about the following complex data structures: +Till now, we've learned about the following complex data structures: -- Objects for storing keyed collections. -- Arrays for storing ordered collections. +- Objects are used for storing keyed collections. +- Arrays are used for storing ordered collections. But that's not enough for real life. That's why `Map` and `Set` also exist. @@ -42,7 +42,7 @@ alert( map.size ); // 3 As we can see, unlike objects, keys are not converted to strings. Any type of key is possible. ```smart header="`map[key]` isn't the right way to use a `Map`" -Although `map[key]` also works, e.g. we can set `map[key] = 2`, this is treating `map` as a plain JavaScript object, so it implies all corresponding limitations (no object keys and so on). +Although `map[key]` also works, e.g. we can set `map[key] = 2`, this is treating `map` as a plain JavaScript object, so it implies all corresponding limitations (only string/symbol keys and so on). So we should use `map` methods: `set`, `get` and so on. ``` @@ -63,24 +63,26 @@ visitsCountMap.set(john, 123); alert( visitsCountMap.get(john) ); // 123 ``` -Using objects as keys is one of most notable and important `Map` features. For string keys, `Object` can be fine, but not for object keys. +Using objects as keys is one of the most notable and important `Map` features. The same does not count for `Object`. String as a key in `Object` is fine, but we can't use another `Object` as a key in `Object`. Let's try: ```js run let john = { name: "John" }; +let ben = { name: "Ben" }; let visitsCountObj = {}; // try to use an object -visitsCountObj[john] = 123; // try to use john object as the key +visitsCountObj[ben] = 234; // try to use ben object as the key +visitsCountObj[john] = 123; // try to use john object as the key, ben object will get replaced *!* // That's what got written! -alert( visitsCountObj["[object Object]"] ); // 123 +alert( visitsCountObj["[object Object]"] ); // 123 */!* ``` -As `visitsCountObj` is an object, it converts all keys, such as `john` to strings, so we've got the string key `"[object Object]"`. Definitely not what we want. +As `visitsCountObj` is an object, it converts all `Object` keys, such as `john` and `ben` above, to same string `"[object Object]"`. Definitely not what we want. ```smart header="How `Map` compares keys" To test keys for equivalence, `Map` uses the algorithm [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). It is roughly the same as strict equality `===`, but the difference is that `NaN` is considered equal to `NaN`. So `NaN` can be used as the key as well. @@ -198,7 +200,7 @@ let prices = Object.fromEntries([ alert(prices.orange); // 2 ``` -We can use `Object.fromEntries` to get an plain object from `Map`. +We can use `Object.fromEntries` to get a plain object from `Map`. E.g. we store the data in a `Map`, but we need to pass it to a 3rd-party code that expects a plain object. @@ -220,7 +222,7 @@ let obj = Object.fromEntries(map.entries()); // make a plain object (*) alert(obj.orange); // 2 ``` -A call to `map.entries()` returns an array of key/value pairs, exactly in the right format for `Object.fromEntries`. +A call to `map.entries()` returns an iterable of key/value pairs, exactly in the right format for `Object.fromEntries`. We could also make line `(*)` shorter: ```js @@ -304,10 +306,10 @@ The same methods `Map` has for iterators are also supported: Methods and properties: - `new Map([iterable])` -- creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization. -- `map.set(key, value)` -- stores the value by the key. +- `map.set(key, value)` -- stores the value by the key, returns the map itself. - `map.get(key)` -- returns the value by the key, `undefined` if `key` doesn't exist in map. - `map.has(key)` -- returns `true` if the `key` exists, `false` otherwise. -- `map.delete(key)` -- removes the value by the key. +- `map.delete(key)` -- removes the value by the key, returns `true` if `key` existed at the moment of the call, otherwise `false`. - `map.clear()` -- removes everything from the map. - `map.size` -- returns the current element count. diff --git a/1-js/05-data-types/08-weakmap-weakset/article.md b/1-js/05-data-types/08-weakmap-weakset/article.md index bcc5e5e6f..5adbced20 100644 --- a/1-js/05-data-types/08-weakmap-weakset/article.md +++ b/1-js/05-data-types/08-weakmap-weakset/article.md @@ -30,7 +30,8 @@ let array = [ john ]; john = null; // overwrite the reference *!* -// john is stored inside the array, so it won't be garbage-collected +// the object previously referenced by john is stored inside the array +// therefore it won't be garbage-collected // we can get it as array[0] */!* ``` @@ -59,7 +60,7 @@ Let's see what it means on examples. ## WeakMap -The first difference from `Map` is that `WeakMap` keys must be objects, not primitive values: +The first difference between `Map` and `WeakMap` is that keys must be objects, not primitive values: ```js run let weakMap = new WeakMap(); @@ -100,9 +101,9 @@ Compare it with the regular `Map` example above. Now if `john` only exists as th Why such a limitation? That's for technical reasons. If an object has lost all other references (like `john` in the code above), then it is to be garbage-collected automatically. But technically it's not exactly specified *when the cleanup happens*. -The JavaScript engine decides that. It may choose to perform the memory cleanup immediately or to wait and do the cleaning later when more deletions happen. So, technically the current element count of a `WeakMap` is not known. The engine may have cleaned it up or not, or did it partially. For that reason, methods that access all keys/values are not supported. +The JavaScript engine decides that. It may choose to perform the memory cleanup immediately or to wait and do the cleaning later when more deletions happen. So, technically, the current element count of a `WeakMap` is not known. The engine may have cleaned it up or not, or did it partially. For that reason, methods that access all keys/values are not supported. -Now where do we need such data structure? +Now, where do we need such a data structure? ## Use case: additional data @@ -146,7 +147,7 @@ countUser(john); // count his visits john = null; ``` -Now `john` object should be garbage collected, but remains in memory, as it's a key in `visitsCountMap`. +Now, `john` object should be garbage collected, but remains in memory, as it's a key in `visitsCountMap`. We need to clean `visitsCountMap` when we remove users, otherwise it will grow in memory indefinitely. Such cleaning can become a tedious task in complex architectures. @@ -163,13 +164,13 @@ function countUser(user) { } ``` -Now we don't have to clean `visitsCountMap`. After `john` object becomes unreachable by all means except as a key of `WeakMap`, it gets removed from memory, along with the information by that key from `WeakMap`. +Now we don't have to clean `visitsCountMap`. After `john` object becomes unreachable, by all means except as a key of `WeakMap`, it gets removed from memory, along with the information by that key from `WeakMap`. ## Use case: caching -Another common example is caching: when a function result should be remembered ("cached"), so that future calls on the same object reuse it. +Another common example is caching. We can store ("cache") results from a function, so that future calls on the same object can reuse it. -We can use `Map` to store results, like this: +To achieve that, we can use `Map` (not optimal scenario): ```js run // 📁 cache.js @@ -206,7 +207,7 @@ alert(cache.size); // 1 (Ouch! The object is still in cache, taking memory!) For multiple calls of `process(obj)` with the same object, it only calculates the result the first time, and then just takes it from `cache`. The downside is that we need to clean `cache` when the object is not needed any more. -If we replace `Map` with `WeakMap`, then this problem disappears: the cached result will be removed from memory automatically after the object gets garbage collected. +If we replace `Map` with `WeakMap`, then this problem disappears. The cached result will be removed from memory automatically after the object gets garbage collected. ```js run // 📁 cache.js @@ -247,7 +248,7 @@ obj = null; - An object exists in the set while it is reachable from somewhere else. - Like `Set`, it supports `add`, `has` and `delete`, but not `size`, `keys()` and no iterations. -Being "weak", it also serves as an additional storage. But not for an arbitrary data, but rather for "yes/no" facts. A membership in `WeakSet` may mean something about the object. +Being "weak", it also serves as additional storage. But not for arbitrary data, rather for "yes/no" facts. A membership in `WeakSet` may mean something about the object. For instance, we can add users to `WeakSet` to keep track of those who visited our site: @@ -275,7 +276,7 @@ john = null; // visitedSet will be cleaned automatically ``` -The most notable limitation of `WeakMap` and `WeakSet` is the absence of iterations, and inability to get all current content. That may appear inconvenient, but does not prevent `WeakMap/WeakSet` from doing their main job -- be an "additional" storage of data for objects which are stored/managed at another place. +The most notable limitation of `WeakMap` and `WeakSet` is the absence of iterations, and the inability to get all current content. That may appear inconvenient, but does not prevent `WeakMap/WeakSet` from doing their main job -- be an "additional" storage of data for objects which are stored/managed at another place. ## Summary @@ -283,6 +284,8 @@ The most notable limitation of `WeakMap` and `WeakSet` is the absence of iterati `WeakSet` is `Set`-like collection that stores only objects and removes them once they become inaccessible by other means. -Both of them do not support methods and properties that refer to all keys or their count. Only individual operations are allowed. +Their main advantages are that they have weak reference to objects, so they can easily be removed by garbage collector. -`WeakMap` and `WeakSet` are used as "secondary" data structures in addition to the "main" object storage. Once the object is removed from the main storage, if it is only found as the key of `WeakMap` or in a `WeakSet`, it will be cleaned up automatically. +That comes at the cost of not having support for `clear`, `size`, `keys`, `values`... + +`WeakMap` and `WeakSet` are used as "secondary" data structures in addition to the "primary" object storage. Once the object is removed from the primary storage, if it is only found as the key of `WeakMap` or in a `WeakSet`, it will be cleaned up automatically. diff --git a/1-js/05-data-types/09-keys-values-entries/article.md b/1-js/05-data-types/09-keys-values-entries/article.md index 66ca3ca92..1820bae80 100644 --- a/1-js/05-data-types/09-keys-values-entries/article.md +++ b/1-js/05-data-types/09-keys-values-entries/article.md @@ -11,7 +11,7 @@ They are supported for: - `Map` - `Set` -- `Array` (except `arr.values()`) +- `Array` Plain objects also support similar methods, but the syntax is a bit different. @@ -63,8 +63,40 @@ for (let value of Object.values(user)) { } ``` -## Object.keys/values/entries ignore symbolic properties - +```warn header="Object.keys/values/entries ignore symbolic properties" Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys. -Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, the method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) returns *all* keys. +Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, there exist a method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys. +``` + + +## Transforming objects + +Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others. + +If we'd like to apply them, then we can use `Object.entries` followed by `Object.fromEntries`: + +1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`. +2. Use array methods on that array, e.g. `map`. +3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object. + +For example, we have an object with prices, and would like to double them: + +```js run +let prices = { + banana: 1, + orange: 2, + meat: 4, +}; + +*!* +let doublePrices = Object.fromEntries( + // convert to array, map, and then fromEntries gives back the object + Object.entries(prices).map(([key, value]) => [key, value * 2]) +); +*/!* + +alert(doublePrices.meat); // 8 +``` + +It may look difficult from the first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way. diff --git a/1-js/05-data-types/10-destructuring-assignment/article.md b/1-js/05-data-types/10-destructuring-assignment/article.md index 2f918e566..81c8a53a2 100644 --- a/1-js/05-data-types/10-destructuring-assignment/article.md +++ b/1-js/05-data-types/10-destructuring-assignment/article.md @@ -117,6 +117,25 @@ for (let [key, value] of user.entries()) { } ``` ```` + +```smart header="Swap variables trick" +A well-known trick for swapping values of two variables: + +```js run +let guest = "Jane"; +let admin = "Pete"; + +// Swap values: make guest=Pete, admin=Jane +[guest, admin] = [admin, guest]; + +alert(`${guest} ${admin}`); // Pete Jane (successfully swapped!) +``` + +Here we create a temporary array of two variables and immediately destructure it in swapped order. + +We can swap more than two variables this way. + + ### The rest '...' If we want not just to get first values, but also to gather all that follows -- we can add one more parameter that gets "the rest" using three dots `"..."`: @@ -183,7 +202,7 @@ The destructuring assignment also works with objects. The basic syntax is: ```js -let {var1, var2} = {var1:…, var2…} +let {var1, var2} = {var1:…, var2:…} ``` We have an existing object at the right side, that we want to split into variables. The left side contains a "pattern" for corresponding properties. In the simple case, that's a list of variable names in `{...}`. @@ -337,7 +356,9 @@ The problem is that JavaScript treats `{...}` in the main code flow (not inside } ``` -To show JavaScript that it's not a code block, we can wrap the whole assignment in parentheses `(...)`: +So here JavaScript assumes that we have a code block, that's why there's an error. We want destructuring instead. + +To show JavaScript that it's not a code block, we can wrap the expression in parentheses `(...)`: ```js run let title, width, height; @@ -383,9 +404,7 @@ alert(item1); // Cake alert(item2); // Donut ``` -The whole `options` object except `extra` that was not mentioned, is assigned to corresponding variables. - -Note that `size` and `items` itself is not destructured. +All properties of `options` object except `extra` that is absent in the left part, are assigned to corresponding variables: ![](destructuring-complex.svg) @@ -416,6 +435,7 @@ In real-life, the problem is how to remember the order of arguments. Usually IDE Like this? ```js +// undefined where default values are fine showMenu("My Menu", undefined, undefined, ["Item1", "Item2"]) ``` diff --git a/1-js/05-data-types/10-destructuring-assignment/destructuring-complex.svg b/1-js/05-data-types/10-destructuring-assignment/destructuring-complex.svg index c3e25b569..cb496bf66 100644 --- a/1-js/05-data-types/10-destructuring-assignment/destructuring-complex.svg +++ b/1-js/05-data-types/10-destructuring-assignment/destructuring-complex.svg @@ -1,59 +1 @@ - - - - destructuring-complex.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/1-js/05-data-types/11-date/1-new-date/solution.md b/1-js/05-data-types/11-date/1-new-date/solution.md index eb271a91a..135c615f9 100644 --- a/1-js/05-data-types/11-date/1-new-date/solution.md +++ b/1-js/05-data-types/11-date/1-new-date/solution.md @@ -2,7 +2,17 @@ The `new Date` constructor uses the local time zone by default. So the only impo So February has number 1. +Here's an example with numbers as date components: + +```js run +//new Date(year, month, date, hour, minute, second, millisecond) +let d1 = new Date(2012, 1, 20, 3, 12); +alert( d1 ); +``` +We could also create a date from a string, like this: + ```js run -let d = new Date(2012, 1, 20, 3, 12); -alert( d ); +//new Date(datastring) +let d2 = new Date("February 20, 2012 03:12:00"); +alert( d2 ); ``` diff --git a/1-js/05-data-types/11-date/6-get-seconds-today/solution.md b/1-js/05-data-types/11-date/6-get-seconds-today/solution.md index a483afe93..8f8e52b68 100644 --- a/1-js/05-data-types/11-date/6-get-seconds-today/solution.md +++ b/1-js/05-data-types/11-date/6-get-seconds-today/solution.md @@ -23,4 +23,6 @@ function getSecondsToday() { let d = new Date(); return d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds(); } + +alert( getSecondsToday() ); ``` diff --git a/1-js/05-data-types/11-date/6-get-seconds-today/task.md b/1-js/05-data-types/11-date/6-get-seconds-today/task.md index 3fbe13286..456790928 100644 --- a/1-js/05-data-types/11-date/6-get-seconds-today/task.md +++ b/1-js/05-data-types/11-date/6-get-seconds-today/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# How many seconds has passed today? +# How many seconds have passed today? Write a function `getSecondsToday()` that returns the number of seconds from the beginning of today. -For instance, if now `10:00 am`, and there was no daylight savings shift, then: +For instance, if now were `10:00 am`, and there was no daylight savings shift, then: ```js getSecondsToday() == 36000 // (3600 * 10) diff --git a/1-js/05-data-types/11-date/8-format-date-relative/solution.md b/1-js/05-data-types/11-date/8-format-date-relative/solution.md index 2507c840c..372485685 100644 --- a/1-js/05-data-types/11-date/8-format-date-relative/solution.md +++ b/1-js/05-data-types/11-date/8-format-date-relative/solution.md @@ -40,7 +40,7 @@ alert( formatDate(new Date(new Date - 30 * 1000)) ); // "30 sec. ago" alert( formatDate(new Date(new Date - 5 * 60 * 1000)) ); // "5 min. ago" -// yesterday's date like 31.12.2016, 20:00 +// yesterday's date like 31.12.2016 20:00 alert( formatDate(new Date(new Date - 86400 * 1000)) ); ``` @@ -62,6 +62,8 @@ function formatDate(date) { year = year.toString().slice(-2); month = month < 10 ? '0' + month : month; dayOfMonth = dayOfMonth < 10 ? '0' + dayOfMonth : dayOfMonth; + hour = hour < 10 ? '0' + hour : hour; + minutes = minutes < 10 ? '0' + minutes : minutes; if (diffSec < 1) { return 'right now'; diff --git a/1-js/05-data-types/11-date/8-format-date-relative/task.md b/1-js/05-data-types/11-date/8-format-date-relative/task.md index 7b341ca2e..9651b305f 100644 --- a/1-js/05-data-types/11-date/8-format-date-relative/task.md +++ b/1-js/05-data-types/11-date/8-format-date-relative/task.md @@ -20,6 +20,6 @@ alert( formatDate(new Date(new Date - 30 * 1000)) ); // "30 sec. ago" alert( formatDate(new Date(new Date - 5 * 60 * 1000)) ); // "5 min. ago" -// yesterday's date like 31.12.2016, 20:00 +// yesterday's date like 31.12.16 20:00 alert( formatDate(new Date(new Date - 86400 * 1000)) ); ``` diff --git a/1-js/05-data-types/11-date/article.md b/1-js/05-data-types/11-date/article.md index 8a75f1cbd..a3117806e 100644 --- a/1-js/05-data-types/11-date/article.md +++ b/1-js/05-data-types/11-date/article.md @@ -29,18 +29,24 @@ To create a new `Date` object call `new Date()` with one of the following argume alert( Jan02_1970 ); ``` - The number of milliseconds that has passed since the beginning of 1970 is called a *timestamp*. + An integer number representing the number of milliseconds that has passed since the beginning of 1970 is called a *timestamp*. It's a lightweight numeric representation of a date. We can always create a date from a timestamp using `new Date(timestamp)` and convert the existing `Date` object to a timestamp using the `date.getTime()` method (see below). -`new Date(datestring)` -: If there is a single argument, and it's a string, then it is parsed with the `Date.parse` algorithm (see below). + Dates before 01.01.1970 have negative timestamps, e.g.: + ```js run + // 31 Dec 1969 + let Dec31_1969 = new Date(-24 * 3600 * 1000); + alert( Dec31_1969 ); + ``` +`new Date(datestring)` +: If there is a single argument, and it's a string, then it is parsed automatically. The algorithm is the same as `Date.parse` uses, we'll cover it later. ```js run let date = new Date("2017-01-26"); alert(date); - // The time portion of the date is assumed to be midnight GMT and + // The time is not set, so it's assumed to be midnight GMT and // is adjusted according to the timezone the code is run in // So the result could be // Thu Jan 26 2017 11:00:00 GMT+1100 (Australian Eastern Daylight Time) @@ -49,9 +55,7 @@ To create a new `Date` object call `new Date()` with one of the following argume ``` `new Date(year, month, date, hours, minutes, seconds, ms)` -: Create the date with the given components in the local time zone. Only two first arguments are obligatory. - - Note: +: Create the date with the given components in the local time zone. Only the first two arguments are obligatory. - The `year` must have 4 digits: `2013` is okay, `98` is not. - The `month` count starts with `0` (Jan), up to `11` (Dec). @@ -61,11 +65,11 @@ To create a new `Date` object call `new Date()` with one of the following argume For instance: ```js - new Date(2011, 0, 1, 0, 0, 0, 0); // // 1 Jan 2011, 00:00:00 + new Date(2011, 0, 1, 0, 0, 0, 0); // 1 Jan 2011, 00:00:00 new Date(2011, 0, 1); // the same, hours etc are 0 by default ``` - The minimal precision is 1 ms (1/1000 sec): + The maximal precision is 1 ms (1/1000 sec): ```js run let date = new Date(2011, 0, 1, 2, 3, 4, 567); @@ -74,7 +78,7 @@ To create a new `Date` object call `new Date()` with one of the following argume ## Access date components -There are many methods to access the year, month and so on from the `Date` object. But they can be easily remembered when categorized. +There are methods to access the year, month and so on from the `Date` object: [getFullYear()](mdn:js/Date/getFullYear) : Get the year (4 digits) @@ -120,7 +124,7 @@ Besides the given methods, there are two special ones that do not have a UTC-var : Returns the timestamp for the date -- a number of milliseconds passed from the January 1st of 1970 UTC+0. [getTimezoneOffset()](mdn:js/Date/getTimezoneOffset) -: Returns the difference between the local time zone and UTC, in minutes: +: Returns the difference between UTC and the local time zone, in minutes: ```js run // if you are in timezone UTC-1, outputs 60 @@ -133,12 +137,12 @@ Besides the given methods, there are two special ones that do not have a UTC-var The following methods allow to set date/time components: -- [`setFullYear(year [, month, date])`](mdn:js/Date/setFullYear) -- [`setMonth(month [, date])`](mdn:js/Date/setMonth) +- [`setFullYear(year, [month], [date])`](mdn:js/Date/setFullYear) +- [`setMonth(month, [date])`](mdn:js/Date/setMonth) - [`setDate(date)`](mdn:js/Date/setDate) -- [`setHours(hour [, min, sec, ms])`](mdn:js/Date/setHours) -- [`setMinutes(min [, sec, ms])`](mdn:js/Date/setMinutes) -- [`setSeconds(sec [, ms])`](mdn:js/Date/setSeconds) +- [`setHours(hour, [min], [sec], [ms])`](mdn:js/Date/setHours) +- [`setMinutes(min, [sec], [ms])`](mdn:js/Date/setMinutes) +- [`setSeconds(sec, [ms])`](mdn:js/Date/setSeconds) - [`setMilliseconds(ms)`](mdn:js/Date/setMilliseconds) - [`setTime(milliseconds)`](mdn:js/Date/setTime) (sets the whole date by milliseconds since 01.01.1970 UTC) @@ -217,21 +221,21 @@ The important side effect: dates can be subtracted, the result is their differen That can be used for time measurements: ```js run -let start = new Date(); // start counting +let start = new Date(); // start measuring time // do the job for (let i = 0; i < 100000; i++) { let doSomething = i * i * i; } -let end = new Date(); // done +let end = new Date(); // end measuring time alert( `The loop took ${end - start} ms` ); ``` ## Date.now() -If we only want to measure the difference, we don't need the `Date` object. +If we only want to measure time, we don't need the `Date` object. There's a special method `Date.now()` that returns the current timestamp. @@ -264,6 +268,8 @@ If we want a reliable benchmark of CPU-hungry function, we should be careful. For instance, let's measure two functions that calculate the difference between two dates: which one is faster? +Such performance measurements are often called "benchmarks". + ```js // we have date1 and date2, which function faster returns their difference in ms? function diffSubtract(date1, date2) { @@ -280,7 +286,7 @@ These two do exactly the same thing, but one of them uses an explicit `date.getT So, which one is faster? -The first idea may be to run them many times in a row and measure the time difference. For our case, functions are very simple, so we have to do it around 100000 times. +The first idea may be to run them many times in a row and measure the time difference. For our case, functions are very simple, so we have to do it at least 100000 times. Let's measure: @@ -310,7 +316,7 @@ Wow! Using `getTime()` is so much faster! That's because there's no type convers Okay, we have something. But that's not a good benchmark yet. -Imagine that at the time of running `bench(diffSubtract)` CPU was doing something in parallel, and it was taking resources. And by the time of running `bench(diffGetTime)` the work has finished. +Imagine that at the time of running `bench(diffSubtract)` CPU was doing something in parallel, and it was taking resources. And by the time of running `bench(diffGetTime)` that work has finished. A pretty real scenario for a modern multi-process OS. @@ -318,7 +324,7 @@ As a result, the first benchmark will have less CPU resources than the second. T **For more reliable benchmarking, the whole pack of benchmarks should be rerun multiple times.** -Here's the code example: +For example, like this: ```js run function diffSubtract(date1, date2) { @@ -368,7 +374,7 @@ for (let i = 0; i < 10; i++) { ``` ```warn header="Be careful doing microbenchmarking" -Modern JavaScript engines perform many optimizations. They may tweak results of "artificial tests" compared to "normal usage", especially when we benchmark something very small. So if you seriously want to understand performance, then please study how the JavaScript engine works. And then you probably won't need microbenchmarks at all. +Modern JavaScript engines perform many optimizations. They may tweak results of "artificial tests" compared to "normal usage", especially when we benchmark something very small, such as how an operator works, or a built-in function. So if you seriously want to understand performance, then please study how the JavaScript engine works. And then you probably won't need microbenchmarks at all. The great pack of articles about V8 can be found at . ``` @@ -382,7 +388,7 @@ The string format should be: `YYYY-MM-DDTHH:mm:ss.sssZ`, where: - `YYYY-MM-DD` -- is the date: year-month-day. - The character `"T"` is used as the delimiter. - `HH:mm:ss.sss` -- is the time: hours, minutes, seconds and milliseconds. -- The optional `'Z'` part denotes the time zone in the format `+-hh:mm`. A single letter `Z` that would mean UTC+0. +- The optional `'Z'` part denotes the time zone in the format `+-hh:mm`. A single letter `Z` would mean UTC+0. Shorter variants are also possible, like `YYYY-MM-DD` or `YYYY-MM` or even `YYYY`. @@ -415,13 +421,13 @@ alert(date); Note that unlike many other systems, timestamps in JavaScript are in milliseconds, not in seconds. -Also, sometimes we need more precise time measurements. JavaScript itself does not have a way to measure time in microseconds (1 millionth of a second), but most environments provide it. For instance, browser has [performance.now()](mdn:api/Performance/now) that gives the number of milliseconds from the start of page loading with microsecond precision (3 digits after the point): +Sometimes we need more precise time measurements. JavaScript itself does not have a way to measure time in microseconds (1 millionth of a second), but most environments provide it. For instance, browser has [performance.now()](mdn:api/Performance/now) that gives the number of milliseconds from the start of page loading with microsecond precision (3 digits after the point): ```js run alert(`Loading started ${performance.now()}ms ago`); // Something like: "Loading started 34731.26000000001ms ago" // .26 is microseconds (260 microseconds) -// more than 3 digits after the decimal point are precision errors, but only the first 3 are correct +// more than 3 digits after the decimal point are precision errors, only the first 3 are correct ``` -Node.js has `microtime` module and other ways. Technically, any device and environment allows to get more precision, it's just not in `Date`. +Node.js has `microtime` module and other ways. Technically, almost any device and environment allows to get more precision, it's just not in `Date`. diff --git a/1-js/05-data-types/12-json/article.md b/1-js/05-data-types/12-json/article.md index 50458906a..8269a5a64 100644 --- a/1-js/05-data-types/12-json/article.md +++ b/1-js/05-data-types/12-json/article.md @@ -105,7 +105,7 @@ JSON is data-only cross-language specification, so some JavaScript-specific obje Namely: - Function properties (methods). -- Symbolic properties. +- Symbolic keys and values. - Properties that store `undefined`. ```js run @@ -276,6 +276,7 @@ name: John name: Alice place: [object Object] number: 23 +occupiedBy: [object Object] */ ``` @@ -286,13 +287,13 @@ The first call is special. It is made using a special "wrapper object": `{"": me The idea is to provide as much power for `replacer` as possible: it has a chance to analyze and replace/skip the whole object if necessary. -## Formatting: spacer +## Formatting: space -The third argument of `JSON.stringify(value, replacer, spaces)` is the number of spaces to use for pretty formatting. +The third argument of `JSON.stringify(value, replacer, space)` is the number of spaces to use for pretty formatting. -Previously, all stringified objects had no indents and extra spaces. That's fine if we want to send an object over a network. The `spacer` argument is used exclusively for a nice output. +Previously, all stringified objects had no indents and extra spaces. That's fine if we want to send an object over a network. The `space` argument is used exclusively for a nice output. -Here `spacer = 2` tells JavaScript to show nested objects on multiple lines, with indentation of 2 spaces inside an object: +Here `space = 2` tells JavaScript to show nested objects on multiple lines, with indentation of 2 spaces inside an object: ```js run let user = { @@ -328,7 +329,9 @@ alert(JSON.stringify(user, null, 2)); */ ``` -The `spaces` parameter is used solely for logging and nice-output purposes. +The third argument can also be a string. In this case, the string is used for indentation instead of a number of spaces. + +The `space` parameter is used solely for logging and nice-output purposes. ## Custom "toJSON" @@ -393,7 +396,7 @@ alert( JSON.stringify(meetup) ); */ ``` -As we can see, `toJSON` is used both for the direct call `JSON.stringify(room)` and for the nested object. +As we can see, `toJSON` is used both for the direct call `JSON.stringify(room)` and when `room` is nested in another encoded object. ## JSON.parse @@ -425,9 +428,9 @@ alert( numbers[1] ); // 1 Or for nested objects: ```js run -let user = '{ "name": "John", "age": 35, "isAdmin": false, "friends": [0,1,2,3] }'; +let userData = '{ "name": "John", "age": 35, "isAdmin": false, "friends": [0,1,2,3] }'; -user = JSON.parse(user); +let user = JSON.parse(userData); alert( user.friends[1] ); // 1 ``` diff --git a/1-js/05-data-types/12-json/json-meetup.svg b/1-js/05-data-types/12-json/json-meetup.svg index 5e1929343..e44674904 100644 --- a/1-js/05-data-types/12-json/json-meetup.svg +++ b/1-js/05-data-types/12-json/json-meetup.svg @@ -1,35 +1 @@ - - - - json-meetup.svg - Created with sketchtool. - - - - - number: 23 - - - - title: "Conference" - - - - ... - - - place - - - - - occupiedBy - - - - participants - - - - - \ No newline at end of file +number: 23title: "Conference"...placeoccupiedByparticipants \ No newline at end of file diff --git a/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md b/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md index 59040a2b7..09e511db5 100644 --- a/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md +++ b/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md @@ -1,4 +1,4 @@ -By definition, a factorial is `n!` can be written as `n * (n-1)!`. +By definition, a factorial `n!` can be written as `n * (n-1)!`. In other words, the result of `factorial(n)` can be calculated as `n` multiplied by the result of `factorial(n-1)`. And the call for `n-1` can recursively descend lower, and lower, till `1`. diff --git a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.svg b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.svg index d5a8ba23d..59e6a52c4 100644 --- a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.svg +++ b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.svg @@ -1,72 +1 @@ - - - - fibonacci-recursion-tree.svg - Created with sketchtool. - - - - fib - ( - 5 - ) - - - - - - - - - - - - - - - - - fib(4) - - - fib(3) - - - fib(3) - - - fib(2) - - - fib(0) - - - fib(1) - - - fib(1) - - - fib(2) - - - fib(0) - - - fib(1) - - - fib(1) - - - fib(2) - - - fib(0) - - - fib(1) - - - - \ No newline at end of file +fib ( 5 )fib(4)fib(3)fib(3)fib(2)fib(0)fib(1)fib(1)fib(2)fib(0)fib(1)fib(1)fib(2)fib(0)fib(1) \ No newline at end of file diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md index d78142190..b6c0820da 100644 --- a/1-js/06-advanced-functions/01-recursion/article.md +++ b/1-js/06-advanced-functions/01-recursion/article.md @@ -96,7 +96,7 @@ function pow(x, n) { The maximal number of nested calls (including the first one) is called *recursion depth*. In our case, it will be exactly `n`. -The maximal recursion depth is limited by JavaScript engine. We can make sure about 10000, some engines allow more, but 100000 is probably out of limit for the majority of them. There are automatic optimizations that help alleviate this ("tail calls optimizations"), but they are not yet supported everywhere and work only in simple cases. +The maximal recursion depth is limited by JavaScript engine. We can rely on it being 10000, some engines allow more, but 100000 is probably out of limit for the majority of them. There are automatic optimizations that help alleviate this ("tail calls optimizations"), but they are not yet supported everywhere and work only in simple cases. That limits the application of recursion, but it still remains very wide. There are many tasks where recursive way of thinking gives simpler code, easier to maintain. @@ -132,7 +132,7 @@ We can sketch it as: -That's when the function starts to execute. The condition `n == 1` is false, so the flow continues into the second branch of `if`: +That's when the function starts to execute. The condition `n == 1` is falsy, so the flow continues into the second branch of `if`: ```js run function pow(x, n) { @@ -185,7 +185,13 @@ Here's the context stack when we entered the subcall `pow(2, 2)`: The new current execution context is on top (and bold), and previous remembered contexts are below. -When we finish the subcall -- it is easy to resume the previous context, because it keeps both variables and the exact place of the code where it stopped. Here in the picture we use the word "line", but of course it's more precise. +When we finish the subcall -- it is easy to resume the previous context, because it keeps both variables and the exact place of the code where it stopped. + +```smart +Here in the picture we use the word "line", as in our example there's only one subcall in line, but generally a single line of code may contain multiple subcalls, like `pow(…) + pow(…) + somethingElse(…)`. + +So it would be more precise to say that the execution resumes "immediately after the subcall". +``` ### pow(2, 1) @@ -296,7 +302,7 @@ let company = { salary: 1000 }, { name: 'Alice', - salary: 600 + salary: 1600 }], development: { @@ -337,14 +343,14 @@ As we can see, when our function gets a department to sum, there are two possibl The (1) is the base of recursion, the trivial case. -The (2) is the recursive step. A complex task is split into subtasks for smaller departments. They may in turn split again, but sooner or later the split will finish at (1). +The 2nd case when we get an object is the recursive step. A complex task is split into subtasks for smaller departments. They may in turn split again, but sooner or later the split will finish at (1). The algorithm is probably even easier to read from the code: ```js run let company = { // the same object, compressed for brevity - sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 600 }], + sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 1600 }], development: { sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }], internals: [{name: 'Jack', salary: 1300}] @@ -366,7 +372,7 @@ function sumSalaries(department) { } */!* -alert(sumSalaries(company)); // 6700 +alert(sumSalaries(company)); // 7700 ``` The code is short and easy to understand (hopefully?). That's the power of recursion. It also works for any level of subdepartment nesting. @@ -453,9 +459,10 @@ let list = { value: 1 }; list.next = { value: 2 }; list.next.next = { value: 3 }; list.next.next.next = { value: 4 }; +list.next.next.next.next = null; ``` -Here we can even more clearer see that there are multiple objects, each one has the `value` and `next` pointing to the neighbour. The `list` variable is the first object in the chain, so following `next` pointers from it we can reach any element. +Here we can even more clearly see that there are multiple objects, each one has the `value` and `next` pointing to the neighbour. The `list` variable is the first object in the chain, so following `next` pointers from it we can reach any element. The list can be easily split into multiple parts and later joined back: diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-0.svg b/1-js/06-advanced-functions/01-recursion/linked-list-0.svg index 97e80b262..f18c6ffb6 100644 --- a/1-js/06-advanced-functions/01-recursion/linked-list-0.svg +++ b/1-js/06-advanced-functions/01-recursion/linked-list-0.svg @@ -1,71 +1 @@ - - - - linked-list-0.svg - Created with sketchtool. - - - - - value - - - 1 - - - - next - - - - value - - - "new item" - - - - next - - - - value - - - 2 - - - - next - - - - value - - - 3 - - - - next - - - - value - - - 4 - - - - next - - - null - - - list - - - - \ No newline at end of file +value1nextvalue"new item"nextvalue2nextvalue3nextvalue4nextnulllist \ No newline at end of file diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg index 959466353..edec23912 100644 --- a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg +++ b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg @@ -1,71 +1 @@ - - - - linked-list-remove-1.svg - Created with sketchtool. - - - - - value - - - "new item" - - - - next - - - - value - - - 1 - - - - next - - - - value - - - 2 - - - - next - - - - value - - - 3 - - - - next - - - - value - - - 4 - - - - next - - - null - - - list - - - - \ No newline at end of file +value"new item"nextvalue1nextvalue2nextvalue3nextvalue4nextnulllist \ No newline at end of file diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-split.svg b/1-js/06-advanced-functions/01-recursion/linked-list-split.svg index 6032a85af..cba81e648 100644 --- a/1-js/06-advanced-functions/01-recursion/linked-list-split.svg +++ b/1-js/06-advanced-functions/01-recursion/linked-list-split.svg @@ -1,66 +1 @@ - - - - linked-list-split.svg - Created with sketchtool. - - - - - value - - - 1 - - - - next - - - - value - - - 2 - - - - next - - - - value - - - 3 - - - - next - - - - value - - - 4 - - - - next - - - null - - - null - - - secondList - - - list - - - - \ No newline at end of file +value1nextvalue2nextvalue3nextvalue4nextnullnullsecondListlist \ No newline at end of file diff --git a/1-js/06-advanced-functions/01-recursion/linked-list.svg b/1-js/06-advanced-functions/01-recursion/linked-list.svg index 4955c436c..63a070fd2 100644 --- a/1-js/06-advanced-functions/01-recursion/linked-list.svg +++ b/1-js/06-advanced-functions/01-recursion/linked-list.svg @@ -1,60 +1 @@ - - - - linked-list.svg - Created with sketchtool. - - - - - value - - - 1 - - - - next - - - - value - - - 2 - - - - next - - - - value - - - 3 - - - - next - - - - value - - - 4 - - - - next - - - null - - - list - - - - \ No newline at end of file +value1nextvalue2nextvalue3nextvalue4nextnulllist \ No newline at end of file diff --git a/1-js/06-advanced-functions/01-recursion/recursion-pow.svg b/1-js/06-advanced-functions/01-recursion/recursion-pow.svg index cb81b12a9..8bd4a43fe 100644 --- a/1-js/06-advanced-functions/01-recursion/recursion-pow.svg +++ b/1-js/06-advanced-functions/01-recursion/recursion-pow.svg @@ -1,50 +1 @@ - - - - recursion-pow.svg - Created with sketchtool. - - - - - - pow(x,n) - - - - - - - x - - - - - - x * pow(x, n-1) - - - - - - - - n == 1 ? - - - - Yes - - - No - - - - - - recursive call until n==1 - - - - - \ No newline at end of file +pow(x,n)xx * pow(x, n-1)n == 1 ?YesNorecursive call until n==1 \ No newline at end of file diff --git a/1-js/06-advanced-functions/01-recursion/recursive-salaries.svg b/1-js/06-advanced-functions/01-recursion/recursive-salaries.svg index a3314e5e9..f47f0668b 100644 --- a/1-js/06-advanced-functions/01-recursion/recursive-salaries.svg +++ b/1-js/06-advanced-functions/01-recursion/recursive-salaries.svg @@ -1,90 +1 @@ - - - - recursive-salaries.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md index 776feb40c..1f139d7a4 100644 --- a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md +++ b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md @@ -227,7 +227,7 @@ So, for the task of turning something into an array, `Array.from` tends to be mo ## Get a new copy of an array/object -Remember when we talked about `Object.assign()` [in the past](https://javascript.info/object#cloning-and-merging-object-assign)? +Remember when we talked about `Object.assign()` [in the past](info:object-copy#cloning-and-merging-object-assign)? It is possible to do the same thing with the spread syntax. diff --git a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md new file mode 100644 index 000000000..7cbd85ab7 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md @@ -0,0 +1,5 @@ +The answer is: **Pete**. + +A function gets outer variables as they are now, it uses the most recent values. + +Old variable values are not saved anywhere. When a function wants a variable, it takes the current value from its own Lexical Environment or the outer one. diff --git a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md new file mode 100644 index 000000000..819189773 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md @@ -0,0 +1,23 @@ +importance: 5 + +--- + +# Does a function pickup latest changes? + +The function sayHi uses an external variable name. When the function runs, which value is it going to use? + +```js +let name = "John"; + +function sayHi() { + alert("Hi, " + name); +} + +name = "Pete"; + +sayHi(); // what will it show: "John" or "Pete"? +``` + +Such situations are common both in browser and server-side development. A function may be scheduled to execute later than it is created, for instance after a user action or a network request. + +So, the question is: does it pick up the latest changes? diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/_js.view/solution.js b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js similarity index 100% rename from 1-js/06-advanced-functions/03-closure/8-make-army/_js.view/solution.js rename to 1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/_js.view/source.js b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js similarity index 100% rename from 1-js/06-advanced-functions/03-closure/8-make-army/_js.view/source.js rename to 1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/_js.view/test.js b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/test.js similarity index 100% rename from 1-js/06-advanced-functions/03-closure/8-make-army/_js.view/test.js rename to 1-js/06-advanced-functions/03-closure/10-make-army/_js.view/test.js diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg new file mode 100644 index 000000000..c4e0e5b98 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg @@ -0,0 +1 @@ +outer<empty>makeArmy() LexicalEnvironmentwhile iteration LexicalEnvironment<empty><empty><empty>i: 10 \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg new file mode 100644 index 000000000..3d1f3022b --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg @@ -0,0 +1 @@ +outermakeArmy() LexicalEnvironmentfor iteration LexicalEnvironmenti: 0i: 1i: 2i: 10... \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg new file mode 100644 index 000000000..c5185e4ff --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg @@ -0,0 +1 @@ +outerj: 0j: 1j: 2j: 10...makeArmy() LexicalEnvironmentwhile iteration LexicalEnvironment \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/solution.md b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md new file mode 100644 index 000000000..3dbefb521 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md @@ -0,0 +1,129 @@ + +Let's examine what exactly happens inside `makeArmy`, and the solution will become obvious. + +1. It creates an empty array `shooters`: + + ```js + let shooters = []; + ``` +2. Fills it with functions via `shooters.push(function)` in the loop. + + Every element is a function, so the resulting array looks like this: + + ```js no-beautify + shooters = [ + function () { alert(i); }, + function () { alert(i); }, + function () { alert(i); }, + function () { alert(i); }, + function () { alert(i); }, + function () { alert(i); }, + function () { alert(i); }, + function () { alert(i); }, + function () { alert(i); }, + function () { alert(i); } + ]; + ``` + +3. The array is returned from the function. + + Then, later, the call to any member, e.g. `army[5]()` will get the element `army[5]` from the array (which is a function) and calls it. + + Now why do all such functions show the same value, `10`? + + That's because there's no local variable `i` inside `shooter` functions. When such a function is called, it takes `i` from its outer lexical environment. + + Then, what will be the value of `i`? + + If we look at the source: + + ```js + function makeArmy() { + ... + let i = 0; + while (i < 10) { + let shooter = function() { // shooter function + alert( i ); // should show its number + }; + shooters.push(shooter); // add function to the array + i++; + } + ... + } + ``` + + We can see that all `shooter` functions are created in the lexical environment of `makeArmy()` function. But when `army[5]()` is called, `makeArmy` has already finished its job, and the final value of `i` is `10` (`while` stops at `i=10`). + + As the result, all `shooter` functions get the same value from the outer lexical environment and that is, the last value, `i=10`. + + ![](lexenv-makearmy-empty.svg) + + As you can see above, on each iteration of a `while {...}` block, a new lexical environment is created. So, to fix this, we can copy the value of `i` into a variable within the `while {...}` block, like this: + + ```js run + function makeArmy() { + let shooters = []; + + let i = 0; + while (i < 10) { + *!* + let j = i; + */!* + let shooter = function() { // shooter function + alert( *!*j*/!* ); // should show its number + }; + shooters.push(shooter); + i++; + } + + return shooters; + } + + let army = makeArmy(); + + // Now the code works correctly + army[0](); // 0 + army[5](); // 5 + ``` + + Here `let j = i` declares an "iteration-local" variable `j` and copies `i` into it. Primitives are copied "by value", so we actually get an independent copy of `i`, belonging to the current loop iteration. + + The shooters work correctly, because the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds the current loop iteration: + + ![](lexenv-makearmy-while-fixed.svg) + + Such problem could also be avoided if we used `for` in the beginning, like this: + + ```js run demo + function makeArmy() { + + let shooters = []; + + *!* + for(let i = 0; i < 10; i++) { + */!* + let shooter = function() { // shooter function + alert( i ); // should show its number + }; + shooters.push(shooter); + } + + return shooters; + } + + let army = makeArmy(); + + army[0](); // 0 + army[5](); // 5 + ``` + + That's essentially the same, because `for` on each iteration generates a new lexical environment, with its own variable `i`. So `shooter` generated in every iteration references its own `i`, from that very iteration. + + ![](lexenv-makearmy-for-fixed.svg) + +Now, as you've put so much effort into reading this, and the final recipe is so simple - just use `for`, you may wonder -- was it worth that? + +Well, if you could easily answer the question, you wouldn't read the solution. So, hopefully this task must have helped you to understand things a bit better. + +Besides, there are indeed cases when one prefers `while` to `for`, and other scenarios, where such problems are real. + diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/task.md b/1-js/06-advanced-functions/03-closure/10-make-army/task.md new file mode 100644 index 000000000..f50c7dc20 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/10-make-army/task.md @@ -0,0 +1,41 @@ +importance: 5 + +--- + +# Army of functions + +The following code creates an array of `shooters`. + +Every function is meant to output its number. But something is wrong... + +```js run +function makeArmy() { + let shooters = []; + + let i = 0; + while (i < 10) { + let shooter = function() { // create a shooter function, + alert( i ); // that should show its number + }; + shooters.push(shooter); // and add it to the array + i++; + } + + // ...and return the array of shooters + return shooters; +} + +let army = makeArmy(); + +*!* +// all shooters show 10 instead of their numbers 0, 1, 2, 3... +army[0](); // 10 from the shooter number 0 +army[1](); // 10 from the shooter number 1 +army[2](); // 10 ...and so on. +*/!* +``` + +Why do all of the shooters show the same value? + +Fix the code so that they work as intended. + diff --git a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/lexenv-nested-work.svg b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/lexenv-nested-work.svg new file mode 100644 index 000000000..5cdf7f1a4 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/lexenv-nested-work.svg @@ -0,0 +1 @@ +makeWorker: function name: "John"<empty>outerouterouternullname: "Pete" \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md new file mode 100644 index 000000000..0a522132f --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md @@ -0,0 +1,9 @@ +The answer is: **Pete**. + +The `work()` function in the code below gets `name` from the place of its origin through the outer lexical environment reference: + +![](lexenv-nested-work.svg) + +So, the result is `"Pete"` here. + +But if there were no `let name` in `makeWorker()`, then the search would go outside and take the global variable as we can see from the chain above. In that case the result would be `"John"`. diff --git a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md new file mode 100644 index 000000000..d12a385c8 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md @@ -0,0 +1,29 @@ +importance: 5 + +--- + +# Which variables are available? + +The function `makeWorker` below makes another function and returns it. That new function can be called from somewhere else. + +Will it have access to the outer variables from its creation place, or the invocation place, or both? + +```js +function makeWorker() { + let name = "Pete"; + + return function() { + alert(name); + }; +} + +let name = "John"; + +// create a function +let work = makeWorker(); + +// call it +work(); // what will it show? +``` + +Which value it will show? "Pete" or "John"? diff --git a/1-js/06-advanced-functions/03-closure/1-counter-independent/solution.md b/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/1-counter-independent/solution.md rename to 1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md diff --git a/1-js/06-advanced-functions/03-closure/1-counter-independent/task.md b/1-js/06-advanced-functions/03-closure/3-counter-independent/task.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/1-counter-independent/task.md rename to 1-js/06-advanced-functions/03-closure/3-counter-independent/task.md diff --git a/1-js/06-advanced-functions/03-closure/2-counter-object-independent/solution.md b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/2-counter-object-independent/solution.md rename to 1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md diff --git a/1-js/06-advanced-functions/03-closure/2-counter-object-independent/task.md b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/2-counter-object-independent/task.md rename to 1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md diff --git a/1-js/06-advanced-functions/03-closure/3-function-in-if/solution.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/3-function-in-if/solution.md rename to 1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md diff --git a/1-js/06-advanced-functions/03-closure/3-function-in-if/task.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/3-function-in-if/task.md rename to 1-js/06-advanced-functions/03-closure/5-function-in-if/task.md diff --git a/1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md b/1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md rename to 1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md diff --git a/1-js/06-advanced-functions/03-closure/4-closure-sum/task.md b/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/4-closure-sum/task.md rename to 1-js/06-advanced-functions/03-closure/6-closure-sum/task.md diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md new file mode 100644 index 000000000..346e4060a --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md @@ -0,0 +1,40 @@ +The result is: **error**. + +Try running it: + +```js run +let x = 1; + +function func() { +*!* + console.log(x); // ReferenceError: Cannot access 'x' before initialization +*/!* + let x = 2; +} + +func(); +``` + +In this example we can observe the peculiar difference between a "non-existing" and "uninitialized" variable. + +As you may have read in the article [](info:closure), a variable starts in the "uninitialized" state from the moment when the execution enters a code block (or a function). And it stays uninitalized until the corresponding `let` statement. + +In other words, a variable technically exists, but can't be used before `let`. + +The code above demonstrates it. + +```js +function func() { +*!* + // the local variable x is known to the engine from the beginning of the function, + // but "unitialized" (unusable) until let ("dead zone") + // hence the error +*/!* + + console.log(x); // ReferenceError: Cannot access 'x' before initialization + + let x = 2; +} +``` + +This zone of temporary unusability of a variable (from the beginning of the code block till `let`) is sometimes called the "dead zone". diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/task.md b/1-js/06-advanced-functions/03-closure/7-let-scope/task.md new file mode 100644 index 000000000..fb7445e66 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/task.md @@ -0,0 +1,21 @@ +importance: 4 + +--- + +# Is variable visible? + +What will be the result of this code? + +```js +let x = 1; + +function func() { + console.log(x); // ? + + let x = 2; +} + +func(); +``` + +P.S. There's a pitfall in this task. The solution is not obvious. diff --git a/1-js/06-advanced-functions/03-closure/7-sort-by-field/solution.md b/1-js/06-advanced-functions/03-closure/7-sort-by-field/solution.md deleted file mode 100644 index bd57085ea..000000000 --- a/1-js/06-advanced-functions/03-closure/7-sort-by-field/solution.md +++ /dev/null @@ -1,22 +0,0 @@ - - -```js run -let users = [ - { name: "John", age: 20, surname: "Johnson" }, - { name: "Pete", age: 18, surname: "Peterson" }, - { name: "Ann", age: 19, surname: "Hathaway" } -]; - -*!* -function byField(field) { - return (a, b) => a[field] > b[field] ? 1 : -1; -} -*/!* - -users.sort(byField('name')); -users.forEach(user => alert(user.name)); // Ann, John, Pete - -users.sort(byField('age')); -users.forEach(user => alert(user.name)); // Pete, Ann, John -``` - diff --git a/1-js/06-advanced-functions/03-closure/6-filter-through-function/_js.view/solution.js b/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/solution.js similarity index 100% rename from 1-js/06-advanced-functions/03-closure/6-filter-through-function/_js.view/solution.js rename to 1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/solution.js diff --git a/1-js/06-advanced-functions/03-closure/6-filter-through-function/_js.view/source.js b/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js similarity index 100% rename from 1-js/06-advanced-functions/03-closure/6-filter-through-function/_js.view/source.js rename to 1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js diff --git a/1-js/06-advanced-functions/03-closure/6-filter-through-function/_js.view/test.js b/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/test.js similarity index 100% rename from 1-js/06-advanced-functions/03-closure/6-filter-through-function/_js.view/test.js rename to 1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/test.js diff --git a/1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md b/1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md rename to 1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md diff --git a/1-js/06-advanced-functions/03-closure/6-filter-through-function/task.md b/1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/6-filter-through-function/task.md rename to 1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/solution.md b/1-js/06-advanced-functions/03-closure/8-make-army/solution.md deleted file mode 100644 index 0fb0b4a49..000000000 --- a/1-js/06-advanced-functions/03-closure/8-make-army/solution.md +++ /dev/null @@ -1,120 +0,0 @@ - -Let's examine what's done inside `makeArmy`, and the solution will become obvious. - -1. It creates an empty array `shooters`: - - ```js - let shooters = []; - ``` -2. Fills it in the loop via `shooters.push(function...)`. - - Every element is a function, so the resulting array looks like this: - - ```js no-beautify - shooters = [ - function () { alert(i); }, - function () { alert(i); }, - function () { alert(i); }, - function () { alert(i); }, - function () { alert(i); }, - function () { alert(i); }, - function () { alert(i); }, - function () { alert(i); }, - function () { alert(i); }, - function () { alert(i); } - ]; - ``` - -3. The array is returned from the function. - -Then, later, the call to `army[5]()` will get the element `army[5]` from the array (it will be a function) and call it. - -Now why all such functions show the same? - -That's because there's no local variable `i` inside `shooter` functions. When such a function is called, it takes `i` from its outer lexical environment. - -What will be the value of `i`? - -If we look at the source: - -```js -function makeArmy() { - ... - let i = 0; - while (i < 10) { - let shooter = function() { // shooter function - alert( i ); // should show its number - }; - ... - } - ... -} -``` - -...We can see that it lives in the lexical environment associated with the current `makeArmy()` run. But when `army[5]()` is called, `makeArmy` has already finished its job, and `i` has the last value: `10` (the end of `while`). - -As a result, all `shooter` functions get from the outer lexical envrironment the same, last value `i=10`. - -We can fix it by moving the variable definition into the loop: - -```js run demo -function makeArmy() { - - let shooters = []; - -*!* - for(let i = 0; i < 10; i++) { -*/!* - let shooter = function() { // shooter function - alert( i ); // should show its number - }; - shooters.push(shooter); - } - - return shooters; -} - -let army = makeArmy(); - -army[0](); // 0 -army[5](); // 5 -``` - -Now it works correctly, because every time the code block in `for (let i=0...) {...}` is executed, a new Lexical Environment is created for it, with the corresponding variable `i`. - -So, the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds the current loop iteration. That's why now it works. - -![](lexenv-makearmy.svg) - -Here we rewrote `while` into `for`. - -Another trick could be possible, let's see it for better understanding of the subject: - -```js run -function makeArmy() { - let shooters = []; - - let i = 0; - while (i < 10) { -*!* - let j = i; -*/!* - let shooter = function() { // shooter function - alert( *!*j*/!* ); // should show its number - }; - shooters.push(shooter); - i++; - } - - return shooters; -} - -let army = makeArmy(); - -army[0](); // 0 -army[5](); // 5 -``` - -The `while` loop, just like `for`, makes a new Lexical Environment for each run. So here we make sure that it gets the right value for a `shooter`. - -We copy `let j = i`. This makes a loop body local `j` and copies the value of `i` to it. Primitives are copied "by value", so we actually get a complete independent copy of `i`, belonging to the current loop iteration. diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/task.md b/1-js/06-advanced-functions/03-closure/8-make-army/task.md deleted file mode 100644 index ede8fd045..000000000 --- a/1-js/06-advanced-functions/03-closure/8-make-army/task.md +++ /dev/null @@ -1,35 +0,0 @@ -importance: 5 - ---- - -# Army of functions - -The following code creates an array of `shooters`. - -Every function is meant to output its number. But something is wrong... - -```js run -function makeArmy() { - let shooters = []; - - let i = 0; - while (i < 10) { - let shooter = function() { // shooter function - alert( i ); // should show its number - }; - shooters.push(shooter); - i++; - } - - return shooters; -} - -let army = makeArmy(); - -army[0](); // the shooter number 0 shows 10 -army[5](); // and number 5 also outputs 10... -// ... all shooters show 10 instead of their 0, 1, 2, 3... -``` - -Why all shooters show the same? Fix the code so that they work as intended. - diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/solution.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/solution.js new file mode 100644 index 000000000..8a71c869d --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/solution.js @@ -0,0 +1,3 @@ +function byField(fieldName){ + return (a, b) => a[fieldName] > b[fieldName] ? 1 : -1; +} diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js new file mode 100644 index 000000000..23b433834 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js @@ -0,0 +1,5 @@ +function byField(fieldName){ + + // Your code goes here. + +} diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js new file mode 100644 index 000000000..e3c335e03 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js @@ -0,0 +1,39 @@ +describe("byField", function(){ + + let users = [ + { name: "John", age: 20, surname: "Johnson" }, + { name: "Pete", age: 18, surname: "Peterson" }, + { name: "Ann", age: 19, surname: "Hathaway" }, + ]; + + it("sorts users by name", function(){ + let nameSortedKey = [ + { name: "Ann", age: 19, surname: "Hathaway" }, + { name: "John", age: 20, surname: "Johnson"}, + { name: "Pete", age: 18, surname: "Peterson" }, + ]; + let nameSortedAnswer = users.sort(byField("name")); + assert.deepEqual(nameSortedKey, nameSortedAnswer); + }); + + it("sorts users by age", function(){ + let ageSortedKey = [ + { name: "Pete", age: 18, surname: "Peterson" }, + { name: "Ann", age: 19, surname: "Hathaway" }, + { name: "John", age: 20, surname: "Johnson"}, + ]; + let ageSortedAnswer = users.sort(byField("age")); + assert.deepEqual(ageSortedKey, ageSortedKey); + }); + + it("sorts users by surname", function(){ + let surnameSortedKey = [ + { name: "Ann", age: 19, surname: "Hathaway" }, + { name: "John", age: 20, surname: "Johnson"}, + { name: "Pete", age: 18, surname: "Peterson" }, + ]; + let surnameSortedAnswer = users.sort(byField("surname")); + assert.deepEqual(surnameSortedAnswer, surnameSortedKey); + }); + +}); diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/solution.md b/1-js/06-advanced-functions/03-closure/9-sort-by-field/solution.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/solution.md @@ -0,0 +1 @@ + diff --git a/1-js/06-advanced-functions/03-closure/7-sort-by-field/task.md b/1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md similarity index 100% rename from 1-js/06-advanced-functions/03-closure/7-sort-by-field/task.md rename to 1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index e771b1cc4..3a6a7e4e5 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -1,203 +1,102 @@ -# Closure +# Variable scope, closure -JavaScript is a very function-oriented language. It gives us a lot of freedom. A function can be created at one moment, then copied to another variable or passed as an argument to another function and called from a totally different place later. +JavaScript is a very function-oriented language. It gives us a lot of freedom. A function can be created at any moment, passed as an argument to another function, and then called from a totally different place of code later. -We know that a function can access variables outside of it; this feature is used quite often. +We already know that a function can access variables outside of it ("outer" variables). -But what happens when an outer variable changes? Does a function get the most recent value or the one that existed when the function was created? +But what happens if outer variables change since a function is created? Will the function get newer values or the old ones? -Also, what happens when a function travels to another place in the code and is called from there -- does it get access to the outer variables of the new place? +And what if a function is passed along as a parameter and called from another place of code, will it get access to outer variables at the new place? -Different languages behave differently here, and in this chapter we cover the behaviour of JavaScript. +Let's expand our knowledge to understand these scenarios and more complex ones. -## A couple of questions +```smart header="We'll talk about `let/const` variables here" +In JavaScript, there are 3 ways to declare a variable: `let`, `const` (the modern ones), and `var` (the remnant of the past). -Let's consider two situations to begin with, and then study the internal mechanics piece-by-piece, so that you'll be able to answer the following questions and more complex ones in the future. - -1. The function `sayHi` uses an external variable `name`. When the function runs, which value is it going to use? - - ```js - let name = "John"; - - function sayHi() { - alert("Hi, " + name); - } - - name = "Pete"; - - *!* - sayHi(); // what will it show: "John" or "Pete"? - */!* - ``` - - Such situations are common both in browser and server-side development. A function may be scheduled to execute later than it is created, for instance after a user action or a network request. - - So, the question is: does it pick up the latest changes? - - -2. The function `makeWorker` makes another function and returns it. That new function can be called from somewhere else. Will it have access to the outer variables from its creation place, or the invocation place, or both? - - ```js - function makeWorker() { - let name = "Pete"; - - return function() { - alert(name); - }; - } - - let name = "John"; - - // create a function - let work = makeWorker(); - - // call it - *!* - work(); // what will it show? "Pete" (name where created) or "John" (name where called)? - */!* - ``` - - -## Lexical Environment - -To understand what's going on, let's first discuss what a "variable" actually is. - -In JavaScript, every running function, code block, and the script as a whole have an associated object known as the *Lexical Environment*. - -The Lexical Environment object consists of two parts: - -1. *Environment Record* -- an object that has all local variables as its properties (and some other information like the value of `this`). -2. A reference to the *outer lexical environment*, usually the one associated with the code lexically right outside of it (outside of the current curly brackets). - -**So, a "variable" is just a property of the special internal object, Environment Record. "To get or change a variable" means "to get or change a property of that object".** - -For instance, in this simple code, there is only one Lexical Environment: - -![lexical environment](lexical-environment-global.svg) - -This is a so-called global Lexical Environment, associated with the whole script. For browsers, all ` + +Function handler is called on this input: +
+ + +

+ +Debounced function debounce(handler, 1000) is called on this input: +
+ + +

+ + + \ No newline at end of file diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md index 4f5867ded..83e75f315 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md @@ -1,28 +1,13 @@ ```js demo -function debounce(f, ms) { - - let isCooldown = false; - +function debounce(func, ms) { + let timeout; return function() { - if (isCooldown) return; - - f.apply(this, arguments); - - isCooldown = true; - - setTimeout(() => isCooldown = false, ms); + clearTimeout(timeout); + timeout = setTimeout(() => func.apply(this, arguments), ms); }; - } -``` - -A call to `debounce` returns a wrapper. There may be two states: -- `isCooldown = false` -- ready to run. -- `isCooldown = true` -- waiting for the timeout. - -In the first call `isCooldown` is falsy, so the call proceeds, and the state changes to `true`. +``` -While `isCooldown` is true, all other calls are ignored. +A call to `debounce` returns a wrapper. When called, it schedules the original function call after given `ms` and cancels the previous such timeout. -Then `setTimeout` reverts it to `false` after the given delay. diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 466c6bc3f..5b0fcc5f8 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -4,21 +4,48 @@ importance: 5 # Debounce decorator -The result of `debounce(f, ms)` decorator should be a wrapper that passes the call to `f` at maximum once per `ms` milliseconds. +The result of `debounce(f, ms)` decorator is a wrapper that suspends calls to `f` until there's `ms` milliseconds of inactivity (no calls, "cooldown period"), then invokes `f` once with the latest arguments. -In other words, when we call a "debounced" function, it guarantees that all other future in the closest `ms` milliseconds will be ignored. +In other words, `debounce` is like a secretary that accepts "phone calls", and waits until there's `ms` milliseconds of being quiet. And only then it transfers the latest call information to "the boss" (calls the actual `f`). -For instance: +For instance, we had a function `f` and replaced it with `f = debounce(f, 1000)`. -```js no-beautify -let f = debounce(alert, 1000); +Then if the wrapped function is called at 0ms, 200ms and 500ms, and then there are no calls, then the actual `f` will be only called once, at 1500ms. That is: after the cooldown period of 1000ms from the last call. -f(1); // runs immediately -f(2); // ignored +![](debounce.svg) -setTimeout( () => f(3), 100); // ignored ( only 100 ms passed ) -setTimeout( () => f(4), 1100); // runs -setTimeout( () => f(5), 1500); // ignored (less than 1000 ms from the last run) +...And it will get the arguments of the very last call, other calls are ignored. + +Here's the code for it (uses the debounce decorator from the [Lodash library](https://lodash.com/docs/4.17.15#debounce)): + +```js +let f = _.debounce(alert, 1000); + +f("a"); +setTimeout( () => f("b"), 200); +setTimeout( () => f("c"), 500); +// debounced function waits 1000ms after the last call and then runs: alert("c") +``` + +Now a practical example. Let's say, the user types something, and we'd like to send a request to the server when the input is finished. + +There's no point in sending the request for every character typed. Instead we'd like to wait, and then process the whole result. + +In a web-browser, we can setup an event handler -- a function that's called on every change of an input field. Normally, an event handler is called very often, for every typed key. But if we `debounce` it by 1000ms, then it will be only called once, after 1000ms after the last input. + +```online + +In this live example, the handler puts the result into a box below, try it: + +[iframe border=1 src="debounce" height=200] + +See? The second input calls the debounced function, so its content is processed after 1000ms from the last input. ``` -In practice `debounce` is useful for functions that retrieve/update something when we know that nothing new can be done in such a short period of time, so it's better not to waste resources. \ No newline at end of file +So, `debounce` is a great way to process a sequence of events: be it a sequence of key presses, mouse movements or something else. + +It waits the given time after the last call, and then runs its function, that can process the result. + +The task is to implement `debounce` decorator. + +Hint: that's just a few lines if you think about it :) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js index 5339c8d11..e671438f6 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js @@ -7,8 +7,8 @@ describe("throttle(f, 1000)", function() { } before(function() { - f1000 = throttle(f, 1000); this.clock = sinon.useFakeTimers(); + f1000 = throttle(f, 1000); }); it("the first call runs now", function() { @@ -44,4 +44,20 @@ describe("throttle(f, 1000)", function() { this.clock.restore(); }); -}); \ No newline at end of file +}); + +describe('throttle', () => { + + it('runs a forwarded call once', done => { + let log = ''; + const f = str => log += str; + const f10 = throttle(f, 10); + f10('once'); + + setTimeout(() => { + assert.equal(log, 'once'); + done(); + }, 20); + }); + +}); diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md index c844016d3..cf851f771 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md @@ -33,7 +33,7 @@ function throttle(func, ms) { A call to `throttle(func, ms)` returns `wrapper`. 1. During the first call, the `wrapper` just runs `func` and sets the cooldown state (`isThrottled = true`). -2. In this state all calls memorized in `savedArgs/savedThis`. Please note that both the context and the arguments are equally important and should be memorized. We need them simultaneously to reproduce the call. -3. ...Then after `ms` milliseconds pass, `setTimeout` triggers. The cooldown state is removed (`isThrottled = false`). And if we had ignored calls, then `wrapper` is executed with last memorized arguments and context. +2. In this state all calls are memorized in `savedArgs/savedThis`. Please note that both the context and the arguments are equally important and should be memorized. We need them simultaneously to reproduce the call. +3. After `ms` milliseconds pass, `setTimeout` triggers. The cooldown state is removed (`isThrottled = false`) and, if we had ignored calls, `wrapper` is executed with the last memorized arguments and context. The 3rd step runs not `func`, but `wrapper`, because we not only need to execute `func`, but once again enter the cooldown state and setup the timeout to reset it. diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index 716b4e1d6..43136dcb5 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -4,17 +4,22 @@ importance: 5 # Throttle decorator -Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper, passing the call to `f` at maximum once per `ms` milliseconds. Those calls that fall into the "cooldown" period, are ignored. +Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper. -**The difference with `debounce` -- if an ignored call is the last during the cooldown, then it executes at the end of the delay.** +When it's called multiple times, it passes the call to `f` at maximum once per `ms` milliseconds. + +The difference with debounce is that it's completely different decorator: +- `debounce` runs the function once after the "cooldown" period. Good for processing the final result. +- `throttle` runs it not more often than given `ms` time. Good for regular updates that shouldn't be very often. + +In other words, `throttle` is like a secretary that accepts phone calls, but bothers the boss (calls the actual `f`) not more often than once per `ms` milliseconds. Let's check the real-life application to better understand that requirement and to see where it comes from. **For instance, we want to track mouse movements.** -In browser we can setup a function to run at every mouse micro-movement and get the pointer location as it moves. During an active mouse usage, this function usually runs very frequently, can be something like 100 times per second (every 10 ms). - -**The tracking function should update some information on the web-page.** +In a browser we can setup a function to run at every mouse movement and get the pointer location as it moves. During an active mouse usage, this function usually runs very frequently, can be something like 100 times per second (every 10 ms). +**We'd like to update some information on the web-page when the pointer moves.** Updating function `update()` is too heavy to do it on every micro-movement. There is also no sense in making it more often than once per 100ms. @@ -31,8 +36,8 @@ A code example: ```js function f(a) { - console.log(a) -}; + console.log(a); +} // f1000 passes calls to f at maximum once per 1000 ms let f1000 = throttle(f, 1000); diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/article.md b/1-js/06-advanced-functions/09-call-apply-decorators/article.md index f2182b6fd..5438d4672 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/article.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/article.md @@ -60,10 +60,9 @@ As we can see, the wrapper returns the result of `func(x)` "as is". From an outs To summarize, there are several benefits of using a separate `cachingDecorator` instead of altering the code of `slow` itself: - The `cachingDecorator` is reusable. We can apply it to another function. -- The caching logic is separate, it did not increase the complexity of `slow` itself (if there were any). +- The caching logic is separate, it did not increase the complexity of `slow` itself (if there was any). - We can combine multiple decorators if needed (other decorators will follow). - ## Using "func.call" for the context The caching decorator mentioned above is not suited to work with object methods. @@ -78,7 +77,7 @@ let worker = { }, slow(x) { - // actually, there can be a scary CPU-heavy task here + // scary CPU-heavy task here alert("Called with " + x); return x * this.someMethod(); // (*) } @@ -152,8 +151,8 @@ let user = { name: "John" }; let admin = { name: "Admin" }; // use call to pass different objects as "this" -sayHi.call( user ); // this = John -sayHi.call( admin ); // this = Admin +sayHi.call( user ); // John +sayHi.call( admin ); // Admin ``` And here we use `call` to call `say` with the given context and phrase: @@ -170,10 +169,8 @@ let user = { name: "John" }; say.call( user, "Hello" ); // John: Hello ``` - In our case, we can use `call` in the wrapper to pass the context to the original function: - ```js run let worker = { someMethod() { @@ -214,7 +211,7 @@ To make it all clear, let's see more deeply how `this` is passed along: 2. So when `worker.slow(2)` is executed, the wrapper gets `2` as an argument and `this=worker` (it's the object before dot). 3. Inside the wrapper, assuming the result is not yet cached, `func.call(this, x)` passes the current `this` (`=worker`) and the current argument (`=2`) to the original method. -## Going multi-argument with "func.apply" +## Going multi-argument Now let's make `cachingDecorator` even more universal. Till now it was working only with single-argument functions. @@ -244,80 +241,7 @@ There are many solutions possible: For many practical applications, the 3rd variant is good enough, so we'll stick to it. -The second task to solve is how to pass many arguments to `func`. Currently, the wrapper `function(x)` assumes a single argument, and `func.call(this, x)` passes it. - -Here we can use another built-in method [func.apply](mdn:js/Function/apply). - -The syntax is: - -```js -func.apply(context, args) -``` - -It runs the `func` setting `this=context` and using an array-like object `args` as the list of arguments. - - -For instance, these two calls are almost the same: - -```js -func(1, 2, 3); -func.apply(context, [1, 2, 3]) -``` - -Both run `func` giving it arguments `1,2,3`. But `apply` also sets `this=context`. - -For instance, here `say` is called with `this=user` and `messageData` as a list of arguments: - -```js run -function say(time, phrase) { - alert(`[${time}] ${this.name}: ${phrase}`); -} - -let user = { name: "John" }; - -let messageData = ['10:00', 'Hello']; // become time and phrase - -*!* -// user becomes this, messageData is passed as a list of arguments (time, phrase) -say.apply(user, messageData); // [10:00] John: Hello (this=user) -*/!* -``` - -The only syntax difference between `call` and `apply` is that `call` expects a list of arguments, while `apply` takes an array-like object with them. - -We already know the spread operator `...` from the chapter that can pass an array (or any iterable) as a list of arguments. So if we use it with `call`, we can achieve almost the same as `apply`. - -These two calls are almost equivalent: - -```js -let args = [1, 2, 3]; - -*!* -func.call(context, ...args); // pass an array as list with spread operator -func.apply(context, args); // is same as using apply -*/!* -``` - -If we look more closely, there's a minor difference between such uses of `call` and `apply`. - -- The spread operator `...` allows to pass *iterable* `args` as the list to `call`. -- The `apply` accepts only *array-like* `args`. - -So, these calls complement each other. Where we expect an iterable, `call` works, where we expect an array-like, `apply` works. - -And if `args` is both iterable and array-like, like a real array, then we technically could use any of them, but `apply` will probably be faster, because it's a single operation. Most JavaScript engines internally optimize it better than a pair `call + spread`. - -One of the most important uses of `apply` is passing the call to another function, like this: - -```js -let wrapper = function() { - return anotherFunction.apply(this, arguments); -}; -``` - -That's called *call forwarding*. The `wrapper` passes everything it gets: the context `this` and arguments to `anotherFunction` and returns back its result. - -When an external code calls such `wrapper`, it is indistinguishable from the call of the original function. +Also we need to pass not just `x`, but all arguments in `func.call`. Let's recall that in a `function()` we can get a pseudo-array of its arguments as `arguments`, so `func.call(this, x)` should be replaced with `func.call(this, ...arguments)`. Now let's bake it all into the more powerful `cachingDecorator`: @@ -358,13 +282,54 @@ alert( worker.slow(3, 5) ); // works alert( "Again " + worker.slow(3, 5) ); // same (cached) ``` -Now the wrapper operates with any number of arguments. +Now it works with any number of arguments (though the hash function would also need to be adjusted to allow any number of arguments. An interesting way to handle this will be covered below). There are two changes: - In the line `(*)` it calls `hash` to create a single key from `arguments`. Here we use a simple "joining" function that turns arguments `(3, 5)` into the key `"3,5"`. More complex cases may require other hashing functions. - Then `(**)` uses `func.apply` to pass both the context and all arguments the wrapper got (no matter how many) to the original function. +## func.apply + +Instead of `func.call(this, ...arguments)` we could use `func.apply(this, arguments)`. + +The syntax of built-in method [func.apply](mdn:js/Function/apply) is: + +```js +func.apply(context, args) +``` + +It runs the `func` setting `this=context` and using an array-like object `args` as the list of arguments. + +The only syntax difference between `call` and `apply` is that `call` expects a list of arguments, while `apply` takes an array-like object with them. + +So these two calls are almost equivalent: + +```js +func.call(context, ...args); // pass an array as list with spread syntax +func.apply(context, args); // is same as using call +``` + +There's only a subtle difference: + +- The spread syntax `...` allows to pass *iterable* `args` as the list to `call`. +- The `apply` accepts only *array-like* `args`. + +So, where we expect an iterable, `call` works, and where we expect an array-like, `apply` works. + +And for objects that are both iterable and array-like, like a real array, we can use any of them, but `apply` will probably be faster, because most JavaScript engines internally optimize it better. + +Passing all arguments along with the context to another function is called *call forwarding*. + +That's the simplest form of it: + +```js +let wrapper = function() { + return func.apply(this, arguments); +}; +``` + +When an external code calls such `wrapper`, it is indistinguishable from the call of the original function `func`. ## Borrowing a method [#method-borrowing] @@ -386,7 +351,7 @@ function hash(args) { } ``` -...Unfortunately, that won't work. Because we are calling `hash(arguments)` and `arguments` object is both iterable and array-like, but not a real array. +...Unfortunately, that won't work. Because we are calling `hash(arguments)`, and `arguments` object is both iterable and array-like, but not a real array. So calling `join` on it would fail, as we can see below: @@ -414,7 +379,7 @@ hash(1, 2); The trick is called *method borrowing*. -We take (borrow) a join method from a regular array `[].join`. And use `[].join.call` to run it in the context of `arguments`. +We take (borrow) a join method from a regular array (`[].join`) and use `[].join.call` to run it in the context of `arguments`. Why does it work? @@ -432,12 +397,20 @@ Taken from the specification almost "as-is": So, technically it takes `this` and joins `this[0]`, `this[1]` ...etc together. It's intentionally written in a way that allows any array-like `this` (not a coincidence, many methods follow this practice). That's why it also works with `this=arguments`. +## Decorators and function properties + +It is generally safe to replace a function or a method with a decorated one, except for one little thing. If the original function had properties on it, like `func.calledCount` or whatever, then the decorated one will not provide them. Because that is a wrapper. So one needs to be careful if one uses them. + +E.g. in the example above if `slow` function had any properties on it, then `cachingDecorator(slow)` is a wrapper without them. + +Some decorators may provide their own properties. E.g. a decorator may count how many times a function was invoked and how much time it took, and expose this information via wrapper properties. + +There exists a way to create decorators that keep access to function properties, but this requires using a special `Proxy` object to wrap a function. We'll discuss it later in the article . + ## Summary *Decorator* is a wrapper around a function that alters its behavior. The main job is still carried out by the function. -It is generally safe to replace a function or a method with a decorated one, except for one little thing. If the original function had properties on it, like `func.calledCount` or whatever, then the decorated one will not provide them. Because that is a wrapper. So one needs to be careful if one uses them. Some decorators provide their own properties. - Decorators can be seen as "features" or "aspects" that can be added to a function. We can add one or add many. And all this without changing its code! To implement `cachingDecorator`, we studied methods: diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/decorator-makecaching-wrapper.svg b/1-js/06-advanced-functions/09-call-apply-decorators/decorator-makecaching-wrapper.svg index 7092d120e..258fcfdfc 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/decorator-makecaching-wrapper.svg +++ b/1-js/06-advanced-functions/09-call-apply-decorators/decorator-makecaching-wrapper.svg @@ -1,64 +1 @@ - - - - decorator-makecaching-wrapper.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wrapper - - - around the function - - - - - \ No newline at end of file +wrapperaround the function \ No newline at end of file diff --git a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md index 8cd18ec56..d6cfb44bf 100644 --- a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md @@ -4,7 +4,7 @@ importance: 5 # Function property after bind -There's a value in the property of a function. Will it change after `bind`? Why, elaborate? +There's a value in the property of a function. Will it change after `bind`? Why, or why not? ```js run function sayHi() { diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index aed139c1c..7bca80ae9 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -83,10 +83,12 @@ let user = { setTimeout(() => user.sayHi(), 1000); -// ...within 1 second -user = { sayHi() { alert("Another user in setTimeout!"); } }; +// ...the value of user changes within 1 second +user = { + sayHi() { alert("Another user in setTimeout!"); } +}; -// Another user in setTimeout?!? +// Another user in setTimeout! ``` The next solution guarantees that such thing won't happen. @@ -98,7 +100,7 @@ Functions provide a built-in method [bind](mdn:js/Function/bind) that allows to The basic syntax is: ```js -// more complex syntax will be little later +// more complex syntax will come a little later let boundFunc = func.bind(context); ```` @@ -159,9 +161,16 @@ let user = { let sayHi = user.sayHi.bind(user); // (*) */!* +// can run it without an object sayHi(); // Hello, John! setTimeout(sayHi, 1000); // Hello, John! + +// even if the value of user changes within 1 second +// sayHi uses the pre-bound value which is reference to the old user object +user = { + sayHi() { alert("Another user in setTimeout!"); } +}; ``` In the line `(*)` we take the method `user.sayHi` and bind it to `user`. The `sayHi` is a "bound" function, that can be called alone or passed to `setTimeout` -- doesn't matter, the context will be right. @@ -193,9 +202,121 @@ for (let key in user) { } ``` -JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(obj)](http://lodash.com/docs#bindAll) in lodash. +JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll) in lodash. ```` +## Partial functions + +Until now we have only been talking about binding `this`. Let's take it a step further. + +We can bind not only `this`, but also arguments. That's rarely done, but sometimes can be handy. + +The full syntax of `bind`: + +```js +let bound = func.bind(context, [arg1], [arg2], ...); +``` + +It allows to bind context as `this` and starting arguments of the function. + +For instance, we have a multiplication function `mul(a, b)`: + +```js +function mul(a, b) { + return a * b; +} +``` + +Let's use `bind` to create a function `double` on its base: + +```js run +function mul(a, b) { + return a * b; +} + +*!* +let double = mul.bind(null, 2); +*/!* + +alert( double(3) ); // = mul(2, 3) = 6 +alert( double(4) ); // = mul(2, 4) = 8 +alert( double(5) ); // = mul(2, 5) = 10 +``` + +The call to `mul.bind(null, 2)` creates a new function `double` that passes calls to `mul`, fixing `null` as the context and `2` as the first argument. Further arguments are passed "as is". + +That's called [partial function application](https://en.wikipedia.org/wiki/Partial_application) -- we create a new function by fixing some parameters of the existing one. + +Please note that here we actually don't use `this` here. But `bind` requires it, so we must put in something like `null`. + +The function `triple` in the code below triples the value: + +```js run +function mul(a, b) { + return a * b; +} + +*!* +let triple = mul.bind(null, 3); +*/!* + +alert( triple(3) ); // = mul(3, 3) = 9 +alert( triple(4) ); // = mul(3, 4) = 12 +alert( triple(5) ); // = mul(3, 5) = 15 +``` + +Why do we usually make a partial function? + +The benefit is that we can create an independent function with a readable name (`double`, `triple`). We can use it and not provide the first argument every time as it's fixed with `bind`. + +In other cases, partial application is useful when we have a very generic function and want a less universal variant of it for convenience. + +For instance, we have a function `send(from, to, text)`. Then, inside a `user` object we may want to use a partial variant of it: `sendTo(to, text)` that sends from the current user. + +## Going partial without context + +What if we'd like to fix some arguments, but not the context `this`? For example, for an object method. + +The native `bind` does not allow that. We can't just omit the context and jump to arguments. + +Fortunately, a function `partial` for binding only arguments can be easily implemented. + +Like this: + +```js run +*!* +function partial(func, ...argsBound) { + return function(...args) { // (*) + return func.call(this, ...argsBound, ...args); + } +} +*/!* + +// Usage: +let user = { + firstName: "John", + say(time, phrase) { + alert(`[${time}] ${this.firstName}: ${phrase}!`); + } +}; + +// add a partial method with fixed time +user.sayNow = partial(user.say, new Date().getHours() + ':' + new Date().getMinutes()); + +user.sayNow("Hello"); +// Something like: +// [10:00] John: Hello! +``` + +The result of `partial(func[, arg1, arg2...])` call is a wrapper `(*)` that calls `func` with: +- Same `this` as it gets (for `user.sayNow` call it's `user`) +- Then gives it `...argsBound` -- arguments from the `partial` call (`"10:00"`) +- Then gives it `...args` -- arguments given to the wrapper (`"Hello"`) + +So easy to do it with the spread syntax, right? + +Also there's a ready [_.partial](https://lodash.com/docs#partial) implementation from lodash library. + ## Summary Method `func.bind(context, ...args)` returns a "bound variant" of function `func` that fixes the context `this` and first arguments if given. diff --git a/1-js/06-advanced-functions/11-currying-partials/1-ask-currying/task.md b/1-js/06-advanced-functions/11-currying-partials/1-ask-currying/task.md index f8b83d7a2..c90851c2b 100644 --- a/1-js/06-advanced-functions/11-currying-partials/1-ask-currying/task.md +++ b/1-js/06-advanced-functions/11-currying-partials/1-ask-currying/task.md @@ -8,7 +8,7 @@ The task is a little more complex variant of . The `user` object was modified. Now instead of two functions `loginOk/loginFail`, it has a single function `user.login(true/false)`. -What to pass `askPassword` in the code below, so that it calls `user.login(true)` as `ok` and `user.login(false)` as `fail`? +What should we pass `askPassword` in the code below, so that it calls `user.login(true)` as `ok` and `user.login(false)` as `fail`? ```js function askPassword(ok, fail) { diff --git a/1-js/06-advanced-functions/12-arrow-functions/article.md b/1-js/06-advanced-functions/12-arrow-functions/article.md index 5659719dd..c4e8d43fc 100644 --- a/1-js/06-advanced-functions/12-arrow-functions/article.md +++ b/1-js/06-advanced-functions/12-arrow-functions/article.md @@ -118,7 +118,6 @@ Aqui precisamos criar as variáveis adicionais `args` e `ctx` para que a funçã *Arrow functions* (funções seta): -- Não possuem `this`. - Não possuem `arguments`. - Não podem ser chamadas com `new`. - (Elas também não possuem `super`, mas ainda não a estudamos. Veremos no capítulo ). diff --git a/1-js/07-object-properties/01-property-descriptors/article.md b/1-js/07-object-properties/01-property-descriptors/article.md index 7768b3557..edf3e260f 100644 --- a/1-js/07-object-properties/01-property-descriptors/article.md +++ b/1-js/07-object-properties/01-property-descriptors/article.md @@ -3,7 +3,7 @@ As we know, objects can store properties. -Till now, a property was a simple "key-value" pair to us. But an object property is actually a more flexible and powerful thing. +Until now, a property was a simple "key-value" pair to us. But an object property is actually a more flexible and powerful thing. In this chapter we'll study additional configuration options, and in the next we'll see how to invisibly turn them into getter/setter functions. @@ -11,7 +11,7 @@ In this chapter we'll study additional configuration options, and in the next we Object properties, besides a **`value`**, have three special attributes (so-called "flags"): -- **`writable`** -- if `true`, can be changed, otherwise it's read-only. +- **`writable`** -- if `true`, the value can be changed, otherwise it's read-only. - **`enumerable`** -- if `true`, then listed in loops, otherwise not listed. - **`configurable`** -- if `true`, the property can be deleted and these attributes can be modified, otherwise not. @@ -66,7 +66,7 @@ Object.defineProperty(obj, propertyName, descriptor) : The object and property to work on. `descriptor` -: Property descriptor to apply. +: Property descriptor object to apply. If the property exists, `defineProperty` updates its flags. Otherwise, it creates the property with the given value and flags; in that case, if a flag is not supplied, it is assumed `false`. @@ -100,9 +100,9 @@ Compare it with "normally created" `user.name` above: now all flags are falsy. I Now let's see effects of the flags by example. -## Read-only +## Non-writable -Let's make `user.name` read-only by changing `writable` flag: +Let's make `user.name` non-writable (can't be reassigned) by changing `writable` flag: ```js run let user = { @@ -122,15 +122,19 @@ user.name = "Pete"; // Error: Cannot assign to read only property 'name'... Now no one can change the name of our user, unless they apply their own `defineProperty` to override ours. -Here's the same operation, but for the case when a property doesn't exist: +```smart header="Errors appear only in strict mode" +In the non-strict mode, no errors occur when writing to non-writable properties and such. But the operation still won't succeed. Flag-violating actions are just silently ignored in non-strict. +``` + +Here's the same example, but the property is created from scratch: ```js run let user = { }; Object.defineProperty(user, "name", { *!* - value: "Pete", - // for new properties need to explicitly list what's true + value: "John", + // for new properties we need to explicitly list what's true enumerable: true, configurable: true */!* @@ -145,7 +149,7 @@ user.name = "Alice"; // Error Now let's add a custom `toString` to `user`. -Normally, a built-in `toString` for objects is non-enumerable, it does not show up in `for..in`. But if we add `toString` of our own, then by default it shows up in `for..in`, like this: +Normally, a built-in `toString` for objects is non-enumerable, it does not show up in `for..in`. But if we add a `toString` of our own, then by default it shows up in `for..in`, like this: ```js run let user = { @@ -159,7 +163,7 @@ let user = { for (let key in user) alert(key); // name, toString ``` -If we don't like it, then we can set `enumerable:false`. Then it won't appear in `for..in` loop, just like the built-in one: +If we don't like it, then we can set `enumerable:false`. Then it won't appear in a `for..in` loop, just like the built-in one: ```js run let user = { @@ -191,9 +195,9 @@ alert(Object.keys(user)); // name The non-configurable flag (`configurable:false`) is sometimes preset for built-in objects and properties. -A non-configurable property can not be deleted or altered with `defineProperty`. +A non-configurable property can not be deleted. -For instance, `Math.PI` is read-only, non-enumerable and non-configurable: +For instance, `Math.PI` is non-writable, non-enumerable and non-configurable: ```js run let descriptor = Object.getOwnPropertyDescriptor(Math, 'PI'); @@ -216,32 +220,50 @@ Math.PI = 3; // Error // delete Math.PI won't work either ``` -Making a property non-configurable is a one-way road. We cannot change it back, because `defineProperty` doesn't work on non-configurable properties. +Making a property non-configurable is a one-way road. We cannot change it back with `defineProperty`. + +To be precise, non-configurability imposes several restrictions on `defineProperty`: +1. Can't change `configurable` flag. +2. Can't change `enumerable` flag. +3. Can't change `writable: false` to `true` (the other way round works). +4. Can't change `get/set` for an accessor property (but can assign them if absent). -Here we are making `user.name` a "forever sealed" constant: +**The idea of "configurable: false" is to prevent changes of property flags and its deletion, while allowing to change its value.** + +Here `user.name` is non-configurable, but we can still change it (as it's writable): ```js run -let user = { }; +let user = { + name: "John" +}; + +Object.defineProperty(user, "name", { + configurable: false +}); + +user.name = "Pete"; // works fine +delete user.name; // Error +``` + +And here we make `user.name` a "forever sealed" constant: + +```js run +let user = { + name: "John" +}; Object.defineProperty(user, "name", { - value: "John", writable: false, configurable: false }); -*!* // won't be able to change user.name or its flags // all this won't work: -// user.name = "Pete" -// delete user.name -// defineProperty(user, "name", ...) -Object.defineProperty(user, "name", {writable: true}); // Error -*/!* +user.name = "Pete"; +delete user.name; +Object.defineProperty(user, "name", { value: "Pete" }); ``` -```smart header="Errors appear only in use strict" -In the non-strict mode, no errors occur when writing to read-only properties and such. But the operation still won't succeed. Flag-violating actions are just silently ignored in non-strict. -``` ## Object.defineProperties @@ -305,6 +327,7 @@ There are also methods that limit access to the *whole* object: [Object.freeze(obj)](mdn:js/Object/freeze) : Forbids adding/removing/changing of properties. Sets `configurable: false, writable: false` for all existing properties. + And also there are tests for them: [Object.isExtensible(obj)](mdn:js/Object/isExtensible) diff --git a/1-js/07-object-properties/02-property-accessors/article.md b/1-js/07-object-properties/02-property-accessors/article.md index 43cd5ae6d..047023efe 100644 --- a/1-js/07-object-properties/02-property-accessors/article.md +++ b/1-js/07-object-properties/02-property-accessors/article.md @@ -1,11 +1,11 @@ # Property getters and setters -There are two kinds of properties. +There are two kinds of object properties. -The first kind is *data properties*. We already know how to work with them. Actually, all properties that we've been using till now were data properties. +The first kind is *data properties*. We already know how to work with them. All properties that we've been using until now were data properties. -The second type of properties is something new. It's *accessor properties*. They are essentially functions that work on getting and setting a value, but look like regular properties to an external code. +The second type of properties is something new. It's *accessor properties*. They are essentially functions that execute on getting and setting a value, but look like regular properties to an external code. ## Getters and setters @@ -27,7 +27,7 @@ The getter works when `obj.propName` is read, the setter -- when it is assigned. For instance, we have a `user` object with `name` and `surname`: -```js run +```js let user = { name: "John", surname: "Smith" @@ -53,7 +53,7 @@ alert(user.fullName); // John Smith */!* ``` -From outside, an accessor property looks like a regular one. That's the idea of accessor properties. We don't *call* `user.fullName` as a function, we *read* it normally: the getter runs behind the scenes. +From the outside, an accessor property looks like a regular one. That's the idea of accessor properties. We don't *call* `user.fullName` as a function, we *read* it normally: the getter runs behind the scenes. As of now, `fullName` has only a getter. If we attempt to assign `user.fullName=`, there will be an error. @@ -82,23 +82,13 @@ alert(user.name); // Alice alert(user.surname); // Cooper ``` -Now we have a "virtual" property. It is readable and writable, but in fact does not exist. - -```smart header="Accessor properties are only accessible with get/set" -Once a property is defined with `get prop()` or `set prop()`, it's an accessor property, not a data properety any more. - -- If there's a getter -- we can read `object.prop`, othrewise we can't. -- If there's a setter -- we can set `object.prop=...`, othrewise we can't. - -And in either case we can't `delete` an accessor property. -``` - +As the result, we have a "virtual" property `fullName`. It is readable and writable. ## Accessor descriptors -Descriptors for accessor properties are different -- as compared with data properties. +Descriptors for accessor properties are different from those for data properties. -For accessor properties, there is no `value` and `writable`, but instead there are `get` and `set` functions. +For accessor properties, there is no `value` or `writable`, but instead there are `get` and `set` functions. So an accessor descriptor may have: @@ -132,7 +122,7 @@ alert(user.fullName); // John Smith for(let key in user) alert(key); // name, surname ``` -Please note once again that a property can be either an accessor or a data property, not both. +Please note that a property can be either an accessor (has `get/set` methods) or a data property (has a `value`), not both. If we try to supply both `get` and `value` in the same descriptor, there will be an error: @@ -181,9 +171,9 @@ Technically, the external code may still access the name directly by using `user ## Using for compatibility -One of the great ideas behind getters and setters -- they allow to take control over a "normal" data property and tweak it at any moment. +One of the great uses of accessors is that they allow to take control over a "regular" data property at any moment by replacing it with a getter and a setter and tweak its behavior. -For instance, we started implementing user objects using data properties `name` and `age`: +Imagine we started implementing user objects using data properties `name` and `age`: ```js function User(name, age) { diff --git a/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/task.md b/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/task.md index 002b24b8a..bc2db47fe 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/task.md +++ b/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/task.md @@ -6,7 +6,7 @@ importance: 5 The task has two parts. -We have an object: +Given the following objects: ```js let head = { diff --git a/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/task.md b/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/task.md index b37499bad..ed8482c07 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/task.md +++ b/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/task.md @@ -2,7 +2,7 @@ importance: 5 --- -# Where it writes? +# Where does it write? We have `rabbit` inheriting from `animal`. diff --git a/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/solution.md b/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/solution.md index fad4b8860..ca833058e 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/solution.md +++ b/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/solution.md @@ -44,7 +44,7 @@ alert( lazy.stomach ); // Now all works fine, because `this.stomach=` does not perform a lookup of `stomach`. The value is written directly into `this` object. -Also we can totally evade the problem by making sure that each hamster has their own stomach: +Also we can totally avoid the problem by making sure that each hamster has their own stomach: ```js run let hamster = { diff --git a/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/task.md b/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/task.md index 6f9fb279e..50171123d 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/task.md +++ b/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Why two hamsters are full? +# Why are both hamsters full? We have two hamsters: `speedy` and `lazy` inheriting from the general `hamster` object. -When we feed one of them, the other one is also full. Why? How to fix it? +When we feed one of them, the other one is also full. Why? How can we fix it? ```js run let hamster = { diff --git a/1-js/08-prototypes/01-prototype-inheritance/article.md b/1-js/08-prototypes/01-prototype-inheritance/article.md index 7c106b1f7..724d55d21 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/article.md +++ b/1-js/08-prototypes/01-prototype-inheritance/article.md @@ -12,11 +12,11 @@ In JavaScript, objects have a special hidden property `[[Prototype]]` (as named ![prototype](object-prototype-empty.svg) -That `[[Prototype]]` has a "magical" meaning. When we want to read a property from `object`, and it's missing, JavaScript automatically takes it from the prototype. In programming, such thing is called "prototypal inheritance". Many cool language features and programming techniques are based on it. +When we read a property from `object`, and it's missing, JavaScript automatically takes it from the prototype. In programming, such thing is called "prototypal inheritance". And soon we'll study many examples of such inheritance, as well as cooler language features built upon it. The property `[[Prototype]]` is internal and hidden, but there are many ways to set it. -One of them is to use `__proto__`, like this: +One of them is to use the special name `__proto__`, like this: ```js run let animal = { @@ -27,23 +27,15 @@ let rabbit = { }; *!* -rabbit.__proto__ = animal; +rabbit.__proto__ = animal; // sets rabbit.[[Prototype]] = animal */!* ``` -```smart header="`__proto__` is a historical getter/setter for `[[Prototype]]`" -Please note that `__proto__` is *not the same* as `[[Prototype]]`. That's a getter/setter for it. - -It exists for historical reasons, in modern language it is replaced with functions `Object.getPrototypeOf/Object.setPrototypeOf` that also get/set the prototype. We'll study the reasons for that and these functions later. - -By the specification, `__proto__` must only be supported by browsers, but in fact all environments including server-side support it. For now, as `__proto__` notation is a little bit more intuitively obvious, we'll use it in the examples. -``` - -If we look for a property in `rabbit`, and it's missing, JavaScript automatically takes it from `animal`. +Now if we read a property from `rabbit`, and it's missing, JavaScript will automatically take it from `animal`. For instance: -```js run +```js let animal = { eats: true }; @@ -131,13 +123,28 @@ alert(longEar.jumps); // true (from rabbit) ![](proto-animal-rabbit-chain.svg) -There are actually only two limitations: +Now if we read something from `longEar`, and it's missing, JavaScript will look for it in `rabbit`, and then in `animal`. + +There are only two limitations: 1. The references can't go in circles. JavaScript will throw an error if we try to assign `__proto__` in a circle. 2. The value of `__proto__` can be either an object or `null`, other types (like primitives) are ignored. Also it may be obvious, but still: there can be only one `[[Prototype]]`. An object may not inherit from two others. + +```smart header="`__proto__` is a historical getter/setter for `[[Prototype]]`" +It's a common mistake of novice developers not to know the difference between these two. + +Please note that `__proto__` is *not the same* as the internal `[[Prototype]]` property. It's a getter/setter for `[[Prototype]]`. Later we'll see situations where it matters, for now let's just keep it in mind, as we build our understanding of JavaScript language. + +The `__proto__` property is a bit outdated. It exists for historical reasons, modern JavaScript suggests that we should use `Object.getPrototypeOf/Object.setPrototypeOf` functions instead that get/set the prototype. We'll also cover these functions later. + +By the specification, `__proto__` must only be supported by browsers. In fact though, all environments including server-side support `__proto__`, so we're quite safe using it. + +As the `__proto__` notation is a bit more intuitively obvious, we use it in the examples. +``` + ## Writing doesn't use prototype The prototype is only used for reading properties. @@ -198,13 +205,16 @@ alert(admin.fullName); // John Smith (*) // setter triggers! admin.fullName = "Alice Cooper"; // (**) + +alert(admin.fullName); // Alice Cooper, state of admin modified +alert(user.fullName); // John Smith, state of user protected ``` Here in the line `(*)` the property `admin.fullName` has a getter in the prototype `user`, so it is called. And in the line `(**)` the property has a setter in the prototype, so it is called. ## The value of "this" -An interesting question may arise in the example above: what's the value of `this` inside `set fullName(value)`? Where the properties `this.name` and `this.surname` are written: into `user` or `admin`? +An interesting question may arise in the example above: what's the value of `this` inside `set fullName(value)`? Where are the properties `this.name` and `this.surname` written: into `user` or `admin`? The answer is simple: `this` is not affected by prototypes at all. @@ -212,7 +222,7 @@ The answer is simple: `this` is not affected by prototypes at all. So, the setter call `admin.fullName=` uses `admin` as `this`, not `user`. -That is actually a super-important thing, because we may have a big object with many methods and inherit from it. Then inherited objects can run its methods, and they will modify the state of these objects, not the big one. +That is actually a super-important thing, because we may have a big object with many methods, and have objects that inherit from it. And when the inheriting objects run the inherited methods, they will modify only their own states, not the state of the big object. For instance, here `animal` represents a "method storage", and `rabbit` makes use of it. @@ -247,14 +257,84 @@ The resulting picture: ![](proto-animal-rabbit-walk-3.svg) -If we had other objects like `bird`, `snake` etc inheriting from `animal`, they would also gain access to methods of `animal`. But `this` in each method would be the corresponding object, evaluated at the call-time (before dot), not `animal`. So when we write data into `this`, it is stored into these objects. +If we had other objects, like `bird`, `snake`, etc., inheriting from `animal`, they would also gain access to methods of `animal`. But `this` in each method call would be the corresponding object, evaluated at the call-time (before dot), not `animal`. So when we write data into `this`, it is stored into these objects. As a result, methods are shared, but the object state is not. +## for..in loop + +The `for..in` loop iterates over inherited properties too. + +For instance: + +```js run +let animal = { + eats: true +}; + +let rabbit = { + jumps: true, + __proto__: animal +}; + +*!* +// Object.keys only returns own keys +alert(Object.keys(rabbit)); // jumps +*/!* + +*!* +// for..in loops over both own and inherited keys +for(let prop in rabbit) alert(prop); // jumps, then eats +*/!* +``` + +If that's not what we want, and we'd like to exclude inherited properties, there's a built-in method [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): it returns `true` if `obj` has its own (not inherited) property named `key`. + +So we can filter out inherited properties (or do something else with them): + +```js run +let animal = { + eats: true +}; + +let rabbit = { + jumps: true, + __proto__: animal +}; + +for(let prop in rabbit) { + let isOwn = rabbit.hasOwnProperty(prop); + + if (isOwn) { + alert(`Our: ${prop}`); // Our: jumps + } else { + alert(`Inherited: ${prop}`); // Inherited: eats + } +} +``` + +Here we have the following inheritance chain: `rabbit` inherits from `animal`, that inherits from `Object.prototype` (because `animal` is a literal object `{...}`, so it's by default), and then `null` above it: + +![](rabbit-animal-object.svg) + +Note, there's one funny thing. Where is the method `rabbit.hasOwnProperty` coming from? We did not define it. Looking at the chain we can see that the method is provided by `Object.prototype.hasOwnProperty`. In other words, it's inherited. + +...But why does `hasOwnProperty` not appear in the `for..in` loop like `eats` and `jumps` do, if `for..in` lists inherited properties? + +The answer is simple: it's not enumerable. Just like all other properties of `Object.prototype`, it has `enumerable:false` flag. And `for..in` only lists enumerable properties. That's why it and the rest of the `Object.prototype` properties are not listed. + +```smart header="Almost all other key/value-getting methods ignore inherited properties" +Almost all other key/value-getting methods, such as `Object.keys`, `Object.values` and so on ignore inherited properties. + +They only operate on the object itself. Properties from the prototype are *not* taken into account. +``` + ## Summary - In JavaScript, all objects have a hidden `[[Prototype]]` property that's either another object or `null`. - We can use `obj.__proto__` to access it (a historical getter/setter, there are other ways, to be covered soon). - The object referenced by `[[Prototype]]` is called a "prototype". -- If we want to read a property of `obj` or call a method, and it doesn't exist, then JavaScript tries to find it in the prototype. Write/delete operations work directly on the object, they don't use the prototype (unless the property is actually a setter). +- If we want to read a property of `obj` or call a method, and it doesn't exist, then JavaScript tries to find it in the prototype. +- Write/delete operations act directly on the object, they don't use the prototype (assuming it's a data property, not a setter). - If we call `obj.method()`, and the `method` is taken from the prototype, `this` still references `obj`. So methods always work with the current object even if they are inherited. +- The `for..in` loop iterates over both its own and its inherited properties. All other key/value-getting methods only operate on the object itself. diff --git a/1-js/08-prototypes/01-prototype-inheritance/object-prototype-empty.svg b/1-js/08-prototypes/01-prototype-inheritance/object-prototype-empty.svg index e1efc1cea..da48a7ccd 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/object-prototype-empty.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/object-prototype-empty.svg @@ -1,22 +1 @@ - - - - object-prototype-empty.svg - Created with sketchtool. - - - - - prototype object - - - - object - - - - [[Prototype]] - - - - \ No newline at end of file +prototype objectobject[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-chain.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-chain.svg index 5eda2d9e2..520bf87ed 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-chain.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-chain.svg @@ -1,40 +1 @@ - - - - proto-animal-rabbit-chain.svg - Created with sketchtool. - - - - - eats: true - walk: function - - - animal - - - - jumps: true - - - rabbit - - - - [[Prototype]] - - - - earLength: 10 - - - longEar - - - - [[Prototype]] - - - - \ No newline at end of file +eats: true walk: functionanimaljumps: truerabbit[[Prototype]]earLength: 10longEar[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-2.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-2.svg index a0a495cb3..8b6573574 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-2.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-2.svg @@ -1,29 +1 @@ - - - - proto-animal-rabbit-walk-2.svg - Created with sketchtool. - - - - - eats: true - walk: function - - - animal - - - - walk: function - - - rabbit - - - - [[Prototype]] - - - - \ No newline at end of file +eats: true walk: functionanimalwalk: functionrabbit[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-3.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-3.svg index 541b92d83..6e3b6f555 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-3.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-3.svg @@ -1,30 +1 @@ - - - - proto-animal-rabbit-walk-3.svg - Created with sketchtool. - - - - - walk: function - sleep: function - - - animal - - - rabbit - - - - [[Prototype]] - - - - name: "White Rabbit" - isSleeping: true - - - - \ No newline at end of file +walk: function sleep: functionanimalrabbit[[Prototype]]name: "White Rabbit" isSleeping: true \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk.svg index db1208eac..b83933a87 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk.svg @@ -1,29 +1 @@ - - - - proto-animal-rabbit-walk.svg - Created with sketchtool. - - - - - eats: true - walk: function - - - animal - - - - jumps: true - - - rabbit - - - - [[Prototype]] - - - - \ No newline at end of file +eats: true walk: functionanimaljumps: truerabbit[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit.svg index 2672739e5..538f5afb3 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit.svg @@ -1,28 +1 @@ - - - - proto-animal-rabbit.svg - Created with sketchtool. - - - - - eats: true - - - animal - - - - jumps: true - - - rabbit - - - - [[Prototype]] - - - - \ No newline at end of file +eats: trueanimaljumps: truerabbit[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-user-admin.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-user-admin.svg index 37b318f2b..ed9fea4a0 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-user-admin.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-user-admin.svg @@ -1,32 +1 @@ - - - - proto-user-admin.svg - Created with sketchtool. - - - - - name: "John" - surname: "Smith" - set fullName: function - - - - isAdmin: true - name: "Alice" - surname: "Cooper" - - - user - - - admin - - - - [[Prototype]] - - - - \ No newline at end of file +name: "John" surname: "Smith" set fullName: functionisAdmin: true name: "Alice" surname: "Cooper"useradmin[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/rabbit-animal-object.svg b/1-js/08-prototypes/01-prototype-inheritance/rabbit-animal-object.svg new file mode 100644 index 000000000..782a858bd --- /dev/null +++ b/1-js/08-prototypes/01-prototype-inheritance/rabbit-animal-object.svg @@ -0,0 +1 @@ +toString: function hasOwnProperty: function ...Object.prototypeanimal[[Prototype]][[Prototype]][[Prototype]]nulleats: truerabbitjumps: true \ No newline at end of file diff --git a/1-js/08-prototypes/02-function-prototype/1-changing-prototype/solution.md b/1-js/08-prototypes/02-function-prototype/1-changing-prototype/solution.md index 771e3061c..ebbdf3a7c 100644 --- a/1-js/08-prototypes/02-function-prototype/1-changing-prototype/solution.md +++ b/1-js/08-prototypes/02-function-prototype/1-changing-prototype/solution.md @@ -7,7 +7,7 @@ Answers: 2. `false`. - Objects are assigned by reference. The object from `Rabbit.prototype` is not duplicated, it's still a single object is referenced both by `Rabbit.prototype` and by the `[[Prototype]]` of `rabbit`. + Objects are assigned by reference. The object from `Rabbit.prototype` is not duplicated, it's still a single object referenced both by `Rabbit.prototype` and by the `[[Prototype]]` of `rabbit`. So when we change its content through one reference, it is visible through the other one. diff --git a/1-js/08-prototypes/02-function-prototype/1-changing-prototype/task.md b/1-js/08-prototypes/02-function-prototype/1-changing-prototype/task.md index 4b8522d3d..2838c125a 100644 --- a/1-js/08-prototypes/02-function-prototype/1-changing-prototype/task.md +++ b/1-js/08-prototypes/02-function-prototype/1-changing-prototype/task.md @@ -20,7 +20,7 @@ alert( rabbit.eats ); // true ``` -1. We added one more string (emphasized), what `alert` shows now? +1. We added one more string (emphasized). What will `alert` show now? ```js function Rabbit() {} @@ -54,7 +54,7 @@ alert( rabbit.eats ); // true alert( rabbit.eats ); // ? ``` -3. Like this (replaced one line)? +3. And like this (replaced one line)? ```js function Rabbit() {} diff --git a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md index 43190e163..0073e252e 100644 --- a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md +++ b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md @@ -15,7 +15,7 @@ alert( user2.name ); // Pete (worked!) It worked, because `User.prototype.constructor == User`. -..But if someone, so to say, overwrites `User.prototype` and forgets to recreate `"constructor"`, then it would fail. +..But if someone, so to speak, overwrites `User.prototype` and forgets to recreate `constructor` to reference `User`, then it would fail. For instance: @@ -41,4 +41,4 @@ Here's how `new user.constructor('Pete')` works: 2. Then it follows the prototype chain. The prototype of `user` is `User.prototype`, and it also has nothing. 3. The value of `User.prototype` is a plain object `{}`, its prototype is `Object.prototype`. And there is `Object.prototype.constructor == Object`. So it is used. -At the end, we have `let user2 = new Object('Pete')`. The built-in `Object` constructor ignores arguments, it always creates an empty object -- that's what we have in `user2` after all. +At the end, we have `let user2 = new Object('Pete')`. The built-in `Object` constructor ignores arguments, it always creates an empty object, similar to `let user2 = {}`, that's what we have in `user2` after all. diff --git a/1-js/08-prototypes/02-function-prototype/article.md b/1-js/08-prototypes/02-function-prototype/article.md index 5511c8ee0..b1ef51826 100644 --- a/1-js/08-prototypes/02-function-prototype/article.md +++ b/1-js/08-prototypes/02-function-prototype/article.md @@ -2,7 +2,7 @@ Remember, new objects can be created with a constructor function, like `new F()`. -If `F.prototype` is an object, then `new` operator uses it to set `[[Prototype]]` for the new object. +If `F.prototype` is an object, then the `new` operator uses it to set `[[Prototype]]` for the new object. ```smart JavaScript had prototypal inheritance from the beginning. It was one of the core features of the language. @@ -41,7 +41,7 @@ That's the resulting picture: On the picture, `"prototype"` is a horizontal arrow, meaning a regular property, and `[[Prototype]]` is vertical, meaning the inheritance of `rabbit` from `animal`. ```smart header="`F.prototype` only used at `new F` time" -`F.prototype` property is only used when `new F` is called, it assigns `[[Prototype]]` of the new object. After that, there's no connection between `F.prototype` and the new object. Think of it as a "one-time gift". +`F.prototype` property is only used when `new F` is called, it assigns `[[Prototype]]` of the new object. If, after the creation, `F.prototype` property changes (`F.prototype = `), then new objects created by `new F` will have another object as `[[Prototype]]`, but already existing objects keep the old one. ``` @@ -158,11 +158,11 @@ Rabbit.prototype = { In this chapter we briefly described the way of setting a `[[Prototype]]` for objects created via a constructor function. Later we'll see more advanced programming patterns that rely on it. -Everything is quite simple, just few notes to make things clear: +Everything is quite simple, just a few notes to make things clear: -- The `F.prototype` property is not the same as `[[Prototype]]`. The only thing `F.prototype` does: it sets `[[Prototype]]` of new objects when `new F()` is called. -- The value of `F.prototype` should be either an object or null: other values won't work. -- The `"prototype"` property only has such a special effect when is set to a constructor function, and invoked with `new`. +- The `F.prototype` property (don't mistake it for `[[Prototype]]`) sets `[[Prototype]]` of new objects when `new F()` is called. +- The value of `F.prototype` should be either an object or `null`: other values won't work. +- The `"prototype"` property only has such a special effect when set on a constructor function, and invoked with `new`. On regular objects the `prototype` is nothing special: ```js diff --git a/1-js/08-prototypes/02-function-prototype/function-prototype-constructor.svg b/1-js/08-prototypes/02-function-prototype/function-prototype-constructor.svg index 6aa3710cc..187b899e4 100644 --- a/1-js/08-prototypes/02-function-prototype/function-prototype-constructor.svg +++ b/1-js/08-prototypes/02-function-prototype/function-prototype-constructor.svg @@ -1,26 +1 @@ - - - - function-prototype-constructor.svg - Created with sketchtool. - - - - - - Rabbit - - - - - prototype - - - constructor - - - default "prototype" - - - - \ No newline at end of file +Rabbitprototypeconstructordefault "prototype" \ No newline at end of file diff --git a/1-js/08-prototypes/02-function-prototype/proto-constructor-animal-rabbit.svg b/1-js/08-prototypes/02-function-prototype/proto-constructor-animal-rabbit.svg index 447a3b72f..a2c19d850 100644 --- a/1-js/08-prototypes/02-function-prototype/proto-constructor-animal-rabbit.svg +++ b/1-js/08-prototypes/02-function-prototype/proto-constructor-animal-rabbit.svg @@ -1,36 +1 @@ - - - - proto-constructor-animal-rabbit.svg - Created with sketchtool. - - - - - eats: true - - - - name: "White Rabbit" - - - animal - - - - Rabbit - - - rabbit - - - - - [[Prototype]] - - - prototype - - - - \ No newline at end of file +eats: truename: "White Rabbit"animalRabbitrabbit[[Prototype]]prototype \ No newline at end of file diff --git a/1-js/08-prototypes/02-function-prototype/rabbit-prototype-constructor.svg b/1-js/08-prototypes/02-function-prototype/rabbit-prototype-constructor.svg index 322f7b103..4d6b10e30 100644 --- a/1-js/08-prototypes/02-function-prototype/rabbit-prototype-constructor.svg +++ b/1-js/08-prototypes/02-function-prototype/rabbit-prototype-constructor.svg @@ -1,39 +1 @@ - - - - rabbit-prototype-constructor.svg - Created with sketchtool. - - - - - - - - - - default "prototype" - - - - - Rabbit - - - rabbit - - - - - - [[Prototype]] - - - prototype - - - constructor - - - - \ No newline at end of file +default "prototype"Rabbitrabbit[[Prototype]]prototypeconstructor \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/solution.md b/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/solution.md index e3651683f..99c358c9b 100644 --- a/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/solution.md +++ b/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/solution.md @@ -15,3 +15,27 @@ function f(a, b) { f.defer(1000)(1, 2); // shows 3 after 1 sec ``` + +Please note: we use `this` in `f.apply` to make our decoration work for object methods. + +So if the wrapper function is called as an object method, then `this` is passed to the original method `f`. + +```js run +Function.prototype.defer = function(ms) { + let f = this; + return function(...args) { + setTimeout(() => f.apply(this, args), ms); + } +}; + +let user = { + name: "John", + sayHi() { + alert(this.name); + } +} + +user.sayHi = user.sayHi.defer(1000); + +user.sayHi(); +``` diff --git a/1-js/08-prototypes/03-native-prototypes/article.md b/1-js/08-prototypes/03-native-prototypes/article.md index c5e0dbd60..9cf9897b2 100644 --- a/1-js/08-prototypes/03-native-prototypes/article.md +++ b/1-js/08-prototypes/03-native-prototypes/article.md @@ -33,7 +33,9 @@ We can check it like this: let obj = {}; alert(obj.__proto__ === Object.prototype); // true -// obj.toString === obj.__proto__.toString == Object.prototype.toString + +alert(obj.toString === obj.__proto__.toString); //true +alert(obj.toString === Object.prototype.toString); //true ``` Please note that there is no additional `[[Prototype]]` in the chain above `Object.prototype`: @@ -99,12 +101,12 @@ alert(f.__proto__.__proto__ == Object.prototype); // true, inherit from objects The most intricate thing happens with strings, numbers and booleans. -As we remember, they are not objects. But if we try to access their properties, then temporary wrapper objects are created using built-in constructors `String`, `Number`, `Boolean`, they provide the methods and disappear. +As we remember, they are not objects. But if we try to access their properties, temporary wrapper objects are created using built-in constructors `String`, `Number` and `Boolean`. They provide the methods and disappear. These objects are created invisibly to us and most engines optimize them out, but the specification describes it exactly this way. Methods of these objects also reside in prototypes, available as `String.prototype`, `Number.prototype` and `Boolean.prototype`. ```warn header="Values `null` and `undefined` have no object wrappers" -Special values `null` and `undefined` stand apart. They have no object wrappers, so methods and properties are not available for them. And there are no corresponding prototypes too. +Special values `null` and `undefined` stand apart. They have no object wrappers, so methods and properties are not available for them. And there are no corresponding prototypes either. ``` ## Changing native prototypes [#native-prototype-change] @@ -129,9 +131,9 @@ So, generally, modifying a native prototype is considered a bad idea. **In modern programming, there is only one case where modifying native prototypes is approved. That's polyfilling.** -Polyfilling is a term for making a substitute for a method that exists in JavaScript specification, but not yet supported by current JavaScript engine. +Polyfilling is a term for making a substitute for a method that exists in the JavaScript specification, but is not yet supported by a particular JavaScript engine. -Then we may implement it manually and populate the built-in prototype with it. +We may then implement it manually and populate the built-in prototype with it. For instance: @@ -179,18 +181,18 @@ obj.join = Array.prototype.join; alert( obj.join(',') ); // Hello,world! ``` -It works, because the internal algorithm of the built-in `join` method only cares about the correct indexes and the `length` property, it doesn't check that the object is indeed the array. And many built-in methods are like that. +It works because the internal algorithm of the built-in `join` method only cares about the correct indexes and the `length` property. It doesn't check if the object is indeed an array. Many built-in methods are like that. Another possibility is to inherit by setting `obj.__proto__` to `Array.prototype`, so all `Array` methods are automatically available in `obj`. But that's impossible if `obj` already inherits from another object. Remember, we only can inherit from one object at a time. -Borrowing methods is flexible, it allows to mix functionality from different objects if needed. +Borrowing methods is flexible, it allows to mix functionalities from different objects if needed. ## Summary - All built-in objects follow the same pattern: - - The methods are stored in the prototype (`Array.prototype`, `Object.prototype`, `Date.prototype` etc). - - The object itself stores only the data (array items, object properties, the date). -- Primitives also store methods in prototypes of wrapper objects: `Number.prototype`, `String.prototype`, `Boolean.prototype`. Only `undefined` and `null` do not have wrapper objects. -- Built-in prototypes can be modified or populated with new methods. But it's not recommended to change them. Probably the only allowable cause is when we add-in a new standard, but not yet supported by the engine JavaScript method. + - The methods are stored in the prototype (`Array.prototype`, `Object.prototype`, `Date.prototype`, etc.) + - The object itself stores only the data (array items, object properties, the date) +- Primitives also store methods in prototypes of wrapper objects: `Number.prototype`, `String.prototype` and `Boolean.prototype`. Only `undefined` and `null` do not have wrapper objects +- Built-in prototypes can be modified or populated with new methods. But it's not recommended to change them. The only allowable case is probably when we add-in a new standard, but it's not yet supported by the JavaScript engine diff --git a/1-js/08-prototypes/03-native-prototypes/function-prototype-constructor.svg b/1-js/08-prototypes/03-native-prototypes/function-prototype-constructor.svg index 6aa3710cc..187b899e4 100644 --- a/1-js/08-prototypes/03-native-prototypes/function-prototype-constructor.svg +++ b/1-js/08-prototypes/03-native-prototypes/function-prototype-constructor.svg @@ -1,26 +1 @@ - - - - function-prototype-constructor.svg - Created with sketchtool. - - - - - - Rabbit - - - - - prototype - - - constructor - - - default "prototype" - - - - \ No newline at end of file +Rabbitprototypeconstructordefault "prototype" \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/native-prototypes-array-tostring.svg b/1-js/08-prototypes/03-native-prototypes/native-prototypes-array-tostring.svg index 37601da27..8475560b3 100644 --- a/1-js/08-prototypes/03-native-prototypes/native-prototypes-array-tostring.svg +++ b/1-js/08-prototypes/03-native-prototypes/native-prototypes-array-tostring.svg @@ -1,39 +1 @@ - - - - native-prototypes-array-tostring.svg - Created with sketchtool. - - - - - toString: function - - ... - - - Array.prototype - - - - toString: function - ... - - - Object.prototype - - - - - [[Prototype]] - - - - [[Prototype]] - - - [1, 2, 3] - - - - \ No newline at end of file +toString: function ...Array.prototypetoString: function ...Object.prototype[[Prototype]][[Prototype]][1, 2, 3] \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg b/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg index a6f78e574..36cc81cd9 100644 --- a/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg +++ b/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg @@ -1,87 +1 @@ - - - - native-prototypes-classes.svg - Created with sketchtool. - - - - - toString: function - other object methods - - - Object.prototype - - - - - null - - - - slice: function - other array methods - - - [[Prototype]] - - - [[Prototype]] - - - [[Prototype]] - - - [[Prototype]] - - - [[Prototype]] - - - [[Prototype]] - - - [[Prototype]] - - - Array.prototype - - - - call: function - other function methods - - - Function.prototype - - - - toFixed: function - other number methods - - - Number.prototype - - - - - - [1, 2, 3] - - - - function f(args) { - ... - } - - - - 5 - - - - - - - \ No newline at end of file +toString: function other object methodsObject.prototypenullslice: function other array methods[[Prototype]][[Prototype]][[Prototype]][[Prototype]][[Prototype]][[Prototype]][[Prototype]]Array.prototypecall: function other function methodsFunction.prototypetoFixed: function other number methodsNumber.prototype[1, 2, 3]function f(args) { ... }5 \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/object-prototype-1.svg b/1-js/08-prototypes/03-native-prototypes/object-prototype-1.svg index 8a93d2a86..c111e0725 100644 --- a/1-js/08-prototypes/03-native-prototypes/object-prototype-1.svg +++ b/1-js/08-prototypes/03-native-prototypes/object-prototype-1.svg @@ -1,38 +1 @@ - - - - object-prototype-1.svg - Created with sketchtool. - - - - - constructor: Object - toString: function - ... - - - - Object.prototype - - - - Object - - - obj = new Object() - - - - - [[Prototype]] - - - prototype - - - constructor - - - - \ No newline at end of file +constructor: Object toString: function ...Object.prototypeObjectobj = new Object()[[Prototype]]prototype \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/object-prototype-null.svg b/1-js/08-prototypes/03-native-prototypes/object-prototype-null.svg index ba22dc601..8b802eb44 100644 --- a/1-js/08-prototypes/03-native-prototypes/object-prototype-null.svg +++ b/1-js/08-prototypes/03-native-prototypes/object-prototype-null.svg @@ -1,21 +1 @@ - - - - object-prototype-null.svg - Created with sketchtool. - - - - - obj - - - - [[Prototype]] - - - null - - - - \ No newline at end of file +obj[[Prototype]]null \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/object-prototype.svg b/1-js/08-prototypes/03-native-prototypes/object-prototype.svg index 828f61d3b..b5014f9f0 100644 --- a/1-js/08-prototypes/03-native-prototypes/object-prototype.svg +++ b/1-js/08-prototypes/03-native-prototypes/object-prototype.svg @@ -1,30 +1 @@ - - - - object-prototype.svg - Created with sketchtool. - - - - - constructor: Object - toString: function - ... - - - Object.prototype - - - - Object - - - - prototype - - - constructor - - - - \ No newline at end of file +constructor: Object toString: function ...Object.prototypeObjectprototype \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/proto-constructor-animal-rabbit.svg b/1-js/08-prototypes/03-native-prototypes/proto-constructor-animal-rabbit.svg index 447a3b72f..a2c19d850 100644 --- a/1-js/08-prototypes/03-native-prototypes/proto-constructor-animal-rabbit.svg +++ b/1-js/08-prototypes/03-native-prototypes/proto-constructor-animal-rabbit.svg @@ -1,36 +1 @@ - - - - proto-constructor-animal-rabbit.svg - Created with sketchtool. - - - - - eats: true - - - - name: "White Rabbit" - - - animal - - - - Rabbit - - - rabbit - - - - - [[Prototype]] - - - prototype - - - - \ No newline at end of file +eats: truename: "White Rabbit"animalRabbitrabbit[[Prototype]]prototype \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/rabbit-prototype-constructor.svg b/1-js/08-prototypes/03-native-prototypes/rabbit-prototype-constructor.svg index 322f7b103..4d6b10e30 100644 --- a/1-js/08-prototypes/03-native-prototypes/rabbit-prototype-constructor.svg +++ b/1-js/08-prototypes/03-native-prototypes/rabbit-prototype-constructor.svg @@ -1,39 +1 @@ - - - - rabbit-prototype-constructor.svg - Created with sketchtool. - - - - - - - - - - default "prototype" - - - - - Rabbit - - - rabbit - - - - - - [[Prototype]] - - - prototype - - - constructor - - - - \ No newline at end of file +default "prototype"Rabbitrabbit[[Prototype]]prototypeconstructor \ No newline at end of file diff --git a/1-js/08-prototypes/04-prototype-methods/article.md b/1-js/08-prototypes/04-prototype-methods/article.md index a0bf20735..b359c141d 100644 --- a/1-js/08-prototypes/04-prototype-methods/article.md +++ b/1-js/08-prototypes/04-prototype-methods/article.md @@ -7,7 +7,7 @@ The `__proto__` is considered outdated and somewhat deprecated (in browser-only The modern methods are: -- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- creates an empty object with given `proto` as `[[Prototype]]` and optional property descriptors. +- [Object.create(proto, [descriptors])](mdn:js/Object/create) -- creates an empty object with given `proto` as `[[Prototype]]` and optional property descriptors. - [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- returns the `[[Prototype]]` of `obj`. - [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- sets the `[[Prototype]]` of `obj` to `proto`. @@ -27,7 +27,7 @@ let rabbit = Object.create(animal); alert(rabbit.eats); // true *!* -alert(Object.getPrototypeOf(rabbit) === animal); // get the prototype of rabbit +alert(Object.getPrototypeOf(rabbit) === animal); // true */!* *!* @@ -56,7 +56,6 @@ The descriptors are in the same format as described in the chapter - - - object-prototype-2.svg - Created with sketchtool. - - - - - ... - get __proto__: function - set __proto__: function - - - - Object.prototype - - - - Object - - - obj - - - - - [[Prototype]] - - - prototype - - - constructor - - - - \ No newline at end of file +... get __proto__: function set __proto__: functionObject.prototypeObjectobj[[Prototype]]prototype \ No newline at end of file diff --git a/1-js/08-prototypes/04-prototype-methods/object-prototype-null.svg b/1-js/08-prototypes/04-prototype-methods/object-prototype-null.svg index ba22dc601..8b802eb44 100644 --- a/1-js/08-prototypes/04-prototype-methods/object-prototype-null.svg +++ b/1-js/08-prototypes/04-prototype-methods/object-prototype-null.svg @@ -1,21 +1 @@ - - - - object-prototype-null.svg - Created with sketchtool. - - - - - obj - - - - [[Prototype]] - - - null - - - - \ No newline at end of file +obj[[Prototype]]null \ No newline at end of file diff --git a/1-js/09-classes/01-class/1-rewrite-to-class/task.md b/1-js/09-classes/01-class/1-rewrite-to-class/task.md index 05365e410..4477de679 100644 --- a/1-js/09-classes/01-class/1-rewrite-to-class/task.md +++ b/1-js/09-classes/01-class/1-rewrite-to-class/task.md @@ -4,6 +4,6 @@ importance: 5 # Rewrite to class -The `Clock` class is written in functional style. Rewrite it the "class" syntax. +The `Clock` class (see the sandbox) is written in functional style. Rewrite it in the "class" syntax. P.S. The clock ticks in the console, open it to see. diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md index b8bd4f339..9dc29128b 100644 --- a/1-js/09-classes/01-class/article.md +++ b/1-js/09-classes/01-class/article.md @@ -68,7 +68,7 @@ So, what exactly is a `class`? That's not an entirely new language-level entity Let's unveil any magic and see what a class really is. That'll help in understanding many complex aspects. -In JavaScript, a class is a kind of a function. +In JavaScript, a class is a kind of function. Here, take a look: @@ -91,7 +91,9 @@ What `class User {...}` construct really does is: Afterwards, for new objects, when we call a method, it's taken from the prototype, just as described in the chapter . So `new User` object has access to class methods. -We can illustrate the result of `class User` as: +After `new User` object is created, when we call its method, it's taken from the prototype, just as described in the chapter . So the object has access to class methods. + +We can illustrate the result of `class User` declaration as: ![](class-user.svg) @@ -117,9 +119,9 @@ alert(User.prototype.sayHi); // alert(this.name); alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi ``` -## Not just a syntax sugar +## Not just a syntactic sugar -Sometimes people say that `class` is a "syntax sugar" in JavaScript, because we could actually declare the same without `class` keyword at all: +Sometimes people say that `class` is a "syntactic sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new), because we could actually declare the same without `class` keyword at all: ```js run // rewriting class User in pure functions @@ -128,7 +130,7 @@ Sometimes people say that `class` is a "syntax sugar" in JavaScript, because we function User(name) { this.name = name; } -// any function prototype has constructor property by default, +// a function prototype has "constructor" property by default, // so we don't need to create it // 2. Add the method to prototype @@ -141,13 +143,13 @@ let user = new User("John"); user.sayHi(); ``` -The result of this definition is about the same. So, there are indeed reasons why `class` can be considered a syntax sugar to define a constructor together with its prototype methods. +The result of this definition is about the same. So, there are indeed reasons why `class` can be considered a syntactic sugar to define a constructor together with its prototype methods. -Although, there are important differences. +Still, there are important differences. 1. First, a function created by `class` is labelled by a special internal property `[[FunctionKind]]:"classConstructor"`. So it's not entirely the same as creating it manually. - Unlike a regular function, a class constructor can't be called without `new`: + The language checks for that property in a variety of places. For example, unlike a regular function, it must be called with `new`: ```js run class User { @@ -167,6 +169,7 @@ Although, there are important differences. alert(User); // class User { ... } ``` + There are other differences, we'll see them soon. 2. Class methods are non-enumerable A class definition sets `enumerable` flag to `false` for all methods in the `"prototype"`. @@ -181,7 +184,7 @@ Also, in addition to its basic operation, the `class` syntax brings many other f ## Class Expression -Just like functions, classes can be defined inside another expression, passed around, returned, assigned etc. +Just like functions, classes can be defined inside another expression, passed around, returned, assigned, etc. Here's an example of a class expression: @@ -210,7 +213,6 @@ new User().sayHi(); // works, shows MyClass definition alert(MyClass); // error, MyClass not visible outside of the class ``` - We can even make classes dynamically "on-demand", like this: ```js run @@ -219,7 +221,7 @@ function makeClass(phrase) { return class { sayHi() { alert(phrase); - }; + } }; } @@ -230,9 +232,9 @@ new User().sayHi(); // Hello ``` -## Getters/setters, other shorthands +## Getters/setters -Classes also include getters/setters, generators, computed properties etc. +Just like literal objects, classes may include getters/setters, computed properties etc. Here's an example for `user.name` implemented using `get/set`: @@ -265,25 +267,14 @@ class User { let user = new User("John"); alert(user.name); // John -user = new User(""); // Name too short. +user = new User(""); // Name is too short. ``` -Internally, getters and setters are created on `User.prototype`, like this: +Technically, such class declaration works by creating getters and setters in `User.prototype`. -```js -Object.defineProperties(User.prototype, { - name: { - get() { - return this._name - }, - set(name) { - // ... - } - } -}); -``` +## Computed names [...] -Here's an example with computed properties: +Here's an example with a computed method name using brackets `[...]`: ```js run function f() { return "sayHi"; } @@ -298,30 +289,119 @@ class User { new User().sayHi(); ``` -For a generator method, similarly, prepend it with `*`. +Such features are easy to remember, as they resemble that of literal objects. -## Class properties +## Class fields ```warn header="Old browsers may need a polyfill" -Class-level properties are a recent addition to the language. +Class fields are a recent addition to the language. ``` -In the example above, `User` only had methods. Let's add a property: +Previously, our classes only had methods. + +"Class fields" is a syntax that allows to add any properties. + +For instance, let's add `name` property to `class User`: ```js run class User { - name = "Anonymous"; +*!* + name = "John"; +*/!* sayHi() { alert(`Hello, ${this.name}!`); } } -new User().sayHi(); +new User().sayHi(); // Hello, John! +``` + +So, we just write " = " in the declaration, and that's it. + +The important difference of class fields is that they are set on individual objects, not `User.prototype`: + +```js run +class User { +*!* + name = "John"; +*/!* +} + +let user = new User(); +alert(user.name); // John +alert(User.prototype.name); // undefined +``` + +We can also assign values using more complex expressions and function calls: + +```js run +class User { +*!* + name = prompt("Name, please?", "John"); +*/!* +} + +let user = new User(); +alert(user.name); // John +``` + + +### Making bound methods with class fields + +As demonstrated in the chapter functions in JavaScript have a dynamic `this`. It depends on the context of the call. + +So if an object method is passed around and called in another context, `this` won't be a reference to its object any more. + +For instance, this code will show `undefined`: + +```js run +class Button { + constructor(value) { + this.value = value; + } + + click() { + alert(this.value); + } +} + +let button = new Button("hello"); + +*!* +setTimeout(button.click, 1000); // undefined +*/!* +``` + +The problem is called "losing `this`". + +There are two approaches to fixing it, as discussed in the chapter : + +1. Pass a wrapper-function, such as `setTimeout(() => button.click(), 1000)`. +2. Bind the method to object, e.g. in the constructor. + +Class fields provide another, quite elegant syntax: + +```js run +class Button { + constructor(value) { + this.value = value; + } +*!* + click = () => { + alert(this.value); + } +*/!* +} + +let button = new Button("hello"); + +setTimeout(button.click, 1000); // hello ``` -The property is not placed into `User.prototype`. Instead, it is created by `new`, separately for every object. So, the property will never be shared between different objects of the same class. +The class field `click = () => {...}` is created on a per-object basis, there's a separate function for each `Button` object, with `this` inside it referencing that object. We can pass `button.click` around anywhere, and the value of `this` will always be correct. +That's especially useful in browser environment, for event listeners. ## Summary @@ -363,6 +443,6 @@ class MyClass { } ``` -`MyClass` is technically a function, while methods are written to `MyClass.prototype`. +`MyClass` is technically a function (the one that we provide as `constructor`), while methods, getters and setters are written to `MyClass.prototype`. In the next chapters we'll learn more about classes, including inheritance and other features. diff --git a/1-js/09-classes/01-class/class-user.svg b/1-js/09-classes/01-class/class-user.svg index 788e14229..95b58179b 100644 --- a/1-js/09-classes/01-class/class-user.svg +++ b/1-js/09-classes/01-class/class-user.svg @@ -1,29 +1 @@ - - - - class-user.svg - Created with sketchtool. - - - - - sayHi: function - - - - User - - - User.prototype - - - - prototype - - - constructor: User - - - - - \ No newline at end of file +sayHi: functionUserUser.prototypeprototypeconstructor: User \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js index ca613ca5e..be2053cfc 100644 --- a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js +++ b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js @@ -1,7 +1,7 @@ class ExtendedClock extends Clock { constructor(options) { super(options); - let { precision=1000 } = options; + let { precision = 1000 } = options; this.precision = precision; } diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg b/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg deleted file mode 100644 index 8ab568291..000000000 --- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - rabbit-extends-object.svg - Created with sketchtool. - - - - - call: function - bind: function - ... - - - - Function.prototype - - - - constructor - - - Object - - - Rabbit - - - - [[Prototype]] - - - - [[Prototype]] - - - constructor - - - - call: function - bind: function - ... - - - - Function.prototype - - - Rabbit - - - - [[Prototype]] - - - constructor - - - class Rabbit - - - class Rabbit extends Object - - - - \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg b/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg index 7a55a5043..3471904ab 100644 --- a/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg +++ b/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg @@ -1,64 +1 @@ - - - - animal-rabbit-extends.svg - Created with sketchtool. - - - - - constructor: Animal - run: function - stop: function - - - - Animal.prototype - - - - constructor: Rabbit - hide: function - - - Rabbit.prototype - - - - Animal - - - - Rabbit - - - new Rabbit - - - - - [[Prototype]] - - - - [[Prototype]] - - - prototype - - - - prototype - - - name: "White Rabbit" - - - constructor - - - constructor - - - - \ No newline at end of file +constructor: Animal run: function stop: functionAnimal.prototypeconstructor: Rabbit hide: functionRabbit.prototypeAnimalRabbitnew Rabbit[[Prototype]][[Prototype]]prototypeprototypename: "White Rabbit"constructorconstructorextends \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/article.md b/1-js/09-classes/02-class-inheritance/article.md index 4b281bafe..85d2ee923 100644 --- a/1-js/09-classes/02-class-inheritance/article.md +++ b/1-js/09-classes/02-class-inheritance/article.md @@ -1,9 +1,13 @@ # Class inheritance -Let's say we have two classes. +Class inheritance is a way for one class to extend another class. -`Animal`: +So we can create new functionality on top of the existing. + +## The "extends" keyword + +Let's say we have class `Animal`: ```js class Animal { @@ -12,7 +16,7 @@ class Animal { this.name = name; } run(speed) { - this.speed += speed; + this.speed = speed; alert(`${this.name} runs with speed ${this.speed}.`); } stop() { @@ -24,52 +28,19 @@ class Animal { let animal = new Animal("My animal"); ``` -![](rabbit-animal-independent-animal.svg) - - -...And `Rabbit`: - -```js -class Rabbit { - constructor(name) { - this.name = name; - } - hide() { - alert(`${this.name} hides!`); - } -} - -let rabbit = new Rabbit("My rabbit"); -``` - -![](rabbit-animal-independent-rabbit.svg) +Here's how we can represent `animal` object and `Animal` class graphically: +![](rabbit-animal-independent-animal.svg) -Right now they are fully independent. - -But we'd want `Rabbit` to extend `Animal`. In other words, rabbits should be based on animals, have access to methods of `Animal` and extend them with its own methods. +...And we would like to create another `class Rabbit`. -To inherit from another class, we should specify `"extends"` and the parent class before the brackets `{..}`. +As rabbits are animals, `Rabbit` class should be based on `Animal`, have access to animal methods, so that rabbits can do what "generic" animals can do. -Here `Rabbit` inherits from `Animal`: +The syntax to extend another class is: `class Child extends Parent`. -```js run -class Animal { - constructor(name) { - this.speed = 0; - this.name = name; - } - run(speed) { - this.speed += speed; - alert(`${this.name} runs with speed ${this.speed}.`); - } - stop() { - this.speed = 0; - alert(`${this.name} stopped.`); - } -} +Let's create `class Rabbit` that inherits from `Animal`: -// Inherit from Animal by specifying "extends Animal" +```js *!* class Rabbit extends Animal { */!* @@ -84,15 +55,18 @@ rabbit.run(5); // White Rabbit runs with speed 5. rabbit.hide(); // White Rabbit hides! ``` -Now the `Rabbit` code became a bit shorter, as it uses `Animal` constructor by default, and it also can `run`, as animals do. +Object of `Rabbit` class have access to both `Rabbit` methods, such as `rabbit.hide()`, and also to `Animal` methods, such as `rabbit.run()`. -Internally, `extends` keyword adds `[[Prototype]]` reference from `Rabbit.prototype` to `Animal.prototype`: +Internally, `extends` keyword works using the good old prototype mechanics. It sets `Rabbit.prototype.[[Prototype]]` to `Animal.prototype`. So, if a method is not found in `Rabbit.prototype`, JavaScript takes it from `Animal.prototype`. ![](animal-rabbit-extends.svg) -So, if a method is not found in `Rabbit.prototype`, JavaScript takes it from `Animal.prototype`. +For instance, to find `rabbit.run` method, the engine checks (bottom-up on the picture): +1. The `rabbit` object (has no `run`). +2. Its prototype, that is `Rabbit.prototype` (has `hide`, but not `run`). +3. Its prototype, that is (due to `extends`) `Animal.prototype`, that finally has the `run` method. -As we can recall from the chapter , JavaScript uses the same prototypal inheritance for build-in objects. E.g. `Date.prototype.[[Prototype]]` is `Object.prototype`, so dates have generic object methods. +As we can recall from the chapter , JavaScript itself uses prototypal inheritance for built-in objects. E.g. `Date.prototype.[[Prototype]]` is `Object.prototype`. That's why dates have access to generic object methods. ````smart header="Any expression is allowed after `extends`" Class syntax allows to specify not just a class, but any expression after `extends`. @@ -102,8 +76,8 @@ For instance, a function call that generates the parent class: ```js run function f(phrase) { return class { - sayHi() { alert(phrase) } - } + sayHi() { alert(phrase); } + }; } *!* @@ -119,20 +93,20 @@ That may be useful for advanced programming patterns when we use functions to ge ## Overriding a method -Now let's move forward and override a method. As of now, `Rabbit` inherits the `stop` method that sets `this.speed = 0` from `Animal`. +Now let's move forward and override a method. By default, all methods that are not specified in `class Rabbit` are taken directly "as is" from `class Animal`. -If we specify our own `stop` in `Rabbit`, then it will be used instead: +But if we specify our own method in `Rabbit`, such as `stop()` then it will be used instead: ```js class Rabbit extends Animal { stop() { - // ...this will be used for rabbit.stop() + // ...now this will be used for rabbit.stop() + // instead of stop() from class Animal } } ``` - -...But usually we don't want to totally replace a parent method, but rather to build on top of it, tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process. +Usually we don't want to totally replace a parent method, but rather to build on top of it to tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process. Classes provide `"super"` keyword for that. @@ -150,7 +124,7 @@ class Animal { } run(speed) { - this.speed += speed; + this.speed = speed; alert(`${this.name} runs with speed ${this.speed}.`); } @@ -207,7 +181,7 @@ setTimeout(function() { super.stop() }, 1000); With constructors it gets a little bit tricky. -Till now, `Rabbit` did not have its own `constructor`. +Until now, `Rabbit` did not have its own `constructor`. According to the [specification](https://tc39.github.io/ecma262/#sec-runtime-semantics-classdefinitionevaluation), if a class extends another class and has no `constructor`, then the following `constructor` is generated: @@ -256,22 +230,24 @@ let rabbit = new Rabbit("White Rabbit", 10); // Error: this is not defined. Whoops! We've got an error. Now we can't create rabbits. What went wrong? -The short answer is: constructors in inheriting classes must call `super(...)`, and (!) do it before using `this`. +The short answer is: + +- **Constructors in inheriting classes must call `super(...)`, and (!) do it before using `this`.** ...But why? What's going on here? Indeed, the requirement seems strange. -Of course, there's an explanation. Let's get into details, so you'd really understand what's going on. +Of course, there's an explanation. Let's get into details, so you'll really understand what's going on. -In JavaScript, there's a distinction between a "constructor function of an inheriting class" and all others. In an inheriting class, the corresponding constructor function is labelled with a special internal property `[[ConstructorKind]]:"derived"`. +In JavaScript, there's a distinction between a constructor function of an inheriting class (so-called "derived constructor") and other functions. A derived constructor has a special internal property `[[ConstructorKind]]:"derived"`. That's a special internal label. -The difference is: +That label affects its behavior with `new`. -- When a normal constructor runs, it creates an empty object as `this` and continues with it. -- But when a derived constructor runs, it doesn't do it. It expects the parent constructor to do this job. +- When a regular function is executed with `new`, it creates an empty object and assigns it to `this`. +- But when a derived constructor runs, it doesn't do this. It expects the parent constructor to do this job. -So if we're making a constructor of our own, then we must call `super`, because otherwise the object with `this` reference to it won't be created. And we'll get an error. +So a derived constructor must call `super` in order to execute its parent (base) constructor, otherwise the object for `this` won't be created. And we'll get an error. -For `Rabbit` to work, we need to call `super()` before using `this`, like here: +For the `Rabbit` constructor to work, it needs to call `super()` before using `this`, like here: ```js run class Animal { @@ -305,9 +281,111 @@ alert(rabbit.earLength); // 10 ``` + +### Overriding class fields: a tricky note + +```warn header="Advanced note" +This note assumes you have a certain experience with classes, maybe in other programming languages. + +It provides better insight into the language and also explains the behavior that might be a source of bugs (but not very often). + +If you find it difficult to understand, just go on, continue reading, then return to it some time later. +``` + +We can override not only methods, but also class fields. + +Although, there's a tricky behavior when we access an overridden field in parent constructor, quite different from most other programming languages. + +Consider this example: + +```js run +class Animal { + name = 'animal'; + + constructor() { + alert(this.name); // (*) + } +} + +class Rabbit extends Animal { + name = 'rabbit'; +} + +new Animal(); // animal +*!* +new Rabbit(); // animal +*/!* +``` + +Here, class `Rabbit` extends `Animal` and overrides `name` field with its own value. + +There's no own constructor in `Rabbit`, so `Animal` constructor is called. + +What's interesting is that in both cases: `new Animal()` and `new Rabbit()`, the `alert` in the line `(*)` shows `animal`. + +**In other words, parent constructor always uses its own field value, not the overridden one.** + +What's odd about it? + +If it's not clear yet, please compare with methods. + +Here's the same code, but instead of `this.name` field we call `this.showName()` method: + +```js run +class Animal { + showName() { // instead of this.name = 'animal' + alert('animal'); + } + + constructor() { + this.showName(); // instead of alert(this.name); + } +} + +class Rabbit extends Animal { + showName() { + alert('rabbit'); + } +} + +new Animal(); // animal +*!* +new Rabbit(); // rabbit +*/!* +``` + +Please note: now the output is different. + +And that's what we naturally expect. When the parent constructor is called in the derived class, it uses the overridden method. + +...But for class fields it's not so. As said, the parent constructor always uses the parent field. + +Why is there the difference? + +Well, the reason is in the field initialization order. The class field is initialized: +- Before constructor for the base class (that doesn't extend anything), +- Immediately after `super()` for the derived class. + +In our case, `Rabbit` is the derived class. There's no `constructor()` in it. As said previously, that's the same as if there was an empty constructor with only `super(...args)`. + +So, `new Rabbit()` calls `super()`, thus executing the parent constructor, and (per the rule for derived classes) only after that its class fields are initialized. At the time of the parent constructor execution, there are no `Rabbit` class fields yet, that's why `Animal` fields are used. + +This subtle difference between fields and methods is specific to JavaScript + +Luckily, this behavior only reveals itself if an overridden field is used in the parent constructor. Then it may be difficult to understand what's going on, so we're explaining it here. + +If it becomes a problem, one can fix it by using methods or getters/setters instead of fields. + + ## Super: internals, [[HomeObject]] -Let's get a little deeper under the hood of `super`. We'll see some interesting things by the way. +```warn header="Advanced information" +If you're reading the tutorial for the first time - this section may be skipped. + +It's about the internal mechanisms behind inheritance and `super`. +``` + +Let's get a little deeper under the hood of `super`. We'll see some interesting things along the way. First to say, from all that we've learned till now, it's impossible for `super` to work. @@ -453,13 +531,72 @@ longEar.eat(); // Long Ear eats. Every method remembers its object in the internal `[[HomeObject]]` property. Then `super` uses it to resolve the parent prototype. -`[[HomeObject]]` is defined for methods defined both in classes and in plain objects. But for objects, methods must be specified exactly the given way: as `method()`, not as `"method: function()"`. +### Methods are not "free" + +As we've known before, generally functions are "free", not bound to objects in JavaScript. So they can be copied between objects and called with another `this`. + +The very existence of `[[HomeObject]]` violates that principle, because methods remember their objects. `[[HomeObject]]` can't be changed, so this bond is forever. + +The only place in the language where `[[HomeObject]]` is used -- is `super`. So, if a method does not use `super`, then we can still consider it free and copy between objects. But with `super` things may go wrong. + +Here's the demo of a wrong `super` result after copying: + +```js run +let animal = { + sayHi() { + alert(`I'm an animal`); + } +}; + +// rabbit inherits from animal +let rabbit = { + __proto__: animal, + sayHi() { + super.sayHi(); + } +}; + +let plant = { + sayHi() { + alert("I'm a plant"); + } +}; + +// tree inherits from plant +let tree = { + __proto__: plant, +*!* + sayHi: rabbit.sayHi // (*) +*/!* +}; + +*!* +tree.sayHi(); // I'm an animal (?!?) +*/!* +``` + +A call to `tree.sayHi()` shows "I'm an animal". Definitely wrong. + +The reason is simple: +- In the line `(*)`, the method `tree.sayHi` was copied from `rabbit`. Maybe we just wanted to avoid code duplication? +- Its `[[HomeObject]]` is `rabbit`, as it was created in `rabbit`. There's no way to change `[[HomeObject]]`. +- The code of `tree.sayHi()` has `super.sayHi()` inside. It goes up from `rabbit` and takes the method from `animal`. + +Here's the diagram of what happens: + +![](super-homeobject-wrong.svg) + +### Methods, not function properties + +`[[HomeObject]]` is defined for methods both in classes and in plain objects. But for objects, methods must be specified exactly as `method()`, not as `"method: function()"`. + +The difference may be non-essential for us, but it's important for JavaScript. In the example below a non-method syntax is used for comparison. `[[HomeObject]]` property is not set and the inheritance doesn't work: ```js run let animal = { - eat: function() { // should be the short syntax: eat() {...} + eat: function() { // intentionally writing like this instead of eat() {... // ... } }; @@ -475,3 +612,18 @@ let rabbit = { rabbit.eat(); // Error calling super (because there's no [[HomeObject]]) */!* ``` + +## Summary + +1. To extend a class: `class Child extends Parent`: + - That means `Child.prototype.__proto__` will be `Parent.prototype`, so methods are inherited. +2. When overriding a constructor: + - We must call parent constructor as `super()` in `Child` constructor before using `this`. +3. When overriding another method: + - We can use `super.method()` in a `Child` method to call `Parent` method. +4. Internals: + - Methods remember their class/object in the internal `[[HomeObject]]` property. That's how `super` resolves parent methods. + - So it's not safe to copy a method with `super` from one object to another. + +Also: +- Arrow functions don't have their own `this` or `super`, so they transparently fit into the surrounding context. diff --git a/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg b/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg index 6f2124ebb..10af6c4c2 100644 --- a/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg +++ b/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg @@ -1,41 +1 @@ - - - - class-inheritance-array-object.svg - Created with sketchtool. - - - - - slice: function - ... - - - Array.prototype - - - arr - - - - hasOwnProperty: function - ... - - - Object.prototype - - - - - - [1, 2, 3] - - - [[Prototype]] - - - [[Prototype]] - - - - \ No newline at end of file +slice: function ...Array.prototypearrhasOwnProperty: function ...Object.prototype[1, 2, 3][[Prototype]][[Prototype]] \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg index 9714d6708..a81676e25 100644 --- a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg +++ b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg @@ -1,62 +1 @@ - - - - class-inheritance-rabbit-animal-2.svg - Created with sketchtool. - - - - - jump: function - - - Rabbit.prototype - - - rabbit - - - - eat: function - - - Animal.prototype - - - - - - name: "White Rabbit" - - - [[Prototype]] - - - [[Prototype]] - - - Rabbit.prototype.__proto__ = Animal.prototype sets this - - - - toString: function - hasOwnProperty: function - ... - - - Object.prototype - - - - [[Prototype]] - - - - [[Prototype]] - - - null - - - - \ No newline at end of file +jump: functionRabbit.prototyperabbiteat: functionAnimal.prototypename: "White Rabbit"[[Prototype]][[Prototype]]Rabbit.prototype.__proto__ = Animal.prototype sets thistoString: function hasOwnProperty: function ...Object.prototype[[Prototype]][[Prototype]]null \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg index 249bfa4c9..35529aa43 100644 --- a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg +++ b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg @@ -1,39 +1 @@ - - - - class-inheritance-rabbit-animal.svg - Created with sketchtool. - - - - - methods of Rabbit - - - Rabbit.prototype - - - rabbit - - - - methods of Animal - - - Animal.prototype - - - - - - [[Prototype]] - - - [[Prototype]] - - - properties of rabbit - - - - \ No newline at end of file +methods of RabbitRabbit.prototyperabbitmethods of AnimalAnimal.prototype[[Prototype]][[Prototype]]properties of rabbit \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg index 7a16b7855..905efe37a 100644 --- a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg +++ b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg @@ -1,42 +1 @@ - - - - rabbit-animal-independent-animal.svg - Created with sketchtool. - - - - - - constructor: Animal - run: function - stop: function - - - Animal.prototype - - - - Animal - - - - new Animal - - - - - [[Prototype]] - - - prototype - - - name: "My animal" - - - constructor - - - - \ No newline at end of file + constructor: Animal run: function stop: functionAnimal.prototypeAnimalnew Animal[[Prototype]]prototypename: "My animal" \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg index ab936c151..81bf1850b 100644 --- a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg +++ b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg @@ -1,41 +1 @@ - - - - rabbit-animal-independent-rabbit.svg - Created with sketchtool. - - - - - - constructor: Rabbit - hide: function - - - Rabbit.prototype - - - - Rabbit - - - - new Rabbit - - - - - [[Prototype]] - - - prototype - - - name: "My rabbit" - - - constructor - - - - \ No newline at end of file + constructor: Rabbit hide: functionRabbit.prototypeRabbitnew Rabbit[[Prototype]]prototypename: "My rabbit" \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg b/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg new file mode 100644 index 000000000..f13d441c9 --- /dev/null +++ b/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg @@ -0,0 +1 @@ +sayHiplantsayHitreesayHianimalrabbit[[HomeObject]]sayHi \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/this-super-loop.svg b/1-js/09-classes/02-class-inheritance/this-super-loop.svg index 7862b41c0..bc200fab3 100644 --- a/1-js/09-classes/02-class-inheritance/this-super-loop.svg +++ b/1-js/09-classes/02-class-inheritance/this-super-loop.svg @@ -1,72 +1 @@ - - - - this-super-loop.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - rabbit - - - longEar - - - rabbit - - - longEar - - - - - - - - \ No newline at end of file +rabbitlongEarrabbitlongEar \ No newline at end of file diff --git a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg new file mode 100644 index 000000000..34d783b4d --- /dev/null +++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg @@ -0,0 +1 @@ +call: function bind: function ...Function.prototypeconstructorObjectRabbit[[Prototype]][[Prototype]]constructorcall: function bind: function ...Function.prototypeRabbit[[Prototype]]constructorclass Rabbitclass Rabbit extends Object \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md similarity index 97% rename from 1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md rename to 1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md index fa26ec834..ca9e80601 100644 --- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md +++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md @@ -26,7 +26,7 @@ Even after the fix, there's still important difference in `"class Rabbit extends As we know, the "extends" syntax sets up two prototypes: 1. Between `"prototype"` of the constructor functions (for methods). -2. Between the constructor functions itself (for static methods). +2. Between the constructor functions themselves (for static methods). In our case, for `class Rabbit extends Object` it means: diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md similarity index 88% rename from 1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md rename to 1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md index ca6628edf..1d0f98a74 100644 --- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md +++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md @@ -1,4 +1,4 @@ -importance: 5 +importance: 3 --- @@ -19,7 +19,6 @@ let rabbit = new Rabbit("Rab"); *!* // hasOwnProperty method is from Object.prototype -// rabbit.__proto__ === Object.prototype alert( rabbit.hasOwnProperty('name') ); // true */!* ``` @@ -39,5 +38,5 @@ class Rabbit extends Object { let rabbit = new Rabbit("Rab"); -alert( rabbit.hasOwnProperty('name') ); // true +alert( rabbit.hasOwnProperty('name') ); // Error ``` diff --git a/1-js/09-classes/03-static-properties-methods/animal-rabbit-static.svg b/1-js/09-classes/03-static-properties-methods/animal-rabbit-static.svg index 1e868cce2..18093d7cf 100644 --- a/1-js/09-classes/03-static-properties-methods/animal-rabbit-static.svg +++ b/1-js/09-classes/03-static-properties-methods/animal-rabbit-static.svg @@ -1,64 +1 @@ - - - - animal-rabbit-static.svg - Created with sketchtool. - - - - - constructor: Animal - run: function - - - - Animal.prototype - - - - constructor: Rabbit - hide: function - - - Rabbit.prototype - - - - Animal - - - - Rabbit - - - rabbit - - - - - [[Prototype]] - - - - [[Prototype]] - - - - [[Prototype]] - - - prototype - - - - prototype - - - compare - - - name: "White Rabbit" - - - - \ No newline at end of file +constructor: Animal run: functionAnimal.prototypeconstructor: Rabbit hide: functionRabbit.prototypeAnimalRabbitrabbit[[Prototype]][[Prototype]][[Prototype]]prototypeprototypecomparename: "White Rabbit" \ No newline at end of file diff --git a/1-js/09-classes/03-static-properties-methods/article.md b/1-js/09-classes/03-static-properties-methods/article.md index 6ccf4fd71..0cf990720 100644 --- a/1-js/09-classes/03-static-properties-methods/article.md +++ b/1-js/09-classes/03-static-properties-methods/article.md @@ -19,12 +19,14 @@ User.staticMethod(); // true That actually does the same as assigning it as a function property: -```js -function User() { } +```js run +class User { } User.staticMethod = function() { alert(this === User); }; + +User.staticMethod(); // true ``` The value of `this` inside `User.staticMethod()` is the class constructor `User` itself (the "object before dot" rule). @@ -90,7 +92,7 @@ class Article { let article = Article.createTodays(); -alert( article.title ); // Todays digest +alert( article.title ); // Today's digest ``` Now every time we need to create a today's digest, we can call `Article.createTodays()`. Once again, that's not a method of an article, but a method of the whole class. @@ -123,14 +125,15 @@ That is the same as a direct assignment to `Article`: Article.publisher = "Ilya Kantor"; ``` -## Statics and inheritance +## Inheritance of static properties and methods -Statics are inherited, we can access `Parent.method` as `Child.method`. +Static properties and methods are inherited. -For instance, `Animal.compare` in the code below is inherited and accessible as `Rabbit.compare`: +For instance, `Animal.compare` and `Animal.planet` in the code below are inherited and accessible as `Rabbit.compare` and `Rabbit.planet`: ```js run class Animal { + static planet = "Earth"; constructor(name, speed) { this.speed = speed; @@ -167,16 +170,18 @@ rabbits.sort(Rabbit.compare); */!* rabbits[0].run(); // Black Rabbit runs with speed 5. + +alert(Rabbit.planet); // Earth ``` -Now we can call `Rabbit.compare` assuming that the inherited `Animal.compare` will be called. +Now when we call `Rabbit.compare`, the inherited `Animal.compare` will be called. How does it work? Again, using prototypes. As you might have already guessed, extends also gives `Rabbit` the `[[Prototype]]` reference to `Animal`. ![](animal-rabbit-static.svg) -So, `Rabbit` function now inherits from `Animal` function. And `Animal` function normally has `[[Prototype]]` referencing `Function.prototype`, because it doesn't `extend` anything. +As a result, inheritance works both for regular and static methods. Here, let's check that: @@ -187,14 +192,13 @@ class Rabbit extends Animal {} // for static properties and methods alert(Rabbit.__proto__ === Animal); // true -// and the next step is Function.prototype -alert(Animal.__proto__ === Function.prototype); // true - -// that's in addition to the "normal" prototype chain for object methods -alert(Rabbit.prototype.__proto__ === Animal.prototype); +// for regular methods +alert(Rabbit.prototype.__proto__ === Animal.prototype); // true ``` -This way `Rabbit` has access to all static methods of `Animal`. +## Summary + +Static methods are used for the functionality that belongs to the class "as a whole". It doesn't relate to a concrete class instance. ## Summary diff --git a/1-js/09-classes/04-private-protected-properties-methods/article.md b/1-js/09-classes/04-private-protected-properties-methods/article.md index 6cd9cc5fb..2d47464c4 100644 --- a/1-js/09-classes/04-private-protected-properties-methods/article.md +++ b/1-js/09-classes/04-private-protected-properties-methods/article.md @@ -48,16 +48,16 @@ So, all we need to use an object is to know its external interface. We may be co That was a general introduction. -In JavaScript, there are three types of properties and members: +In JavaScript, there are two types of object fields (properties and methods): -- Public: accessible from anywhere. They comprise the external interface. Till now we were only using public properties and methods. +- Public: accessible from anywhere. They comprise the external interface. Until now we were only using public properties and methods. - Private: accessible only from inside the class. These are for the internal interface. -In many other languages there also exist "protected" fields: accessible only from inside the class and those extending it. They are also useful for the internal interface. They are in a sense more widespread than private ones, because we usually want inheriting classes to gain access to properly do the extension. +In many other languages there also exist "protected" fields: accessible only from inside the class and those extending it (like private, but plus access from inheriting classes). They are also useful for the internal interface. They are in a sense more widespread than private ones, because we usually want inheriting classes to gain access to them. Protected fields are not implemented in JavaScript on the language level, but in practice they are very convenient, so they are emulated. -In the next step we'll make a coffee machine in JavaScript with all these types of properties. A coffee machine has a lot of details, we won't model them to stay simple (though we could). +Now we'll make a coffee machine in JavaScript with all these types of properties. A coffee machine has a lot of details, we won't model them to stay simple (though we could). ## Protecting "waterAmount" @@ -87,7 +87,7 @@ Let's change `waterAmount` property to protected to have more control over it. F **Protected properties are usually prefixed with an underscore `_`.** -That is not enforced on the language level, but there's a convention that such properties and methods should not be accessed from the outside. Most programmers follow it. +That is not enforced on the language level, but there's a well-known convention between programmers that such properties and methods should not be accessed from the outside. So our property will be called `_waterAmount`: @@ -96,7 +96,9 @@ class CoffeeMachine { _waterAmount = 0; set waterAmount(value) { - if (value < 0) throw new Error("Negative water"); + if (value < 0) { + value = 0; + } this._waterAmount = value; } @@ -117,7 +119,7 @@ let coffeeMachine = new CoffeeMachine(100); coffeeMachine.waterAmount = -10; // Error: Negative water ``` -Now the access is under control, so setting the water below zero fails. +Now the access is under control, so setting the water amount below zero becomes impossible. ## Read-only "power" @@ -159,21 +161,21 @@ class CoffeeMachine { _waterAmount = 0; *!*setWaterAmount(value)*/!* { - if (value < 0) throw new Error("Negative water"); + if (value < 0) value = 0; this._waterAmount = value; } *!*getWaterAmount()*/!* { - return this.waterAmount; + return this._waterAmount; } } new CoffeeMachine().setWaterAmount(100); ``` -That looks a bit longer, but functions are more flexible. They can accept multiple arguments (even if we don't need them right now). So, for the future, just in case we need to refactor something, functions are a safer choise. +That looks a bit longer, but functions are more flexible. They can accept multiple arguments (even if we don't need them right now). -Surely, there's a tradeoff. On the other hand, get/set syntax is shorter, so ultimately there's no strict rule, it's up to you to decide. +On the other hand, get/set syntax is shorter, so ultimately there's no strict rule, it's up to you to decide. ```` ```smart header="Protected fields are inherited" @@ -190,32 +192,23 @@ There's a finished JavaScript proposal, almost in the standard, that provides la Privates should start with `#`. They are only accessible from inside the class. -For instance, here we add a private `#waterLimit` property and extract the water-checking logic into a separate method: +For instance, here's a private `#waterLimit` property and the water-checking private method `#checkWater`: -```js +```js run class CoffeeMachine { *!* #waterLimit = 200; */!* *!* - #checkWater(value) { - if (value < 0) throw new Error("Negative water"); - if (value > this.#waterLimit) throw new Error("Too much water"); + #fixWaterAmount(value) { + if (value < 0) return 0; + if (value > this.#waterLimit) return this.#waterLimit; } */!* - _waterAmount = 0; - - set waterAmount(value) { -*!* - this.#checkWater(value); -*/!* - this._waterAmount = value; - } - - get waterAmount() { - return this.waterAmount; + setWaterAmount(value) { + this.#waterLimit = this.#fixWaterAmount(value); } } @@ -223,11 +216,10 @@ class CoffeeMachine { let coffeeMachine = new CoffeeMachine(); *!* -coffeeMachine.#checkWater(); // Error +// can't access privates from outside of the class +coffeeMachine.#fixWaterAmount(123); // Error coffeeMachine.#waterLimit = 1000; // Error */!* - -coffeeMachine.waterAmount = 100; // Works ``` On the language level, `#` is a special sign that the field is private. We can't access it from outside or from inheriting classes. @@ -246,7 +238,7 @@ class CoffeeMachine { } set waterAmount(value) { - if (value < 0) throw new Error("Negative water"); + if (value < 0) value = 0; this.#waterAmount = value; } } @@ -262,7 +254,7 @@ Unlike protected ones, private fields are enforced by the language itself. That' But if we inherit from `CoffeeMachine`, then we'll have no direct access to `#waterAmount`. We'll need to rely on `waterAmount` getter/setter: ```js -class CoffeeMachine extends CoffeeMachine() { +class MegaCoffeeMachine extends CoffeeMachine { method() { *!* alert( this.#waterAmount ); // Error: can only access from CoffeeMachine @@ -271,19 +263,19 @@ class CoffeeMachine extends CoffeeMachine() { } ``` -In many scenarios such limitation is too severe. If we extend a `CoffeeMachine`, we may have legitimate reason to access its internals. That's why protected fields are used most of the time, even though they are not supported by the language syntax. +In many scenarios such limitation is too severe. If we extend a `CoffeeMachine`, we may have legitimate reasons to access its internals. That's why protected fields are used more often, even though they are not supported by the language syntax. -````warn +````warn header="Private fields are not available as this[name]" Private fields are special. -Remember, usually we can access fields by this[name]: +As we know, usually we can access fields using `this[name]`: ```js class User { ... sayHi() { let fieldName = "name"; - alert(`Hello, ${this[fieldName]}`); + alert(`Hello, ${*!*this[fieldName]*/!*}`); } } ``` @@ -293,11 +285,11 @@ With private fields that's impossible: `this['#name']` doesn't work. That's a sy ## Summary -In terms of OOP, delimiting of the internal interface from the external one is called [encapsulation]("https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)"). +In terms of OOP, delimiting of the internal interface from the external one is called [encapsulation](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)). It gives the following benefits: -Protection for users, so that they don't shoot themselves in the feet +Protection for users, so that they don't shoot themselves in the foot : Imagine, there's a team of developers using a coffee machine. It was made by the "Best CoffeeMachine" company, and works fine, but a protective cover was removed. So the internal interface is exposed. All developers are civilized -- they use the coffee machine as intended. But one of them, John, decided that he's the smartest one, and made some tweaks in the coffee machine internals. So the coffee machine failed two days later. @@ -309,22 +301,22 @@ Protection for users, so that they don't shoot themselves in the feet Supportable : The situation in programming is more complex than with a real-life coffee machine, because we don't just buy it once. The code constantly undergoes development and improvement. - **If we strictly delimit the internal interface, then the developer of the class can freely change its internal properties and methods, even without informing the users..** + **If we strictly delimit the internal interface, then the developer of the class can freely change its internal properties and methods, even without informing the users.** - It's much easier to develop, if you know that certain methods can be renamed, their parameters can be changed, and even removed, because no external code depends on them. + If you're a developer of such class, it's great to know that private methods can be safely renamed, their parameters can be changed, and even removed, because no external code depends on them. - For users, when a new version comes out, it may be a total overhaul, but still simple to upgrade if the external interface is the same. + For users, when a new version comes out, it may be a total overhaul internally, but still simple to upgrade if the external interface is the same. Hiding complexity -: People adore to use things that are simple. At least from outside. What's inside is a different thing. +: People adore using things that are simple. At least from outside. What's inside is a different thing. Programmers are not an exception. **It's always convenient when implementation details are hidden, and a simple, well-documented external interface is available.** -To hide internal interface we use either protected or public properties: +To hide an internal interface we use either protected or private properties: - Protected fields start with `_`. That's a well-known convention, not enforced at the language level. Programmers should only access a field starting with `_` from its class and classes inheriting from it. -- Private fields start with `#`. JavaScript makes sure we only can access those from inside the class. +- Private fields start with `#`. JavaScript makes sure we can only access those from inside the class. Right now, private fields are not well-supported among browsers, but can be polyfilled. diff --git a/1-js/09-classes/05-extend-natives/article.md b/1-js/09-classes/05-extend-natives/article.md index 4cf1c2bdd..36c97b0cf 100644 --- a/1-js/09-classes/05-extend-natives/article.md +++ b/1-js/09-classes/05-extend-natives/article.md @@ -21,7 +21,7 @@ alert(filteredArr); // 10, 50 alert(filteredArr.isEmpty()); // false ``` -Please note a very interesting thing. Built-in methods like `filter`, `map` and others -- return new objects of exactly the inherited type. They rely on the `constructor` property to do so. +Please note a very interesting thing. Built-in methods like `filter`, `map` and others -- return new objects of exactly the inherited type `PowerArray`. Their internal implementation uses the object's `constructor` property for that. In the example above, ```js @@ -33,7 +33,7 @@ That's actually very cool, because we can keep using `PowerArray` methods furthe Even more, we can customize that behavior. -There's a special static getter `Symbol.species`, if exists, it returns the constructor to use in such cases. +We can add a special static getter `Symbol.species` to the class. If it exists, it should return the constructor that JavaScript will use internally to create new entities in `map`, `filter` and so on. If we'd like built-in methods like `map`, `filter` will return regular arrays, we can return `Array` in `Symbol.species`, like here: @@ -71,9 +71,11 @@ Built-in objects have their own static methods, for instance `Object.keys`, `Arr And we've already been talking about native classes extending each other: `Array.[[Prototype]] = Object`. -But statics are an exception. Built-in classes don't inherit static properties from each other. +Normally, when one class extends another, both static and non-static methods are inherited. That was thoroughly explained in the article [](info:static-properties-methods#statics-and-inheritance). -In other words, the prototype of built-in constructor `Array` does not point to `Object`. This way `Array` and `Date` do not have `Array.keys` or `Date.keys`. And that feels natural. +But built-in classes are an exception. They don't inherit statics from each other. + +For example, both `Array` and `Date` inherit from `Object`, so their instances have methods from `Object.prototype`. But `Array.[[Prototype]]` does not reference `Object`, so there's no, for instance, `Array.keys()` (or `Date.keys()`) static method. Here's the picture structure for `Date` and `Object`: diff --git a/1-js/09-classes/05-extend-natives/object-date-inheritance.svg b/1-js/09-classes/05-extend-natives/object-date-inheritance.svg index f46577f14..470aabf7f 100644 --- a/1-js/09-classes/05-extend-natives/object-date-inheritance.svg +++ b/1-js/09-classes/05-extend-natives/object-date-inheritance.svg @@ -1,71 +1 @@ - - - - object-date-inheritance.svg - Created with sketchtool. - - - - - constructor: Object - toString: function - hasOwnProperty: function - ... - - - - Object.prototype - - - - constructor: Date - toString: function - getDate: function - ... - - - Date.prototype - - - - Object - - - - Date - - - new Date() - - - - - [[Prototype]] - - - - [[Prototype]] - - - prototype - - - - prototype - - - defineProperty - keys - ... - - - now - parse - ... - - - 1 Jan 2019 - - - - \ No newline at end of file +constructor: Object toString: function hasOwnProperty: function ...Object.prototypeconstructor: Date toString: function getDate: function ...Date.prototypeObjectDatenew Date()[[Prototype]][[Prototype]]prototypeprototypedefineProperty keys ...now parse ...1 Jan 2019 \ No newline at end of file diff --git a/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md b/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md index e9481912a..5b8dc7de3 100644 --- a/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md +++ b/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md @@ -4,7 +4,7 @@ importance: 5 # Strange instanceof -Why `instanceof` below returns `true`? We can easily see that `a` is not created by `B()`. +In the code below, why does `instanceof` return `true`? We can easily see that `a` is not created by `B()`. ```js run function A() {} diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md index e7800535d..382c6798b 100644 --- a/1-js/09-classes/06-instanceof/article.md +++ b/1-js/09-classes/06-instanceof/article.md @@ -2,7 +2,7 @@ The `instanceof` operator allows to check whether an object belongs to a certain class. It also takes inheritance into account. -Such a check may be necessary in many cases, here we'll use it for building a *polymorphic* function, the one that treats arguments differently depending on their type. +Such a check may be necessary in many cases. For example, it can be used for building a *polymorphic* function, the one that treats arguments differently depending on their type. ## The instanceof operator [#ref-instanceof] @@ -44,9 +44,9 @@ alert( arr instanceof Array ); // true alert( arr instanceof Object ); // true ``` -Please note that `arr` also belongs to the `Object` class. That's because `Array` prototypally inherits from `Object`. +Please note that `arr` also belongs to the `Object` class. That's because `Array` prototypically inherits from `Object`. -The `instanceof` operator examines the prototype chain for the check, and is also fine-tunable using the static method `Symbol.hasInstance`. +Normally, `instanceof` examines the prototype chain for the check. We can also set a custom logic in the static method `Symbol.hasInstance`. The algorithm of `obj instanceof Class` works roughly as follows: @@ -64,7 +64,7 @@ The algorithm of `obj instanceof Class` works roughly as follows: alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) is called ``` -2. Most classes do not have `Symbol.hasInstance`. In that case, check if `Class.prototype` equals to one of prototypes in the `obj` prototype chain. +2. Most classes do not have `Symbol.hasInstance`. In that case, the standard logic is used: `obj instanceOf Class` checks whether `Class.prototype` is equal to one of the prototypes in the `obj` prototype chain. In other words, compare: ```js @@ -96,9 +96,9 @@ Here's the illustration of what `rabbit instanceof Animal` compares with `Animal By the way, there's also a method [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf), that returns `true` if `objA` is somewhere in the chain of prototypes for `objB`. So the test of `obj instanceof Class` can be rephrased as `Class.prototype.isPrototypeOf(obj)`. -That's funny, but the `Class` constructor itself does not participate in the check! Only the chain of prototypes and `Class.prototype` matters. +It's funny, but the `Class` constructor itself does not participate in the check! Only the chain of prototypes and `Class.prototype` matters. -That can lead to interesting consequences when `prototype` is changed. +That can lead to interesting consequences when a `prototype` property is changed after the object is created. Like here: @@ -179,11 +179,11 @@ let user = { alert( {}.toString.call(user) ); // [object User] ``` -For most environment-specific objects, there is such a property. Here are few browser specific examples: +For most environment-specific objects, there is such a property. Here are some browser specific examples: ```js run -// toStringTag for the envinronment-specific object and class: -alert( window[Symbol.toStringTag]); // window +// toStringTag for the environment-specific object and class: +alert( window[Symbol.toStringTag]); // Window alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest alert( {}.toString.call(window) ); // [object Window] diff --git a/1-js/09-classes/06-instanceof/instanceof.svg b/1-js/09-classes/06-instanceof/instanceof.svg index b291384f2..78bff9f12 100644 --- a/1-js/09-classes/06-instanceof/instanceof.svg +++ b/1-js/09-classes/06-instanceof/instanceof.svg @@ -1,51 +1 @@ - - - - instanceof.svg - Created with sketchtool. - - - - - Animal.prototype - - - - Object.prototype - - - - - Rabbit.prototype - - - - [[Prototype]] - - - - rabbit - - - - [[Prototype]] - - - [[Prototype]] - - - - null - - - [[Prototype]] - - - = Animal.prototype? - - - - - - - \ No newline at end of file +Animal.prototypeObject.prototypeRabbit.prototype[[Prototype]]rabbit[[Prototype]][[Prototype]]null[[Prototype]]= Animal.prototype? \ No newline at end of file diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 2502c3982..bcb75c06a 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -2,11 +2,8 @@ In JavaScript we can only inherit from a single object. There can be only one `[[Prototype]]` for an object. And a class may extend only one other class. -<<<<<<< HEAD But sometimes that feels limiting. For instance, I have a class `StreetSweeper` and a class `Bicycle`, and want to make a `StreetSweepingBicycle`. -======= But sometimes that feels limiting. For instance, we have a class `StreetSweeper` and a class `Bicycle`, and want to make their mix: a `StreetSweepingBicycle`. ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 Or, talking about programming, we have a class `Renderer` that implements templating and a class `EventEmitter` that implements event handling, and want to merge these functionalities together with a class `Page`, to make a page that can use templates and emit events. @@ -103,17 +100,21 @@ Please note that the call to the parent method `super.say()` from `sayHiMixin` l ![](mixin-inheritance.svg) -That's because methods from `sayHiMixin` have `[[HomeObject]]` set to it. So `super` actually means `sayHiMixin.__proto__`, not `User.__proto__`. +That's because methods `sayHi` and `sayBye` were initially created in `sayHiMixin`. So even though they got copied, their `[[HomeObject]]` internal property references `sayHiMixin`, as shown in the picture above. + +As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`, not `User.[[Prototype]]`. ## EventMixin Now let's make a mixin for real life. -The important feature of many objects is working with events. +An important feature of many browser objects (for instance) is that they can generate events. Events are a great way to "broadcast information" to anyone who wants it. So let's make a mixin that allows us to easily add event-related functions to any class/object. -That is: an object should have a method to "generate an event" when something important happens to it, and other objects should be able to "listen" to such events. +- The mixin will provide a method `.trigger(name, [...data])` to "generate an event" when something important happens to it. The `name` argument is a name of the event, optionally followed by additional arguments with event data. +- Also the method `.on(name, handler)` that adds `handler` function as the listener to events with the given name. It will be called when an event with the given `name` triggers, and get the arguments from the `.trigger` call. +- ...And the method `.off(name, handler)` that removes the `handler` listener. -An event must have a name and, optionally, bundle some additional data. +After adding the mixin, an object `user` will be able to generate an event `"login"` when the visitor logs in. And another object, say, `calendar` may want to listen for such events to load the calendar for the logged-in person. For instance, an object `user` can generate an event `"login"` when the visitor logs in. And another object `calendar` may want to receive such events to load the calendar for the logged-in person. @@ -140,7 +141,7 @@ let eventMixin = { * menu.off('select', handler) */ off(eventName, handler) { - let handlers = this._eventHandlers && this._eventHandlers[eventName]; + let handlers = this._eventHandlers?.[eventName]; if (!handlers) return; for (let i = 0; i < handlers.length; i++) { if (handlers[i] === handler) { @@ -154,7 +155,7 @@ let eventMixin = { * this.trigger('select', data1, data2); */ trigger(eventName, ...args) { - if (!this._eventHandlers || !this._eventHandlers[eventName]) { + if (!this._eventHandlers?.[eventName]) { return; // no handlers for that event name } @@ -170,6 +171,9 @@ There are 3 methods here: 2. `.off(eventName, handler)` -- removes the function from the handlers list. 3. `.trigger(eventName, ...args)` -- generates the event: all assigned handlers are called and `args` are passed as arguments to them. +- `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name occurs. Technically, there's an `_eventHandlers` property that stores an array of handlers for each event name, and it just adds it to the list. +- `.off(eventName, handler)` -- removes the function from the handlers list. +- `.trigger(eventName, ...args)` -- generates the event: all handlers from `_eventHandlers[eventName]` are called, with a list of arguments `...args`. Usage: @@ -194,7 +198,7 @@ menu.on("select", value => alert(`Value selected: ${value}`)); menu.choose("123"); // value selected ``` -Now if we have the code interested to react on user selection, we can bind it with `menu.on(...)`. +Now, if we'd like any code to react to a menu selection, we can listen for it with `menu.on(...)`. And the `eventMixin` can add such behavior to as many classes as we'd like, without interfering with the inheritance chain. @@ -202,8 +206,8 @@ And the `eventMixin` can add such behavior to as many classes as we'd like, with *Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes. -Some other languages like e.g. python allow to create mixins using multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying them into the prototype. +Some other languages allow multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype. -We can use mixins as a way to augment a class by multiple behaviors, like event-handling as we have seen above. +We can use mixins as a way to augment a class by adding multiple behaviors, like event-handling as we have seen above. -Mixins may become a point of conflict if they occasionally overwrite native class methods. So generally one should think well about the naming for a mixin, to minimize such possibility. +Mixins may become a point of conflict if they accidentally overwrite existing class methods. So generally one should think well about the naming methods of a mixin, to minimize the probability of that happening. diff --git a/1-js/09-classes/07-mixins/head.html b/1-js/09-classes/07-mixins/head.html index 77ea38b20..20e3a6354 100644 --- a/1-js/09-classes/07-mixins/head.html +++ b/1-js/09-classes/07-mixins/head.html @@ -18,7 +18,7 @@ * menu.off('select', handler) */ off(eventName, handler) { - let handlers = this._eventHandlers && this._eventHandlers[eventName]; + let handlers = this._eventHandlers?.[eventName]; if (!handlers) return; for(let i = 0; i < handlers.length; i++) { if (handlers[i] == handler) { diff --git a/1-js/09-classes/07-mixins/mixin-inheritance.svg b/1-js/09-classes/07-mixins/mixin-inheritance.svg index c1ce62f91..aaa8cb7d0 100644 --- a/1-js/09-classes/07-mixins/mixin-inheritance.svg +++ b/1-js/09-classes/07-mixins/mixin-inheritance.svg @@ -1,54 +1 @@ - - - - mixin-inheritance.svg - Created with sketchtool. - - - - - sayHi: function - sayBye: function - - - sayHiMixin - - - - say: function - - - sayMixin - - - - [[Prototype]] - - - - constructor: User - sayHi: function - sayBye: function - - - User.prototype - - - - - - [[Prototype]] - - - - name: ... - - - user - - - [[HomeObject] - - - - \ No newline at end of file +sayHi: function sayBye: functionsayHiMixinsay: functionsayMixin[[Prototype]]constructor: User sayHi: function sayBye: functionUser.prototype[[Prototype]]name: ...user[[HomeObject] \ No newline at end of file diff --git a/1-js/10-error-handling/1-try-catch/article.md b/1-js/10-error-handling/1-try-catch/article.md index 82941387a..9f200bab6 100644 --- a/1-js/10-error-handling/1-try-catch/article.md +++ b/1-js/10-error-handling/1-try-catch/article.md @@ -1,10 +1,10 @@ # Error handling, "try..catch" -No matter how great we are at programming, sometimes our scripts have errors. They may occur because of our mistakes, an unexpected user input, an erroneous server response and for a thousand of other reasons. +No matter how great we are at programming, sometimes our scripts have errors. They may occur because of our mistakes, an unexpected user input, an erroneous server response, and for a thousand other reasons. Usually, a script "dies" (immediately stops) in case of an error, printing it to console. -But there's a syntax construct `try..catch` that allows to "catch" errors and, instead of dying, do something more reasonable. +But there's a syntax construct `try..catch` that allows us to "catch" errors so the script can, instead of dying, do something more reasonable. ## The "try..catch" syntax @@ -25,14 +25,14 @@ try { It works like this: 1. First, the code in `try {...}` is executed. -2. If there were no errors, then `catch(err)` is ignored: the execution reaches the end of `try` and then jumps over `catch`. -3. If an error occurs, then `try` execution is stopped, and the control flows to the beginning of `catch(err)`. The `err` variable (can use any name for it) contains an error object with details about what's happened. +2. If there were no errors, then `catch(err)` is ignored: the execution reaches the end of `try` and goes on, skipping `catch`. +3. If an error occurs, then the `try` execution is stopped, and control flows to the beginning of `catch(err)`. The `err` variable (we can use any name for it) will contain an error object with details about what happened. ![](try-catch-flow.svg) -So, an error inside the `try {…}` block does not kill the script: we have a chance to handle it in `catch`. +So, an error inside the `try {…}` block does not kill the script -- we have a chance to handle it in `catch`. -Let's see more examples. +Let's look at some examples. - An errorless example: shows `alert` `(1)` and `(2)`: @@ -89,9 +89,9 @@ try { } ``` -The JavaScript engine first reads the code, and then runs it. The errors that occur on the reading phrase are called "parse-time" errors and are unrecoverable (from inside that code). That's because the engine can't understand the code. +The JavaScript engine first reads the code, and then runs it. The errors that occur on the reading phase are called "parse-time" errors and are unrecoverable (from inside that code). That's because the engine can't understand the code. -So, `try..catch` can only handle errors that occur in the valid code. Such errors are called "runtime errors" or, sometimes, "exceptions". +So, `try..catch` can only handle errors that occur in valid code. Such errors are called "runtime errors" or, sometimes, "exceptions". ```` @@ -205,7 +205,7 @@ You can find more detailed information about JSON in the chapter. **If `json` is malformed, `JSON.parse` generates an error, so the script "dies".** -Should we be satisfied with that? Of course, not! +Should we be satisfied with that? Of course not! This way, if something's wrong with the data, the visitor will never know that (unless they open the developer console). And people really don't like when something "just dies" without any error message. @@ -302,7 +302,7 @@ try { *!* alert(e.name); // SyntaxError */!* - alert(e.message); // Unexpected token o in JSON at position 2 + alert(e.message); // Unexpected token b in JSON at position 2 } ``` @@ -338,9 +338,9 @@ Now `catch` became a single place for all error handling: both for `JSON.parse` ## Rethrowing -In the example above we use `try..catch` to handle incorrect data. But is it possible that *another unexpected error* occurs within the `try {...}` block? Like a variable is undefined or something else, not just that "incorrect data" thing. +In the example above we use `try..catch` to handle incorrect data. But is it possible that *another unexpected error* occurs within the `try {...}` block? Like a programming error (variable is not defined) or something else, not just this "incorrect data" thing. -Like this: +For example: ```js run let json = '{ "age": 30 }'; // incomplete data @@ -357,29 +357,33 @@ try { Of course, everything's possible! Programmers do make mistakes. Even in open-source utilities used by millions for decades -- suddenly a crazy bug may be discovered that leads to terrible hacks (like it happened with the `ssh` tool). -In our case, `try..catch` is meant to catch "incorrect data" errors. But by its nature, `catch` gets *all* errors from `try`. Here it gets an unexpected error, but still shows the same `"JSON Error"` message. That's wrong and also makes the code more difficult to debug. +In our case, `try..catch` is placed to catch "incorrect data" errors. But by its nature, `catch` gets *all* errors from `try`. Here it gets an unexpected error, but still shows the same `"JSON Error"` message. That's wrong and also makes the code more difficult to debug. + +To avoid such problems, we can employ the "rethrowing" technique. The rule is simple: -Fortunately, we can find out which error we get, for instance from its `name`: +**Catch should only process errors that it knows and "rethrow" all others.** + +The "rethrowing" technique can be explained in more detail as: + +1. Catch gets all errors. +2. In the `catch(err) {...}` block we analyze the error object `err`. +3. If we don't know how to handle it, we do `throw err`. + +Usually, we can check the error type using the `instanceof` operator: ```js run try { user = { /*...*/ }; -} catch(e) { +} catch(err) { *!* - alert(e.name); // "ReferenceError" for accessing an undefined variable + if (err instanceof ReferenceError) { */!* + alert('ReferenceError'); // "ReferenceError" for accessing an undefined variable + } } ``` -The rule is simple: - -**Catch should only process errors that it knows and "rethrow" all others.** - -The "rethrowing" technique can be explained in more detail as: - -1. Catch gets all errors. -2. In `catch(err) {...}` block we analyze the error object `err`. -2. If we don't know how to handle it, then we do `throw err`. +We can also get the error class name from `err.name` property. All native errors have it. Another option is to read `err.constructor.name`. In the code below, we use rethrowing so that `catch` only handles `SyntaxError`: @@ -402,7 +406,7 @@ try { } catch(e) { *!* - if (e.name == "SyntaxError") { + if (e instanceof SyntaxError) { alert( "JSON Error: " + e.message ); } else { throw e; // rethrow (*) @@ -429,7 +433,7 @@ function readData() { */!* } catch (e) { // ... - if (e.name != 'SyntaxError') { + if (!(e instanceof SyntaxError)) { *!* throw e; // rethrow (don't know how to deal with it) */!* @@ -526,7 +530,7 @@ alert(result || "error occured"); alert( `execution took ${diff}ms` ); ``` -You can check by running the code with entering `35` into `prompt` -- it executes normally, `finally` after `try`. And then enter `-1` -- there will be an immediate error, an the execution will take `0ms`. Both measurements are done correctly. +You can check by running the code with entering `35` into `prompt` -- it executes normally, `finally` after `try`. And then enter `-1` -- there will be an immediate error, and the execution will take `0ms`. Both measurements are done correctly. In other words, there may be two ways to exit a function: either a `return` or `throw`. The `finally` clause handles them both. @@ -586,11 +590,11 @@ In the code above, an error inside `try` always falls out, because there's no `c The information from this section is not a part of the core JavaScript. ``` -Let's imagine we've got a fatal error outside of `try..catch`, and the script died. Like a programming error or something else terrible. +Let's imagine we've got a fatal error outside of `try..catch`, and the script died. Like a programming error or some other terrible thing. -Is there a way to react on such occurrences? We may want to log the error, show something to the user (normally they don't see error messages) etc. +Is there a way to react on such occurrences? We may want to log the error, show something to the user (normally they don't see error messages), etc. -There is none in the specification, but environments usually provide it, because it's really useful. For instance, Node.js has [process.on('uncaughtException')](https://nodejs.org/api/process.html#process_event_uncaughtexception) for that. And in the browser we can assign a function to special [window.onerror](mdn:api/GlobalEventHandlers/onerror) property. It will run in case of an uncaught error. +There is none in the specification, but environments usually provide it, because it's really useful. For instance, Node.js has [`process.on("uncaughtException")`](https://nodejs.org/api/process.html#process_event_uncaughtexception) for that. And in the browser we can assign a function to the special [window.onerror](mdn:api/GlobalEventHandlers/onerror) property, that will run in case of an uncaught error. The syntax: @@ -672,4 +676,4 @@ We can also generate our own errors using the `throw` operator. Technically, the Rethrowing is a basic pattern of error handling: a `catch` block usually expects and knows how to handle the particular error type, so it should rethrow errors it doesn't know. -Even if we don't have `try..catch`, most environments allow to setup a "global" error handler to catch errors that "fall out". In-browser that's `window.onerror`. +Even if we don't have `try..catch`, most environments allow us to setup a "global" error handler to catch errors that "fall out". In-browser, that's `window.onerror`. diff --git a/1-js/10-error-handling/1-try-catch/try-catch-flow.svg b/1-js/10-error-handling/1-try-catch/try-catch-flow.svg index 1db85eec7..ac816e356 100644 --- a/1-js/10-error-handling/1-try-catch/try-catch-flow.svg +++ b/1-js/10-error-handling/1-try-catch/try-catch-flow.svg @@ -1,58 +1 @@ - - - - try-catch-flow.svg - Created with sketchtool. - - - - - - Begin - - - - - - - - - - - - - - No Errors - - - - - - An error occured in the code - - - - - - - Ignore catch block - - - Ignore the rest of try - - - Execute catch block - - - try { - - - - } - - - // code... - - - - \ No newline at end of file +BeginNo ErrorsAn error occured in the codeIgnore catch blockIgnore the rest of tryExecute catch blocktry { }// code... \ No newline at end of file diff --git a/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md b/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md index bb6b74cfa..754e68f9a 100644 --- a/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md +++ b/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md @@ -2,7 +2,7 @@ class FormatError extends SyntaxError { constructor(message) { super(message); - this.name = "FormatError"; + this.name = this.constructor.name; } } diff --git a/1-js/10-error-handling/2-custom-errors/article.md b/1-js/10-error-handling/2-custom-errors/article.md index 5079c746d..8c89e30ef 100644 --- a/1-js/10-error-handling/2-custom-errors/article.md +++ b/1-js/10-error-handling/2-custom-errors/article.md @@ -2,11 +2,11 @@ When we develop something, we often need our own error classes to reflect specific things that may go wrong in our tasks. For errors in network operations we may need `HttpError`, for database operations `DbError`, for searching operations `NotFoundError` and so on. -Our errors should support basic error properties like `message`, `name` and, preferably, `stack`. But they also may have other properties of their own, e.g. `HttpError` objects may have `statusCode` property with a value like `404` or `403` or `500`. +Our errors should support basic error properties like `message`, `name` and, preferably, `stack`. But they also may have other properties of their own, e.g. `HttpError` objects may have a `statusCode` property with a value like `404` or `403` or `500`. JavaScript allows to use `throw` with any argument, so technically our custom error classes don't need to inherit from `Error`. But if we inherit, then it becomes possible to use `obj instanceof Error` to identify error objects. So it's better to inherit from it. -As we build our application, our own errors naturally form a hierarchy, for instance `HttpTimeoutError` may inherit from `HttpError`, and so on. +As the application grows, our own errors naturally form a hierarchy. For instance, `HttpTimeoutError` may inherit from `HttpError`, and so on. ## Extending Error @@ -25,9 +25,7 @@ Our function `readUser(json)` will not only read JSON, but check ("validate") th Our `ValidationError` class should inherit from the built-in `Error` class. -That class is built-in, but we should have its approximate code before our eyes, to understand what we're extending. - -So here you are: +That class is built-in, but here's its approximate code so we can understand what we're extending: ```js // The "pseudocode" for the built-in Error class defined by JavaScript itself @@ -185,7 +183,7 @@ try { The new class `PropertyRequiredError` is easy to use: we only need to pass the property name: `new PropertyRequiredError(property)`. The human-readable `message` is generated by the constructor. -Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = ` when creating each custom error. But there's a way out. We can make our own "basic error" class that removes this burden from our shoulders by using `this.constructor.name` for `this.name` in the constructor. And then inherit from it. +Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = ` in every custom error class. We can avoid it by making our own "basic error" class that assigns `this.name = this.constructor.name`. And then inherit all our custom errors from it. Let's call it `MyError`. @@ -220,11 +218,39 @@ Now custom errors are much shorter, especially `ValidationError`, as we got rid The purpose of the function `readUser` in the code above is "to read the user data", right? There may occur different kinds of errors in the process. Right now we have `SyntaxError` and `ValidationError`, but in the future `readUser` function may grow: the new code will probably generate other kinds of errors. -The code which calls `readUser` should handle these errors. Right now it uses multiple `if` in the `catch` block to check for different error types and rethrow the unknown ones. But if `readUser` function generates several kinds of errors -- then we should ask ourselves: do we really want to check for all error types one-by-one in every code that calls `readUser`? +The code which calls `readUser` should handle these errors. Right now it uses multiple `if`s in the `catch` block, that check the class and handle known errors and rethrow the unknown ones. + +The scheme is like this: + +```js +try { + ... + readUser() // the potential error source + ... +} catch (err) { + if (err instanceof ValidationError) { + // handle validation errors + } else if (err instanceof SyntaxError) { + // handle syntax errors + } else { + throw err; // unknown error, rethrow it + } +} +``` + +In the code above we can see two types of errors, but there can be more. + +If the `readUser` function generates several kinds of errors, then we should ask ourselves: do we really want to check for all error types one-by-one every time? + +Often the answer is "No": we'd like to be "one level above all that". We just want to know if there was a "data reading error" -- why exactly it happened is often irrelevant (the error message describes it). Or, even better, we'd like to have a way to get the error details, but only if we need to. + +The technique that we describe here is called "wrapping exceptions". -Often the answer is "No": the outer code wants to be "one level above all that". It wants to have some kind of "data reading error". Why exactly it happened -- is often irrelevant (the error message describes it). Or, even better if there is a way to get error details, but only if we need to. +1. We'll make a new class `ReadError` to represent a generic "data reading" error. +2. The function `readUser` will catch data reading errors that occur inside it, such as `ValidationError` and `SyntaxError`, and generate a `ReadError` instead. +3. The `ReadError` object will keep the reference to the original error in its `cause` property. -So let's make a new class `ReadError` to represent such errors. If an error occurs inside `readUser`, we'll catch it there and generate `ReadError`. We'll also keep the reference to the original error in its `cause` property. Then the outer code will only have to check for `ReadError`. +Then the code that calls `readUser` will only have to check for `ReadError`, not for every kind of data reading errors. And if it needs more details of an error, it can check its `cause` property. Here's the code that defines `ReadError` and demonstrates its use in `readUser` and `try..catch`: @@ -296,12 +322,12 @@ try { In the code above, `readUser` works exactly as described -- catches syntax and validation errors and throws `ReadError` errors instead (unknown errors are rethrown as usual). -So the outer code checks `instanceof ReadError` and that's it. No need to list possible all error types. +So the outer code checks `instanceof ReadError` and that's it. No need to list all possible error types. -The approach is called "wrapping exceptions", because we take "low level exceptions" and "wrap" them into `ReadError` that is more abstract and more convenient to use for the calling code. It is widely used in object-oriented programming. +The approach is called "wrapping exceptions", because we take "low level" exceptions and "wrap" them into `ReadError` that is more abstract. It is widely used in object-oriented programming. ## Summary -- We can inherit from `Error` and other built-in error classes normally, just need to take care of `name` property and don't forget to call `super`. -- Most of the time, we should use `instanceof` to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from the 3rd-party library and there's no easy way to get the class. Then `name` property can be used for such checks. -- Wrapping exceptions is a widespread technique when a function handles low-level exceptions and makes a higher-level object to report about the errors. Low-level exceptions sometimes become properties of that object like `err.cause` in the examples above, but that's not strictly required. +- We can inherit from `Error` and other built-in error classes normally. We just need to take care of the `name` property and don't forget to call `super`. +- We can use `instanceof` to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from a 3rd-party library and there's no easy way to get its class. Then `name` property can be used for such checks. +- Wrapping exceptions is a widespread technique: a function handles low-level exceptions and creates higher-level errors instead of various low-level ones. Low-level exceptions sometimes become properties of that object like `err.cause` in the examples above, but that's not strictly required. diff --git a/1-js/11-async/01-callbacks/article.md b/1-js/11-async/01-callbacks/article.md index 742b621b7..918b130ec 100644 --- a/1-js/11-async/01-callbacks/article.md +++ b/1-js/11-async/01-callbacks/article.md @@ -2,30 +2,44 @@ # Introduction: callbacks -Many actions in JavaScript are *asynchronous*. +```warn header="We use browser methods in examples here" +To demonstrate the use of callbacks, promises and other abstract concepts, we'll be using some browser methods: specifically, loading scripts and performing simple document manipulations. -For instance, take a look at the function `loadScript(src)`: +If you're not familiar with these methods, and their usage in the examples is confusing, you may want to read a few chapters from the [next part](/document) of the tutorial. + +Although, we'll try to make things clear anyway. There won't be anything really complex browser-wise. +``` + +Many functions are provided by JavaScript host environments that allow you to schedule *asynchronous* actions. In other words, actions that we initiate now, but they finish later. + +For instance, one such function is the `setTimeout` function. + +There are other real-world examples of asynchronous actions, e.g. loading scripts and modules (we'll cover them in later chapters). + +Take a look at the function `loadScript(src)`, that loads a script with the given `src`: ```js function loadScript(src) { + // creates a @@ -255,19 +264,21 @@ For instance: ``` -Please note: the second script actually works before the first! So we'll see `undefined` first, and then `object`. +Please note: the second script actually runs before the first! So we'll see `undefined` first, and then `object`. -That's because modules are deferred, so way wait for the document to be processed. The regular scripts runs immediately, so we saw its output first. +That's because modules are deferred, so we wait for the document to be processed. The regular script runs immediately, so we see its output first. -When using modules, we should be aware that HTML-document can show up before the JavaScript application is ready. Some functionality may not work yet. We should put transparent overlays or "loading indicators", or otherwise ensure that the visitor won't be confused because of it. +When using modules, we should be aware that the HTML page shows up as it loads, and JavaScript modules run after that, so the user may see the page before the JavaScript application is ready. Some functionality may not work yet. We should put "loading indicators", or otherwise ensure that the visitor won't be confused by that. ### Async works on inline scripts -Async attribute ` @@ -311,11 +322,11 @@ import {sayHi} from 'sayHi'; // Error, "bare" module // must be './sayHi.js' or wherever the module is ``` -Certain environments, like Node.js or bundle tools allow bare modules, as they have own ways for finding modules and hooks to fine-tune them. But browsers do not support bare modules yet. +Certain environments, like Node.js or bundle tools allow bare modules, without any path, as they have their own ways for finding modules and hooks to fine-tune them. But browsers do not support bare modules yet. ### Compatibility, "nomodule" -Old browsers do not understand `type="module"`. Scripts of the unknown type are just ignored. For them, it's possible to provide a fallback using `nomodule` attribute: +Old browsers do not understand `type="module"`. Scripts of an unknown type are just ignored. For them, it's possible to provide a fallback using the `nomodule` attribute: ```html run -``` - -If we change the text inside `me`, we'll get a single mutation: - -```js -mutationRecords = [{ - type: "characterData", - oldValue: "me", - target: , - // other properties empty -}]; -``` - -If we select and remove the `me` altogether, we'll get multiple mutations: - -```js -mutationRecords = [{ - type: "childList", - target: , - removedNodes: [], - nextSibling: , - previousSibling: - // other properties empty -}, { - type: "characterData" - target: - // ...details depend on how the browser handles the change - // it may coalesce two adjacent text nodes "Edit " and ", please" into one node - // or it can just delete the extra space after "Edit". - // may be one mutation or a few -}]; -``` - -## Observer use case - -When `MutationObserver` is needed? Is there a scenario when such thing can be useful? - -Sure, we can track something like `contentEditable` and create "undo/redo" stack, but here's an example where `MutationObserver` is good from architectural standpoint. - -Let's say we're making a website about programming, like this one. Naturally, articles and other materials may contain source code snippets. - -An HTML code snippet looks like this: -```html -... -


-  // here's the code
-  let hello = "world";
-
-... -``` - -There's also a JavaScript highlighting library, e.g. [Prism.js](https://prismjs.com/). A call to `Prism.highlightElem(pre)` examines the contents of such `pre` elements and adds colored syntax highlighting, similar to what you in examples here, this page. - -Generally, when a page loads, e.g. at the bottom of the page, we can search for elements `pre[class*="language"]` and call `Prism.highlightElem` on them: - -```js -// highlight all code snippets on the page -document.querySelectorAll('pre[class*="language"]').forEach(Prism.highlightElem); -``` - -Now the `
` snippet looks like this (without line numbers by default):
-
-```js
-// here's the code
-let hello = "world";
-```
-
-Everything's simple so far, right? There are `
` code snippets in HTML, we highlight them.
-
-Now let's go on. Let's say we're going to dynamically fetch materials from a server. We'll study methods for that [later in the tutorial](info:fetch-basics). For now it only matters that we fetch an HTML article from a webserver and display it on demand:
-
-```js
-let article = /* fetch new content from server */
-articleElem.innerHTML = article;
-```
-
-The new `article` HTML may contain code snippets. We need to call `Prism.highlightElem` on them, otherwise they won't get highlighted.
-
-**Who's responsibility is to call `Prism.highlightElem` for a dynamically loaded article?**
-
-We could append that call to the code that loads an article, like this:
-
-```js
-let article = /* fetch new content from server */
-articleElem.innerHTML = article;
-
-*!*
-let snippets = articleElem.querySelectorAll('pre[class*="language-"]');
-snippets.forEach(Prism.highlightElem);
-*/!*
-```
-
-...But imagine, we have many places where we load contents with code: articles, quizzes, forum posts. Do we need to put the highlighting call everywhere? Then we need to be careful, not to forget about it.
-
-And what if we load the content into a third-party engine? E.g. we have a forum written by someone else, that loads contents dynamically, and we'd like to add syntax highlighting to it. No one likes to patch third-party scripts.
-
-Luckily, there's another option.
-
-We can use `MutationObserver` to automatically detect code snippets inserted in the page and highlight them.
-
-So we'll handle the highlighting functionality in one place, relieving us from the need to integrate it.
-
-## Dynamic highlight demo
-
-Here's the working example.
-
-If you run this code, it starts observing the element below and highlighting any code snippets that appear there:
-
-```js run
-let observer = new MutationObserver(mutations => {
-
-  for(let mutation of mutations) {
-    // examine new nodes
-
-    for(let node of mutation.addedNodes) {
-      // skip newly added text nodes
-      if (!(node instanceof HTMLElement)) continue;
-
-      // check the inserted element for being a code snippet
-      if (node.matches('pre[class*="language-"]')) {
-        Prism.highlightElement(node);
-      }
-
-      // search its subtree for code snippets
-      for(let elem of node.querySelectorAll('pre[class*="language-"]')) {
-        Prism.highlightElement(elem);
-      }
-    }
-  }
-
-});
-
-let demoElem = document.getElementById('highlight-demo');
-
-observer.observe(demoElem, {childList: true, subtree: true});
-```
-
-

Demo element with id="highlight-demo", obverved by the example above.

- -The code below populates `innerHTML`. If you've run the code above, snippets will get highlighted: - -```js run -let demoElem = document.getElementById('highlight-demo'); - -// dynamically insert content with code snippets -demoElem.innerHTML = `A code snippet is below: -
 let hello = "world!"; 
-
Another one:
-
-
.class { margin: 5px; } 
-
-`; -``` - -Now we have `MutationObserver` that can track all highlighting in observed elements or the whole `document`. We can add/remove code snippets in HTML without thinking about it. - - -## Garbage collection - -Observers use weak references to nodes internally. That is: if a node is removed from DOM, and becomes unreachable, then it becomes garbage collected, an observer doesn't prevent that. - -Still, we can release observers any time: - -- `observer.disconnect()` -- stops the observation. - -Additionally: - -- `mutationRecords = observer.takeRecords()` -- gets a list of unprocessed mutation records, those that happened, but the callback did not handle them. - -```js -// we're going to disconnect the observer -// it might have not yet handled some mutations -let mutationRecords = observer.takeRecords(); -// process mutationRecords - -// now all handled, disconnect -observer.disconnect(); -``` - -## Summary - -`MutationObserver` can react on changes in DOM: attributes, added/removed elements, text content. - -We can use it to track changes introduced by other parts of our own or 3rd-party code. - -For example, to post-process dynamically inserted content, as demo `innerHTML`, like highlighting in the example above. diff --git a/10-misc/index.md b/10-misc/index.md deleted file mode 100644 index 65ab3188a..000000000 --- a/10-misc/index.md +++ /dev/null @@ -1,4 +0,0 @@ - -# Miscellaneous - -Not yet categorized articles. diff --git a/2-ui/1-document/01-browser-environment/article.md b/2-ui/1-document/01-browser-environment/article.md index 974142761..5bd9287b9 100644 --- a/2-ui/1-document/01-browser-environment/article.md +++ b/2-ui/1-document/01-browser-environment/article.md @@ -1,12 +1,12 @@ # Browser environment, specs -The JavaScript language was initially created for web browsers. Since then, it has evolved and become a language with many uses and platforms. +The JavaScript language was initially created for web browsers. Since then it has evolved and become a language with many uses and platforms. -A platform may be a browser, or a web-server, or a washing machine, or another *host*. Each of them provides platform-specific functionality. The JavaScript specification calls that a *host environment*. +A platform may be a browser, or a web-server or another *host*, even a "smart" coffee machine, if it can run JavaScript. Each of them provides platform-specific functionality. The JavaScript specification calls that a *host environment*. A host environment provides platform-specific objects and functions additional to the language core. Web browsers give a means to control web pages. Node.js provides server-side features, and so on. -Here's a bird's-eye view of what we have when JavaScript runs in a web-browser: +Here's a bird's-eye view of what we have when JavaScript runs in a web browser: ![](windowObjects.svg) @@ -47,20 +47,7 @@ document.body.style.background = "red"; setTimeout(() => document.body.style.background = "", 1000); ``` -Here we used `document.body.style`, but there's much, much more. Properties and methods are described in the specification. There happen to be two working groups who develop it: - -1. [W3C](https://en.wikipedia.org/wiki/World_Wide_Web_Consortium) -- the documentation is at . -2. [WhatWG](https://en.wikipedia.org/wiki/WHATWG), publishing at . - -As it happens, the two groups don't always agree, so it's like we have two sets of standards. But they are very similar and eventually things merge. The documentation that you can find on the given resources is very similar, with about a 99% match. There are very minor differences that you probably won't notice. - -Personally, I find more pleasant to use. - -In the ancient past, there was no standard at all -- each browser implemented however it wanted. Different browsers had different sets, methods, and properties for the same thing, and developers had to write different code for each of them. Dark, messy times. - -Even now we can sometimes meet old code that uses browser-specific properties and works around incompatibilities. But, in this tutorial we'll use modern stuff: there's no need to learn old things until you really need to (chances are high that you won't). - -Then the DOM standard appeared, in an attempt to bring everyone to an agreement. The first version was "DOM Level 1", then it was extended by DOM Level 2, then DOM Level 3, and now it's reached DOM Level 4. People from WhatWG group got tired of version numbers and are calling it just "DOM", without a number. So we'll do the same. +Here we used `document.body.style`, but there's much, much more. Properties and methods are described in the specification: [DOM Living Standard](https://dom.spec.whatwg.org). ```smart header="DOM is not only for browsers" The DOM specification explains the structure of a document and provides objects to manipulate it. There are non-browser instruments that use it too. @@ -69,14 +56,14 @@ For instance, server-side tools that download HTML pages and process them use th ``` ```smart header="CSSOM for styling" -CSS rules and stylesheets are not structured like HTML. There's a separate specification [CSSOM](https://www.w3.org/TR/cssom-1/) that explains how they are represented as objects, and how to read and write them. +There's also a separate specification, [CSS Object Model (CSSOM)](https://www.w3.org/TR/cssom-1/) for CSS rules and stylesheets, that explains how they are represented as objects, and how to read and write them. -CSSOM is used together with DOM when we modify style rules for the document. In practice though, CSSOM is rarely required, because usually CSS rules are static. We rarely need to add/remove CSS rules from JavaScript, so we won't cover it right now. +CSSOM is used together with DOM when we modify style rules for the document. In practice though, CSSOM is rarely required, because we rarely need to modify CSS rules from JavaScript (usually we just add/remove CSS classes, not modify their CSS rules), but that's also possible. ``` -## BOM (part of HTML spec) +## BOM (Browser Object Model) -Browser Object Model (BOM) are additional objects provided by the browser (host environment) to work with everything except the document. +The Browser Object Model (BOM) represents additional objects provided by the browser (host environment) for working with everything except the document. For instance: @@ -94,18 +81,10 @@ if (confirm("Go to wikipedia?")) { Functions `alert/confirm/prompt` are also a part of BOM: they are directly not related to the document, but represent pure browser methods of communicating with the user. -<<<<<<< HEAD - -```smart header="HTML specification" -BOM is the part of the general [HTML specification](https://html.spec.whatwg.org). - -Yes, you heard that right. The HTML spec at is not only about the "HTML language" (tags, attributes), but also covers a bunch of objects, methods and browser-specific DOM extensions. That's "HTML in broad terms". -======= ```smart header="Specifications" BOM is the part of the general [HTML specification](https://html.spec.whatwg.org). Yes, you heard that right. The HTML spec at is not only about the "HTML language" (tags, attributes), but also covers a bunch of objects, methods and browser-specific DOM extensions. That's "HTML in broad terms". Also, some parts have additional specs listed at . ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 ``` ## Summary diff --git a/2-ui/1-document/01-browser-environment/windowObjects.svg b/2-ui/1-document/01-browser-environment/windowObjects.svg index 69c295bbf..d1b280ee8 100644 --- a/2-ui/1-document/01-browser-environment/windowObjects.svg +++ b/2-ui/1-document/01-browser-environment/windowObjects.svg @@ -1,72 +1 @@ - - - - windowObjects.svg - Created with sketchtool. - - - - - window - - - - - - document - - - - Object - - - - navigator - - - - screen - - - - location - - - - frames - - - - history - - - Array - - - - Function - - - XMLHttpRequest - - - BOM - - - JavaScript - - - DOM - - - - - - - - - - - - - \ No newline at end of file +windowdocumentObjectnavigatorscreenlocationframeshistoryArrayFunctionXMLHttpRequestBOMJavaScriptDOM \ No newline at end of file diff --git a/2-ui/1-document/02-dom-nodes/article.md b/2-ui/1-document/02-dom-nodes/article.md index 6bb34ff8c..2fa8b8dcc 100644 --- a/2-ui/1-document/02-dom-nodes/article.md +++ b/2-ui/1-document/02-dom-nodes/article.md @@ -6,26 +6,42 @@ libs: # DOM tree -The backbone of an HTML document are tags. +The backbone of an HTML document is tags. -According to Document Object Model (DOM), every HTML-tag is an object. Nested tags are called "children" of the enclosing one. +According to the Document Object Model (DOM), every HTML tag is an object. Nested tags are "children" of the enclosing one. The text inside a tag is an object as well. -The text inside a tag it is an object as well. +All these objects are accessible using JavaScript, and we can use them to modify the page. -All these objects are accessible using JavaScript. +For example, `document.body` is the object representing the `` tag. -## An example of DOM +Running this code will make the `` red for 3 seconds: -For instance, let's explore the DOM for this document: +```js run +document.body.style.background = 'red'; // make the background red + +setTimeout(() => document.body.style.background = '', 3000); // return back +``` + +Here we used `style.background` to change the background color of `document.body`, but there are many other properties, such as: + +- `innerHTML` -- HTML contents of the node. +- `offsetWidth` -- the node width (in pixels) +- ...and so on. + +Soon we'll learn more ways to manipulate the DOM, but first we need to know about its structure. + +## An example of the DOM + +Let's start with the following simple document: ```html run no-beautify - About elks + About elk - The truth about elks. + The truth about elk. ``` @@ -35,7 +51,7 @@ The DOM represents HTML as a tree structure of tags. Here's how it looks:
@@ -44,36 +60,38 @@ drawHtmlTree(node1, 'div.domtree', 690, 320); On the picture above, you can click on element nodes and their children will open/collapse. ``` -Tags are called *element nodes* (or just elements). Nested tags become children of the enclosing ones. As a result we have a tree of elements: `` is at the root, then `` and `` are its children, etc. +Every tree node is an object. + +Tags are *element nodes* (or just elements) and form the tree structure: `` is at the root, then `` and `` are its children, etc. The text inside elements forms *text nodes*, labelled as `#text`. A text node contains only a string. It may not have children and is always a leaf of the tree. -For instance, the `` tag has the text `"About elks"`. +For instance, the `<title>` tag has the text `"About elk"`. Please note the special characters in text nodes: - a newline: `↵` (in JavaScript known as `\n`) - a space: `␣` -Spaces and newlines -- are totally valid characters, they form text nodes and become a part of the DOM. So, for instance, in the example above the `<head>` tag contains some spaces before `<title>`, and that text becomes a `#text` node (it contains a newline and some spaces only). +Spaces and newlines are totally valid characters, like letters and digits. They form text nodes and become a part of the DOM. So, for instance, in the example above the `<head>` tag contains some spaces before `<title>`, and that text becomes a `#text` node (it contains a newline and some spaces only). There are only two top-level exclusions: -1. Spaces and newlines before `<head>` are ignored for historical reasons, -2. If we put something after `</body>`, then that is automatically moved inside the `body`, at the end, as the HTML spec requires that all content must be inside `<body>`. So there may be no spaces after `</body>`. +1. Spaces and newlines before `<head>` are ignored for historical reasons. +2. If we put something after `</body>`, then that is automatically moved inside the `body`, at the end, as the HTML spec requires that all content must be inside `<body>`. So there can't be any spaces after `</body>`. -In other cases everything's straightforward -- if there are spaces (just like any character) in the document, then they become text nodes in DOM, and if we remove them, then there won't be any. +In other cases everything's straightforward -- if there are spaces (just like any character) in the document, then they become text nodes in the DOM, and if we remove them, then there won't be any. Here are no space-only text nodes: ```html no-beautify <!DOCTYPE HTML> -<html><head><title>About elksThe truth about elks. +About elkThe truth about elk. ```
@@ -89,11 +107,11 @@ On further DOM pictures we'll sometimes omit them where they are irrelevant, to ## Autocorrection -If the browser encounters malformed HTML, it automatically corrects it when making DOM. +If the browser encounters malformed HTML, it automatically corrects it when making the DOM. -For instance, the top tag is always ``. Even if it doesn't exist in the document -- it will exist in the DOM, the browser will create it. The same goes for ``. +For instance, the top tag is always ``. Even if it doesn't exist in the document, it will exist in the DOM, because the browser will create it. The same goes for ``. -As an example, if the HTML file is a single word `"Hello"`, the browser will wrap it into `` and ``, add the required ``, and the DOM will be: +As an example, if the HTML file is the single word `"Hello"`, the browser will wrap it into `` and ``, and add the required ``, and the DOM will be:
@@ -106,7 +124,7 @@ drawHtmlTree(node3, 'div.domtree', 690, 150); While generating the DOM, browsers automatically process errors in the document, close tags and so on. -Such an "invalid" document: +A document with unclosed tags: ```html no-beautify

Hello @@ -115,7 +133,7 @@ Such an "invalid" document:

  • Dad ``` -...Will become a normal DOM, as the browser reads tags and restores the missing parts: +...will become a normal DOM as the browser reads tags and restores the missing parts:
    @@ -126,7 +144,7 @@ drawHtmlTree(node4, 'div.domtree', 690, 360); ````warn header="Tables always have ``" -An interesting "special case" is tables. By the DOM specification they must have ``, but HTML text may (officially) omit it. Then the browser creates `` in DOM automatically. +An interesting "special case" is tables. By DOM specification they must have `` tag, but HTML text may omit it. Then the browser creates `` in the DOM automatically. For the HTML: @@ -143,7 +161,7 @@ let node5 = {"name":"TABLE","nodeType":1,"children":[{"name":"TBODY","nodeType": drawHtmlTree(node5, 'div.domtree', 600, 200); -You see? The `` appeared out of nowhere. You should keep this in mind while working with tables to avoid surprises. +You see? The `` appeared out of nowhere. We should keep this in mind while working with tables to avoid surprises. ```` ## Other node types @@ -154,7 +172,7 @@ Let's add more tags and a comment to the page: - The truth about elks. + The truth about elk.
    1. An elk is a smart
    2. *!* @@ -169,7 +187,7 @@ Let's add more tags and a comment to the page:
      @@ -180,7 +198,7 @@ We may think -- why is a comment added to the DOM? It doesn't affect the visual **Everything in HTML, even comments, becomes a part of the DOM.** -Even the `` directive at the very beginning of HTML is also a DOM node. It's in the DOM tree right before ``. We are not going to touch that node, we even don't draw it on diagrams for that reason, but it's there. +Even the `` directive at the very beginning of HTML is also a DOM node. It's in the DOM tree right before ``. Few people know about that. We are not going to touch that node, we even don't draw it on diagrams, but it's there. The `document` object that represents the whole document is, formally, a DOM node as well. @@ -189,31 +207,31 @@ There are [12 node types](https://dom.spec.whatwg.org/#node). In practice we usu 1. `document` -- the "entry point" into DOM. 2. element nodes -- HTML-tags, the tree building blocks. 3. text nodes -- contain text. -4. comments -- sometimes we can put the information there, it won't be shown, but JS can read it from the DOM. +4. comments -- sometimes we can put information there, it won't be shown, but JS can read it from the DOM. ## See it for yourself -To see the DOM structure in real-time, try [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up DOM at an instant. +To see the DOM structure in real-time, try [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up as a DOM at an instant. ## In the browser inspector Another way to explore the DOM is to use the browser developer tools. Actually, that's what we use when developing. -To do so, open the web-page [elks.html](elks.html), turn on the browser developer tools and switch to the Elements tab. +To do so, open the web page [elk.html](elk.html), turn on the browser developer tools and switch to the Elements tab. It should look like this: -![](elks.png) +![](elk.svg) You can see the DOM, click on elements, see their details and so on. Please note that the DOM structure in developer tools is simplified. Text nodes are shown just as text. And there are no "blank" (space only) text nodes at all. That's fine, because most of the time we are interested in element nodes. -Clicking the button in the left-upper corner allows to choose a node from the webpage using a mouse (or other pointer devices) and "inspect" it (scroll to it in the Elements tab). This works great when we have a huge HTML page (and corresponding huge DOM) and would like to see the place of a particular element in it. +Clicking the button in the left-upper corner allows us to choose a node from the webpage using a mouse (or other pointer devices) and "inspect" it (scroll to it in the Elements tab). This works great when we have a huge HTML page (and corresponding huge DOM) and would like to see the place of a particular element in it. Another way to do it would be just right-clicking on a webpage and selecting "Inspect" in the context menu. -![](inspect.png) +![](inspect.svg) At the right part of the tools there are the following subtabs: - **Styles** -- we can see CSS applied to the current element rule by rule, including built-in rules (gray). Almost everything can be edited in-place, including the dimensions/margins/paddings of the box below. @@ -234,13 +252,13 @@ Now the last selected element is available as `$0`, the previously selected is ` We can run commands on them. For instance, `$0.style.background = 'red'` makes the selected list item red, like this: -![](domconsole0.png) +![](domconsole0.svg) From the other side, if we're in console and have a variable referencing a DOM node, then we can use the command `inspect(node)` to see it in the Elements pane. -Or we can just output it in the console and explore "at-place", like `document.body` below: +Or we can just output the DOM node in the console and explore "in-place", like `document.body` below: -![](domconsole1.png) +![](domconsole1.svg) That's for debugging purposes of course. From the next chapter on we'll access and modify DOM using JavaScript. @@ -258,4 +276,4 @@ We can use developer tools to inspect DOM and modify it manually. Here we covered the basics, the most used and important actions to start with. There's an extensive documentation about Chrome Developer Tools at . The best way to learn the tools is to click here and there, read menus: most options are obvious. Later, when you know them in general, read the docs and pick up the rest. -DOM nodes have properties and methods that allow to travel between them, modify, move around the page and more. We'll get down to them in the next chapters. +DOM nodes have properties and methods that allow us to travel between them, modify them, move around the page, and more. We'll get down to them in the next chapters. diff --git a/2-ui/1-document/02-dom-nodes/domconsole0.png b/2-ui/1-document/02-dom-nodes/domconsole0.png deleted file mode 100644 index 121c11d75aa3fec9ad63204f7eda8d27b399af0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94995 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 esu6^%$xlhmfl28bg=d#Wzp$Pz#Lr!r3 diff --git a/2-ui/1-document/02-dom-nodes/domconsole0.svg b/2-ui/1-document/02-dom-nodes/domconsole0.svg new file mode 100644 index 000000000..c0096060a --- /dev/null +++ b/2-ui/1-document/02-dom-nodes/domconsole0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/2-ui/1-document/02-dom-nodes/domconsole0@2x.png b/2-ui/1-document/02-dom-nodes/domconsole0@2x.png deleted file mode 100644 index a8953395c57a551dec64f409fe3746f8489e8970..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167554 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�!-?hjOufKn|K0V$57bWjiwkY)jusz~UdLg-C; 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 KdxX0Zi~j-5y?(L) diff --git a/2-ui/1-document/02-dom-nodes/elks.html b/2-ui/1-document/02-dom-nodes/elk.html similarity index 86% rename from 2-ui/1-document/02-dom-nodes/elks.html rename to 2-ui/1-document/02-dom-nodes/elk.html index 7d29f3d4e..dc5d65f54 100644 --- a/2-ui/1-document/02-dom-nodes/elks.html +++ b/2-ui/1-document/02-dom-nodes/elk.html @@ -1,7 +1,7 @@ - The truth about elks. + The truth about elk.

      1. An elk is a smart
      2. diff --git a/2-ui/1-document/02-dom-nodes/elk.svg b/2-ui/1-document/02-dom-nodes/elk.svg new file mode 100644 index 000000000..19ea221d2 --- /dev/null +++ b/2-ui/1-document/02-dom-nodes/elk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/2-ui/1-document/02-dom-nodes/elks.png b/2-ui/1-document/02-dom-nodes/elks.png deleted file mode 100644 index 03177c40e8fd6c4751efe2b0dc6a8d846daf9f9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74948 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

        h^?$SxGu3gXV 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%0A%r_EN>(kPmY}v}riVG#m}H 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ºZ825X1V$y&7hIB7T7vNP3aow_t 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 diff --git a/2-ui/1-document/03-dom-navigation/1-dom-children/task.md b/2-ui/1-document/03-dom-navigation/1-dom-children/task.md index 4a9e741a9..d97f2748a 100644 --- a/2-ui/1-document/03-dom-navigation/1-dom-children/task.md +++ b/2-ui/1-document/03-dom-navigation/1-dom-children/task.md @@ -4,7 +4,7 @@ importance: 5 # DOM children -For the page: +Look at this page: ```html @@ -18,7 +18,7 @@ For the page: ``` -How to access: +For each of the following, give at least one way of how to access them: - The `

        ` DOM node? - The `

        ^-!HnKTt`%0C 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 z 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 z \ No newline at end of file diff --git a/2-ui/1-document/02-dom-nodes/inspect@2x.png b/2-ui/1-document/02-dom-nodes/inspect@2x.png deleted file mode 100644 index 8743dd297d441840e4f002632d71886ed8c1262e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198241 zcmeEtQ*@>6vTlryZQJVDPIqkEwr#Uxr(-dPuQP;fPmn>NQfu^0f8F<0fByog82A`XO6}T2nZIxkVJTrDx})CFDRSU1&GKRgdhq+R}$5;ZAvG4B&5JX;cykW~MMD?~gDF zlUD4C{PwFUwbYPFz2c6Ec0!cc$TypjJ%jb=op$IwIn!$982i~yjs>h|W;auRqpZ#( zB!UTT7v0A~gtVU;QFq&(^ufT3LKqd7qK-fh=1p$`2owm_PVHA7qNU(CqVd4fa1EX$ z;dStX85jdUsY-|sdE{BE&u!;aF6YesT%- z@1~#Ju8|OF1lFm>BcPL>_$bGJL}E4|g?%5$gd_6FAcu-dUe!D0?44<6v}BX4ML!20 z=jJD2Q#*|$a|jOC&&TD^dIzF{jOsfW8fn(AY4gfA?i6iVk!SX-2*|)grK@CdkyArt zIbF*_z>(5`Jl7|;R7kX{bZvQ(2PoKZeCqWh_yH+J7(jwH4wmM(#5BzT^qw#Y27-?0 z=hO|Z!aPwT9$*xLki(RV_zI1L0X6jMMOLRJ2XwDHSU+2gCh=_?U4o~!8zs!qPI?{1 zb*OK94hNol9o!Y~-jF(`>MJbaGfH5%zepVuzSS@n4m|Mo8;&-mm!rOm0sZR?Zs!0A z50MiRK5`X`2UL?Fj~i_`ab0?kCh<>yPL!ZPd`vpIWNqrG6@H6A9O1>7W`;}PC*eyD z&?PXHX3+6|$j5*dPN9oOSW(0E&V`$y`~HfqDe)pzMpe5+fCS!)@#|oPPt@+Cb~MKi zyytwfMiB0(tRWeF3;=os5+mT78p>h}9>yL(#*OwQXlCI%*?O%W?q*4}bft9H#1X-w z$;cwcl4R;sRu;oA%vY1cNu(dMEH`O~`Ve1~8R zep&{m*oJQx1WE-X7NnH`nbRL&5rE(4ff)yl6hxu~w(KFVfjb9k6J+H8g7+7j29fc1 z+-5!oTk6qX#_-+-#{|3TW(*)C4GNh?f)l}D5~4-q?gzgX0f}QI#r`6s5a$#W8y4q2 ztWW@^9&07+Lc}^;JVR}2WJA&+!GDAO6l6e&rYzbZZ|DSa8t|N(XGY5fCoO(E zE#!pNioFq_^8IB7;ttgVt0U$imtmR+R__KAbgr+05n~)7vOfXvS;~*DI|86kfn45~ zzH{Y;cGd$?6U%{AyeGB(>A{2%KeX4KR51>Hj%GJ@NLBF2HAnio!|+qCF3=bhqjp1 zl=O%kgK8)~gQQ8!CRVF%9j%40ML&XhAZS-GywFGiU9nN_l+u*ykLp;Icxn~J!Cz? zCns>rU_|hkUZG&-V2EIw;FJi52(bvhh&ePEG)XiB8Xb9DxdcUKl^aC^Dmpo8MXn+z zMRSR?Dywqb(#-t!ukJZFq6enbq-cgoKxi?e%t;&6#me|IOs&8hv6Dp%g;#kwg^#7k z%F;^0N-WBfN(dz`CGcgXC7dM#*eSiE6plfG};jUc@8=5R~7V)R`kKN9UPOauS^X950m+t2e zPHg6ROJ6ce2k-PvSeh887$NWL?*i^cJlgKK?n3UR@AmFej+f51*mE(PF$=J)KAW*% zex7HAWzRHKvveDhm>eFU>@%yIanFAoBp-wx9E-+@&PglD2uejwpHE+BDNOT7J4{na z*I^+^Z%H*yvt~d0EIxrZ!7@HJUagjkE`!b!d4aB-3?`{6*=byOAWc)26szp7T&Y~m z+Q&8S5$>FSKL#Cwl0Z?BVdvAUiX)z3mBGvAYOQQVu|f~9ZuGV`wHa!pscSQltwX5S zHQO?JAMNS&Ka<gek3$C4{ge)g^>pUPjUzHz<)Uva;$0$SaTevtmp z{wMwo{(*uqf{uY2fzUm9J!b*7A!ea9!WKdh6r8f@{3lYBte?r9G>`ijZy5#E967N0 zsJw)Kc0lDr`G^>jhQWrfBf9gCl2S9AHjVU;$bTCn=MQg;&c^WO3&Ce0G0`1wQ`=f* z1-R}>?TOf1Uq@Uk?pf|`QT(K+kUjpA8OOnY?T}!C%uq^|mWZ3v&hBpZwL4K-@wtdg zhA!R1Fny$cWsY8EDKne*?I-L2Rs~k5A`}%g)r$gO9kF^+Mc#be{LQ>zBY`K&3;0k* zUHshC{dUz6pY*MSX3hic28p+@hi{0gnE4>kRBTi9BQ*<$qxj)V#c)MgMf`ct`7^GA z%-2b#&QJW2z9vPJ<0~v}4s;HY4xTsbH*5!RpM=0YgTw67Yp8V5@Euo0i@xWGbbx1r z8-o*=3`}wHXu7lcy1d}ta?%{}(81Ea8q@Qo@HSazZ?+HIdK|rsZ#4j^$F=5K=k@d& z!@Qt_)0OE+sb@C)d?aI&Tx4)>`>bz%%Y0!Rnaul4bzHnk984@YGjVV^=33FM`a{L3 zqF%Sf`C!RF=DH9$BVjgSs(iVe{>|#;HaSOJrMU7^ZLhw_fX<%I_afR^=d5grrkX+P z-AwprNJ#W}^Z?G5O*-Jjpj7xIW+HLo`vk9MZ{ufc*7a7Gvm7J4gKBc>= z_e$cbIi>bhr7Oh^w$gMOG-VfC{La2d!0({a&MMArrkUfGkJx5(duO54H$9au? z^r2@ln0QqDU->oG{XUPIV_J=yotuBPIOSqHQPZsRyq(#q@GZBPv83Xza`Bpg9t}69 z5R*aA#PM&4YFvAKh2MJ>h%tl-MJFGA|Dw{+hhh4-Sn;y zpAPl}7UqO89Rp$Sl56#xbc7Sq&u7Sa)_C50>Gc-{6J81|Jz6ZMijThG*i1Ca16caT*2eH zVua^*VzP?Ej0TRY3umVVN|pLcDa- zZ~sHLzYp}N?iQEzF~a6ap=GrH@te2!^GSghXhy;{pGK>+|9GY!@%FV_A}?sIm+B?e``e9?MJ%>`kyuClJEmwfe$z|{!exX{=`T)_V^#g3;4tT zVdTJEcdXyK?Y|U(9lqiH4{rVVJvR^xGwy=WOef?&8UyIV3<&>ghW~dnOw)nXUV2dA zwq>7Sb zW_5m6S#`L&*%gzPx{tFlHYY* zJwd}Qrdox%<~yBEyz@cRn8F#)fW`O+*!vU$e1)~28*3eZbFc2;{n<2Ya~I_+!;PzH zg$}YcnziV!Z@TXfTnfxh2c(8YHFvm(ZU&xO87$>n^s`Q0u`o<}_U!e~zAJU81ZJNr zP%+KbNm?iWA{}3binS!Tp>QhIA>OG%c9WUc-}CC@z0}aQa<`>@ptB|H$3}vtymsr~ zlE8~70M=1O8$4|z-O2i16IGT``KZj4h%R@ohN$lge8rR z5iLj!r=lGVAk4O{-~UDw?i&0#+zoD@no@r zJQSIqr*q_%=gaTo2>@b^8mG*i6*@j1s(1UZHh@G^@tKsfj zg_>T`p#k^M&tP9ZcNeQyIt&${s3;buGbtIeCG+W5WDu-Nv-_Hxf+p32veDNJ!| z$|1x?^;owU6!6qX_eoU$f@aMAFmI(TMk(KVOlBL*XO-C9H2u`}nsK>8 z)R7r|D3puPVChg{>*^lpm-67$Y}Am{9d(0EhVAuQY<>Cf2z}zjm*bQLTNR6Qk8`@S z1TiYqRR`8fHC>fz8G>3}<(T??6n)DXwJ+ZqxK0?r)MQoeNW?VQIOG@=6Qh&guGPhY ziA=47^{wb6Rcvp$hG1nyZu*T#Dac5e^hphZWS{emHM#;D%I?ZHV+NYYNJf_#)Zed} z?H>beZHl#{Ov`>m3q`rv4twI7Hc!Dz8Xt`rOsF1YV_BIdTX4#5t)sSz(A+Dx=3Xicti9~F@!qHh#Fv6Y4Bm45g3yhN$aSs-o+nz zA=OO}Exdxi?vzgUbu>gCc$4avxb}(nvBrqAw(Yt% zP_a;eEt;gcYfJFHaO$U{eH_D>lb8SH#L^Sy}$$N?MTIw`>=lIjPT9GoP4uza&+KZ;Xv5SrIq5q z>>%;{#TKiL!hfbNZuBIGk554+Mc);v32atWeKs&+>I-S7g z{dHb79j)nVk=RZ|o1;J0)AF+oStDOp_fjoh3l_0JRx8)`vUG~=h@c3_jqH5hzD9Rv zUsXGL#Y$M&o3kC7shM|*B??8vW2JVxWYeX+`_)-W(r^Y);>e>*2}_FREPHa{@6Z>o zdTvF<_-#LmY}ikAZX1d+9%9-fq?l0}YiVT(3`fq0c4zWq=UYh{UT1pwH<7GjBl)sL z^0?Dd9xIzh2jlc=pU&ckpq=%dudz^ur_K}=H}hCB>>2BOXDPFTAhMN!fbzvU=UbIn zD2V4(+1aXZjb>SnHKz4AshE> z4Wwlz9OE`P=X(}l#UfV2VzOQnS~RT4#52V>fW$?HYhy7~W8VG_tr2fKQp3Z=vW8B0 z>(e)p3B)QKB;)n~GV7`wj=^~xN%gIrM6Yvh0K9ohgnH)eK(ZhBSma$T_vl?A#@%`@ z)#DJnu}MXfpBj8m{YqTPgb-bja87{*bs?_Qu$Zwn8TxusM9>UCqL~d8r)%9NJGhk* z679aTY}fR$WectDYZ4utJHPC8;l1`~U+}1v46ErwzZYhkUTca4(HP$k9z$Cq!?*eZ z4#|l_gtMl~L8q4Uo**7nKC4UL{bpDz?Zg6B1vUnR81m%9=}&AKcKPQsr3R%4faeQX zCdn5Oz61kMC1jS~1yP2wfhfH>^fbS7gX<;LGiKx4-=LL08U%CyOQg6Y!_?%M`I%%r zT@jwy2E82jT(qu5{06Wlx8X#?l%0k(|Iv=5qEBR3Dj6}te2lb2dX3-SihRO8uJE-aZLL&2*}_aNd!)Ss--nyky|lMWaQa^H2Em zXeIacIVMCS*s}Os(4q%VA-gX7U8is;Dv_)n3*fW~=o3N-PYRt}fYb)9v#epwDCJ7E zgq~^t?Jtg2JZ_v9QoNszou(C8 zHJqv$17~)lE7<^_rIQ~~&tFl)1u9&}L>&ScILb}Hmva`qlmPIzN&pCv74n%MnU%|C zY4K;SEyI|kky4yfS~i?pc;T7mPbFIP0b70jy1U1p6KSur_k4ek%7jpk`B;pEablYi z+tAk<1XS@K@LYP7De#9E`pfrYf|9lJf{p3;A8qt6E)}$(2iX?$cMld)vC%`C3q~jj zPob1!*iC3aq#<9o~uX_gNf%?FB)B!lp;fopBkSG z8q3BO_C4#XCW9*gd2io>Rx6yV!3>QL**u{Tpi$}~FV4oLE2ac*?3nr<@(h&NnYh=r z!o`2n3VbxIWdc*M!`P;tGLhn$uceI>5Sl0q#&pWc!7nP%96EFY4qKR7@#Ks9S%6Q< z2HrE#V@r8PV&&;9$`LpWM;0DU&BH~D^U9J~kMUtyxsXosb4quMYSmeDAr1a>$h(MG zSS$OU^CsLKdKKoMxg8MMWwS(WxD2^!q=$vFHflO+uB=vOrJ|x_#I9pJ6y5QE-$H+; zn`Qy69b~FzFrNV}i&9R5*Uo*NF(Tc}%pdHt%oW29=0s$Y)~Ihb=ajXGpV(<+YXVkjy&`8TgG9|vJI$gZB|15F=&XPL&0~~} z2sFFzMeeh1g{$7``LI-kVA@>b2#mZHu_MKaA5Y!aHJcFq0x?ax8UX^^6lJejB9W&=xs~R zay-n*Rza3iF0_oa?}VD^t#aDNDz+(9zt^`L1P>+7+DRCp82nNq<4~-h#5jF(clYYB zPd`<^H0L9$q!bxEe4^M5(U=OdYcIaMGiAeG+J!}&XQ3;emI7*4;ZZ9$WM}`HlU=3F zd_iql!_w_nKbuE>D*r11`%Y5yumSMhfRubAy^x*ICqP#xpCDb)MoHDIyn)!gUSC_Y zX(wwXsMtPK~w^SMk$Y zZ^rR&q9(mo%h6YY4fai-BU{p92f(btC9&B-?aT;`^pbNd1IUPYZ&h;)lc>K1kUAiE z$Z^iT=hNBqRX>6-^I6bfh}6&v!OMu_pTF_+Wl;+3_7B+o92i@t^ySe`+elMx1%lS_ z7G5|^;2xE?gnhuC)6izhXE9rg59?BSr*gX=T9jGLzr*Uo&W59}RHoCPQ=r^3ciT<^ zFbGyxFD)qkVv)Od1Xc*4SLKFXN)Z*6t9Izn5$_WB$WCV7u%p9R)(lz6Xdf!2xsBWR zWa!`Gf(fZ1yy>T1@zV^%E9`t0;4{%K4;+Z@5~{8(USy~_R?`g<>Im9$-}9zhQ?cf= zy<@M>BOB-&Wkx464^@kg*$@5tX8PP(4tPG~*pEmMm1NfFS`YXD6u)|iZQsS-S`C6m zRMCD;wMU03c|~sB=`Io)%kb4UpucW?yX-iibfbjiL_o{^US6?MexCyUyZD)Q|HF*I zYq&L~@b={T-jzg%sFa9Q>sldc-U|)SJiKcS>Wm>q01}LFCjDXWGR%W3rQGwv1qp=6 z-hFoimE9n({Vi;Q8|^q2oO=O1st6rtO6Lp9Ii$s=Y1~A`Nz~pQ*v)onb;||M&CVa6 z_S*>;QJmX$)|F${=P?TySb4n6=bTV&?7J($Ux?$KlK7@-txV!wC$x(3PQ3eSJVKWW zTuciWfwjMkfk@S*(#Tudu_juund@?4&E-%B8oIKcuSLY;Cxw9sSKhedm2ApK>{|07 z_Q5VFv@OlZ;hNbIno1Qh&>#f!Gl4OZe5>&Y#79qDqIVlY#CupM`{|6Y)T8`Bd%UB@ zv^QsxN=IX|QZ!B%qBzc6Rc)X9Gp|%)T+QlOhDxQHPIa<8?fMIq1v26oeBwyXd*n*R zKvVDs0r6a+)e*;;#7wf4sIQwIlUn0c;Zur>c9od_vs8;zJX#54_Df_ViD7+dvs%s) zG7x)Ch`CF{wXK;NwMF#V$Y`jSG3qmTps`seBON3fBrRN|YYTN27ugCjsSB~~xY0f> zoj}hlu9p2b-?qg?H>uyT7aq|9>gs7n;S||F>YrSC_v{xI+{;EId5E=+k#dVvH*Yn0 zUo6ge=;i6B56dd=_N5t@Mz-V%Q}}mol&mM&8^WR8vqu@UJscY}c?~X0TcWnEL1Y*7 zJHASkqP*}B!(!HKyxwRqU204%CaE9Z&Z)SU^}B)E=-S+eG3K|l@3?J*Ap7=Vk>NWR zG!(A*pUDhA&PNC}JP=0;r!=plG`99>He&sC2P%RJz_SbM=_$HO1%LoqVRsXWOWw+&QJ%dr<17 z(=@V{dx(S0A%BMC|C0MQ<>QlYx&eFkL@S&0+_|BPTwqgXYFW9%B~5BMHUUA-ue+6S znCJ%UI=+W=_3n)(n*1o8Y+5dycylk^i7*h@EcG_FW%UyW`6`$AY?<8X%sR7#x%~?E zDy^>}J9_nnY@u#ro{33LwNU&uFnFgGqM97nE#h~~@tp`TmS+;v@{+Fa#_gh}t^2eM z@CvVJh+h;FhoMYy)iuOn)UqIG6!S1kp#+r%D&cT3L~R6a$gsAya<^YDZAOPfIp?tP zxd_V%7t+2`_0a}}`=W9fRAyhgEk1(?A?x&^gVkrSE-&XI+8Md9ad~IZ8Kf)auiT&Lc2&*@mMq8?Q(ud*xpNxJ6NFvP3mdvQ_faqNuZS} z?Onx@r%QNeWF(rXD^q(V31Hg3vYf(341uz+NqMXU*W8%Yd&Ahn5LB8o`ILx#m6AUB zVCA!jTd>I6Vf^(WlJM2*EOp`8fMKh6my5Y3or`V)`R9GIB-$0A%&&r8Hk@gi+qb;* zh3CIdWBx1lJHB*d$H9FAUWw&?Untv|hW7oR-nc&l`8f8cj8Re&3s z=V||2^L79XqusVZP-tlW5}482$hV2#(b50P8&K4GaKkR+!W{uFp%lNv_y218@9;k+ zJf2e>hZ4U#_>X7&WzatcFyCx}7-WB!k^T_^{?{h|zug`GuuT@Fn8c4_ zC!hx$JB0ER%<<2xz$-yWOIraM9U}bCBzQyhW3+qedA02LL7`v)Luh0G@0$M?_&iny z$@8ISwp%OTM8~E53)W{5cKcaTi|i@X;bRJdfqd9$IpND zx=vLe6UnTzsd7a>kV;gjJ7YkSGywZAc@t1-{H|EJ)(}y}f9Ea%6cE^9Hvc}wk298# zYkaWIH9F=z=d_i2ci-aN3as3aQ@kcqLQgCHcRFls`_Oaa4Zijr^|%M*6r(*E9?)>F z;enT2{AZR0^ViGCpo6O^yQr_%k!9S+{5vBHNPbMGt;5mB6mlbB+FRG=20Sq}9_JaH z@{-UCd8A`sJPrE-*cNsz!L7sp%H!I)xnw;GXQoCa&I=xS$yd)7=R|*51=URRBcrb^ zeyjYL%@q^n`uM|?hMNS`Sm4x7AV!ucH~*!Qn*Sl6WyYuP*k^3YG6RZZp$aOMeY}5* zIfnbNf?IFmvy4pfQmYWjr*%gln@8gzqJ-JAZO?=HZO3WZME;KRqJO26z*5^lwk z=rG77_2I97`OrU`_QUD2oo%={;I00C_mR5O^z2As)@5)^{Eeb4Mi~|~W?OCn|9W~_ z6g&W2DA0RTeGF$zeQJcL{0KCQB_T*-QZ4jff%Qj9nN|e<80VL|ChvV0U`Lee%4A(x zAoO3>b2bKITSl*tskvEvovXC9jve|_g+@d(YE0}?)0EYahW2!Z7jqudarW%GL(L(I zHM6Ry2Kd;2!bcY6qt@YU$~WPJMV*J>*;b9g$t=^9A*Lk;1m*d|v>|ZFubByZS#bm5 zmV|T^;Wz3-hY_s8UqIq3R8O$_l)^+H5@O<%=yVfSK9JR)jh$%V??g4fyntK4!Ng8m&A^CZ1A&-uePcy+Qfus ziZ)JtPXJ0q`Iy-h2f1cw2@Un|(U*i(7bD2gc&|evH_y1B%7!F~aO*Y68dhzAH{{|Y zHHAT_va7@f8Am}ib?Hh&Ynh2AE!Kj*xl){2aJ8^MeHG+)?|AG4lJTK3ultF>(<0A( ztA+Qy+C}Sl(_!h+erL<=VC}yL0{KTEpt#Oo)aRS2(-&1!-X^D`FNmDPa2$xO+~6Jv zrA;N07=HOGu2sKLwX>-ml^P_~^+3|#T8J}%B|ofXOOLz-KNq+m!^Ex97KI02tO;hs z&2m@eTr@;B&tM}6X%d|s5irQ*CLTITYt0aem&MmuRC6*J~BJ;*slW2gmCmbFiSZ{WOR@iamxkcf)nF zET_Z?@8WH_p?8q_C+<2P1zDV`(-V|epY)Ky$2r4^tu!~+v(9fZEYE0Yzvub)Fhr-?)d+ti%a^CDDmS?y|IIy9{@6_l7(y)5?Hhr|0U$8*X(3Mgv&oJF4WW& zxl3iNtrr<3jW~vS=Lh79QDbF~F&|c1{r!1B2H&DbO&IIGy;XJeX;QW7C!Y=)7QeiO z$37L(IxD1Ghx?}ESKu+$pFo*&1vfs1(q5YMObSInIKQGgfZyu2YFaDa%{k zn4b*iQqkD+Z>cdFWP>kpX_I{d-Siigr>8E1+RFk1M&A6D5pYD~0pXR0%+X!GzE}#f zTvsCaxssniIc+hxK@uoyjm4&?>=Q`&_pGV0Bg2tMf?+E+nJm<5#jnr%UyO@ihgLDp z06Mc77MJY}fBQ3wDi=Z^@SbSe-7q^n+4CtOCvea^*CqOBVM;oUg1x~f*JH3>P(9Fa-^cMZd25y?@FvYWqLZUSO4%`y*Bc@RBhp>cUoE}O$QO2fmW zB{|09{LOg(NI$oOHb2{vy0WqGGTM2b=knjG1S&@~qJr%Hak`;Hm+CHD_vEn9Xbo6@ zgsV%P+JWk3LCKz=T5U^3$K6`?a!3Xw_-69v(Pi!lI(Vd=(8RF?SJ9Oq0?4wO` zeQi;!TKZVlc^ko5?dV-m&SW;xH)wTAWXoFYix>P)c4Xm z5i}^gp&vIL_BZ&kBH7ia!uF`#OP=>YNMS$ORi#zzy^LP3l`iQ=7OoGMf2+BQcH;r; z$zq;FTT+w7EOGv*?n?S@wbSQjdmg#`!vW%yk8&`ws~ttt1uDX^!aVtvhBJWPV&c(ce=$o*wS$dSA*4kfDen|*~3M*XNGTJ zu_}M08^CI4&z!BDivfSiT7~8v_ZDN(;N&~T0<7`-IxoqOOopSKE$g2B+m~l>?Mi>; zGeD`}U*m?>Qa{*q>?VOBX4y`oX=Mm~5@O=%E?-{}QBnPFKj5&aD3PsB?ymV;(oeKk*mf4xC6IyDS!p@m%#j4p1XsH= zN_;g@XXy~e%eY9rk9d1$xAi9Ne@$Mevm zlkHdPtu!px6^)l~<^&>;^ImidsQiy~+Qbm?_gV;yp-A_Qq0D7wUrd!ZG)fOW9*Eap zFa;4F4r?911jl`if)iBUS#Hko+?*c}uGcj!V%GU%9{Dn(*{L@*T^FZqqc{wwyB+h1 zUvjWE*$wpE)YSN|gXPY9d;3%PZ=2)|QT{>{9xZ;4`3hcYA;BYCZ@4Hq8R8<(xo+Mb zH~S;9e7}C~ov>v{Lr;!&Tb0xqFKm~$s-{&AO&pXTwfqTxKPFYYf&%Xw^0JuHvbceD zxM^P*SrJZBp3%uM(*xQ$Lwc&D#na~OtiFm7U$|pfxZ0rVGkR-!HNg%R@Zpg7WF4NM<%G zmmasGL$6aYmiTNggJdCVC9){}Wi#g`^kxb!a5uiQ23h$5x$oy2_tAR&D8>(MzxJ2* z9yN996BVY&1~q~l-w8cVV!6&?oTwx+g{m$g=)qB^^M<+_=T6&@lb99CH5y0ZtzY-t zSW#$eys;jE0A@U!z5-5Pp@+}zddm>~doRJhecmkhZ3w8;JK=uxOFQ^vm>I#r48G)(IlUnlS9>oW&^(H2CQySQLyxFW0f6t*%Q#Fb5QYcj0c}gX z1=7v~tES%Z_SY!Gb%Psz;wrzex9*Zr^^Nq-P?#}2VSL(+(8!-}{9&%|W;2(_wVZY? zNG7A-s;uqqMBiQ>xoN)3=J@YQ7DVwrBI!P3MlH0b{>dBsg!#!wb6{%1e;t8NW-##U zyJE47we?tlttUq}Rp?pz zXjK!BRdOT3cXwVR&BlRC?Wy^BxgUWyWa^{BLkWkr10Z9O&+JfMI)F#YICkwJsmgD(=PaUoKcHM4S6RXT8Tk65R$1{l?0o8$-yKXFl5O~Q#5RsP6>^sLnoEU9J6YaD<4G2S zly5}^9(HLI?7Tff(n%glhkc%C);a0GnH(n6kj6XQR`;4+EAoaHVht~<8k(Id+*C&o zUbg+UP%u>I3FT2m16RYQgY zokwHndI8?XS*Emne*VzUE?&+Plj`HT{k-!2_7KcIOM4LzT_OFx`<;V(~e~g#QtdEMNE;rd%}$Uy9butLb}lmT97Pd{#jRbP0anGZ4GHqrA4O!xPv% z^d9b_nNBY}^pGY9Ud zdbEC^Kkc9J-0Wx`rdjl(q6u5;{26M+tW(o33KcdZ%%J`TUh&W4qQZR>1j6X2jsuDQ zsOi0LXirN!kkBl0fUy&6Vjg_gUoQTSd0IW#ywu5?226B^ruF+&dc4P%Zs9ixI}s zdQ1Du2fbD0#4hDsDn3JeMbdN*V@mXxhr2({+UXF_!my;2&zKJ-(^nxfH{!xmveBY# z>Fu9ddFs$2r>cta>fAhR>r%BSAOYQWv(2bJe=Vad!79@vcYa@2Gg)8YkH={~5_Zas z7QCiWTj1A15pU2~tyPu#oTac|5b`l*U}oNGU~S2+Yyp4IkMymFKO8DTGdQVtw7ZSP zAME0TMh$YMiAg z+Bmi7Z-$Ilx%;N?Ae(FalAZoB26;a$XU~(J8@*f-q(mL~F;f1g4m`S+&0C9mcdvB{ zR_S{IkG&f%@j!aR%>t6N_jC`O@8pNBiSC50A!=D2KE&{8hiGI~=6BcSBrvACzAv&CNFh zQgDOVy8!$tDqKf`ftBkmOsvh~DLr8{^1nd-$3I_~XjFV4ViU*EKX9ZV&mGNn(m)?; zlGjrUJ|$jF0@0k>RNMsVUnWF7egN@*Us7x$PU{gQ+4E$MsEQ-I9hKXQgM{1 z#=q!{+Q{;KibZ)B_^&s@qb3BYI0DxYS9v;rm`G5bvlvR8a@S0 zHLF8*8Ka7&d}}KcdMQE*(V85Mw-i0@1&39W8bwnt#$9yR#|EKnbIqH(WQ}8~8jWjp zo}x6_fbdAIf`d0%t-NyP!tP2#Px||7pu;)FSvT=|NTjU~D$eFRLaiw_{xZ4D8&f$@ zPR=DVSPvH>q3_n!RbO3O2ZfFL15#Dna8U~Km1Q5P8ZW=x*YP-B`efR$^R26Mf#S5k zm|cNT=uDCn+Bk#UJbC;+yXtz{*y za~v0QTx+g2EnS+8pm!uFoGL^iGXCA6VP`qPDVc=cn5`@n8^j@*cmhA-{TiX4*jF|@ z&&=NqQN_M(0={Z9F^VR8acNXkG7&$H0V#}nmEmXFEyVOIuGhLG@)CJ#P2q5oBL@aPHoiXjR3eYBv5%Yc{kJPnT$ zr(EOpH^!JPbaHP7d5ZqJD7gZz7$2Nz3%A)5r?cZg(kYmlcf!P#FnK^XGx(b zlOwaMPFg~mWBJpJRC210ez*uW_;ugXvp3oDP%+L>@w;;R>T+?n1k+vZfkc( z6Yh!qH_;KReQ8O?c{5`NCu|FL%z&9Q7W;vGYm}&%T9*;>-YS|=IcqqB2v%d&k6!vz zg9d`n1!qlN*Emi2Tx_86Yli_$%HD-5$&XPn-_TTBW5dpq9;0V6sZ!t~k~cyv*+xpT zL63ep{dZru9)oyas~kMdhFb$(15QH~2n%n1*U!>97m(Kj)kp?!%X%I28U}w7)dKzx zD2S5iB5Z7I)Hy3Rj@-+V58ZB6Zyx>0|Cr?w>BB5(p2{6_IJnA@!N@o?y3ELFx9ItL z0|rJiQo$X9l^d^}UZTmihx;G}Q8u0J3dF>~>LIMkM2Aa(tvw-JZ?D;{ z=;LhBqKhVm66k7~$ze50NO7AA^Z}8^YHxB}-v`5T?jmXSQ;wb|pqyC^jWU_2eesKJ z0PF|)XI^i>$}ZP&)py0`rzhwa(cUH2)73lHB4D57{W5i57#g-6%7F(zljab7Y?3yb z)eIUGOwtBBi{16F61xe zM%1R_x9Y2?^*8tz+=ZWRYmUqJEsro-y22t4ZwP$I{E<9V1h59DwRyn*q+}pqB%=#U zttvvbY2`!BCIR$uP2{wgXU+htP<3&eHbxFN&+34L-A<~%hz0e$>3y2A&!k)EYmF+!S{@NHwH znb?@xgyEixp0Y~lp@Hp! z`BHGSmw3*jw(yaH#N7ta1lO^$O=T~PX8;XsNZ=qsfJ!jtP2chUseoSxB3L=|TNNkP zX6HxJ5mX3ci9{(H55N~gCvvjC`i6oWpGtbU_H0$5VWbA7Z%r-+FFSabl0^rV0NT~@ zhT|sMt{XeHefov{;jIz~yxJY>^39y9KJ1W*Lg(Glzo!_t?U4g+h}f&W9J9J&X3G!_ zfqtlqZ)S_1Lp^o_C&wSZihdwRa?D;thnoj@t80p56;F-(g?XL-9{F{*N7vvc6YXd6 zjs?vXZm9c8-SyLs$Nc+|bNlNq%=1b#|Da|P!I&TIyKhQW@1Hw=xqaaKrT{JO#b%!h zCQ3`G@+`&Ms3B%+*lFxJ3(kLM-cX=uXlQP|?qj985+eYT)dLREHz;rFj$W;u$rWa_ zo(E$4zetsNw#UK;Q1;@^U@j>p)It-I)WZ<&LRg~C7B=YHf8_%k(A#3uzkNr&x?syp z94W^jyy~&i;+gd%IBn#O^7Lt4R*>KwA6(UrHGC)WuA$uaR7`9;vPHCYUAJFwwjk?z zTkrb3&3$cv6+&^@YiJ1<|5$#g*OLhu&tt)ON{!!lN5H>Z?g@SQCQStK>qLR)p1tcZ z5%x*R)aI{Il~YwWj%~X?41F_DAOxI{n_KfMq~hJlocN07+|BZHLPv`GUHNmSvRVJRxx!{S8y&SsY}caqKEgWY@8 zNJHgD+w@{NKE^%KD(@~-iny=LgJq-=S|;fVOpj1XOZ5Fq3jm%4qd14N;rlQS+@W1j zR09f}g@x_C8U;BVim;`$ql8N_SY_cHf(H3<_B@irJ)xB9CuC|?8svalXuq27@YXfi-bBJS@I4OLYMJVKwnmG3{J zj}k7EAs>nv*`6otI4C@?Ld0N2_yK_aEF#%<`&Zic6H&ySb}=5SHEb8tX=jDX^*E5$ z6~p~@EHjP3@0gEwNQBY}wFH^o{Q!jUrW=6TWfvylt3Bsw>PgK>$8p8$x?rH=+CfBAD3*-oHqJDg7X&ia%l4eCJXX2a5t>{d)xSc z@rUkM`$O&&P=?av$xNNIxl4QWt5Af?%2I1Ob50dQpp#-s;vzPK+tNOTAILtt0kMBj z&!!+%L!!iEA`fCy9t7MT2Uf_u?}da4l<92n--)-$YP=+(!lj#1)t>c&JgsayX(1|m zLa{$h@z=2X1<}lbi`0!j)r$r@#F?o7^B?F))Hm|26d?C~I~hE!W&*PvuId!0 z+rCW=nALhHrcX0|YpN7KE{uyX<+CHCA&{eeQi_NmU)jGima__a${-t`?O472{$MaB zOI1z_igCQ@kvz|BAq8f8-ckR%{{@A;CpLn>$RRjUU2YX?@Mg)nKy`m2XO^z2Q;X}PISJ^d$BkwLruLq#-fH*RUs@D( zd5=mL&6TZOcAJ!=d@fv;P>Z`Ax@1U$s$bpCr)bzsx$GbnYS~zhr3rEuURy{E?p9y2 zr@s-JpX*JFZLtVLD{5XbGtb40o%i12uVHO5o7dk78)Y6p=i6v&lD-1-fc-7 zDcpd78*Q0$53)C1+g%^624CLJ1v5iqf=R9= zdh|Rep;<=Rs-+6&3ee`bcAax{hZpKyzo3uu79Th{x7okqAomdy-aiK4r}8nDO_N+0 zqB9HV8?~>SDS5@s@jv;6)U%pV8Ub&C8c{hxx9eG;BngY#jjqGD&G29WgFMT6+$HWo z_U)Ia^On2n3N07q>{#cSnJh`Z@3PkRA;B>s^;*7u9dGhkVetK9hBs{LG6aID#yaI$ zmRV#4J5cF{|26FJ?a#bVZqq=8d{!}nnt#>i{XD5ddH?N>cW#MpWC+j;`7O;6p@@3* zo!m4jixdZ81UdWyEu=L~H=P!&S1+`GrOVSBMM#=)zB-7;b=IA31{l-GX<}} zMM5ZXdbmCSQQoh0X{grRiN<@%k~TsI_~6F(@Fhj1H*G)2W0z6rk^NiVaouZjRK89r zx|>M3BQ5&n9CE5Q9gwZ*gFc#y!7KRb-n z#cl?axx$b)d?kr?@R=66%^>IP2~OM32mpzvs6z})-zsV;w2`1gb0l{Z=FdY&j~L!N zKr7!%ho$|?{GHcX&Urxy?jC~k+-d2g--_y*t9tRt(6{Q|h@1V&{dkMZ) z&1q?p%9!Sr+dpgo_ewCh%l~j{Z`mTdo>yT{Y_?|!VNfb5G40vFnJ1V20fX%`|2__l z3Et`DnZxxQ9Lob}Y`v)NHCT>Du4nHf=Vm+KSOhYGj&TCpU!OyK+|Y$cUN6`E~EJ!MvbkhdOVLH*8fz$VdfnR`{eY?jqGa&7e< z!0@y=gdU%g9wgvmI)wFZ;%hJ`Tn=ZcMsUpziP_CFM&HHqrS7`?R!;q0qg3_O%VY7I zydCNlU~KBLG-PCq!N0f`(#G0*%3YFoRq+}cHr)x^+qLwLO#QNZ!{3AXtZzZs|9N!~ zPT~9<%2ccILmU(SuNuJd5(PP~#Y$u$aDNsDkecZqfs)3wKM4D2Vz~(BzBlA0LXuq-F&r<= zP&%Io5+9z_!GX5~K5E+r3T~?#R1s4f{!9*I=SEl11h^}GLHE!qsiy)9*qMYKyo7C4 zuX0CN;k@Z-{h-9m!FTv&_^l_3#d_P;HPS1BlLK>O?r3Hq#pB}ZYv%dzrbl&3^d(>& zsNT?x8QyXT$7VYxqiWdi^VPG~2FJVQnB|0KgSFmepkAT=urrTD5{n+!qX(u!8}g~0 zn7it`wFt9EhnALrH)f|CVNWWkB_Kbn)>SUV)=EbQEkpfbD;l63*<$(0n!8R|opCcY zDN1=UWZwlgZ`mG!&)|Kq5?YtEU?HfuV(TtY@AxJ~ut!@7H`AKYNsWa{`3#Q$p~ZW_R@UmSM=OZWhsU=%#qLy(H(9fpa{(H zJuCulhUhZRL6!lv-&~%@lnrYtS|6Tj7P$|uk=<$%8CArZLs!Xv=OKa}sN?%K#-M@sJx<52AOXA$eii1J`eX4Wm`-VYDz9j?9I`|)^I zc<;`rff)ygXuhV#VT7R{UHE+_a3V#WS2d`LU)Pv&48|ffgl>voc*|GI)7sNf1Ok^@ zPqb5&RJfQnQq``PYSdn;NDMVc6n;kl-p)C-YDp>d&Px@RtICMOm0^E91E4>ANWxE~ z!u26|+Y<;6C1GsNP>>`nT?h|FvEdkboj!WXr(R8t3`sopWudSIs3cO&dARPk=P!<( z^sO>u+`WJoz`c~xW!pElyEPOA46p0KFQn1#+rYLshh5z~pI#tw+NCJ)c^@E^AhbX6bA`)x8&@1LQa(|gYnn9iB{&p) zE<$J&l(>Ef%?~dqS=~ko44Hl1XyH}3x={!ZWf^O|y{*YCcnc^H90nbsy};`2k3(#> zIM%{He0l%wj>H~&GZ1;^u~3EQ=-Fua{#&Jc!EsmD(^lhklZ@LRs!3y_&tn@zxCc9Y z@$L5vgm@aThn?Z+xbK(2EzU{dO>LO9*dpawiEL^4*Xtud*UA;~cqMYP zYNVGgyJ?>}xmJlBuMl7GLDU0xAiH795T;{7N`<-Z&Z{iT7TY*}g(2gU04tIXNcD3~ znomVfVm`&=J_@J9?DVFoVNM~MS?1OC*~KM^PH!Mmu^%*_ufe@&Q{Pt zm6^?u^bLYNGO^wJ*3txSKZ?GVxg_6FUSch>vL`sZ6>=qJ6)T{R6?813Qxs>0qFl;t zoVTrRyIx5l>UATHw)>)1Aef~r{6?H^FVO<12s}%{n(P!83RD+CooF4z zlex|T`x9_UNVsfQ^5vkZSF*;ME%`QQ-JK^ljf|atCcj;<$J-d3 z_Y|rDYXmE{L*K+Uu|CeeY|V~BM%>sQ7l<*-W7(DKnz@+g{u9Cke|W>aDZ zP7os>d8;kci^@deCzR)a-s3R!!vztYW;g3+FWD*_&4*ldMOO5_ZoLa^K=4hYY(*lY`uO)TxU*`*Z6*iQ z)GLa#$0zKmaP_*S(&1z)Og4z7o^W*$PuuUC1=LW^3M_z+7LM*#olwI8M1J}J7@+IV zG-ComYMmS;1eB@C4)oDBP>=5F8qTp}*kxCa#+?GDWulpbU|1BcD=h4TJ1uDCr=AHd zRD4<8>KiV0=nng{sxE&d%BNcWo=L6cj9a$vr!VC3)JrAc-m8?|SX9-;9>bfd6Lakd zPgfwg?zN`N8VyK*f;SGd&`da})jR%2E$aNeEpqlv>G-~=zBpkXs4gSA&zU}hTfMom z{AI`~`SWLayxp3wdNwTCy+#^EqJ9oB43r(nD>d`hTyaiYF;ylJY$h{sJ_86&H7UGaJ%X@>saq!~ zw%0(=d;Iv9$11Nus5m1x_If;Q>_~_h^Y3@00*|@K?*XvLgM;}CXODYr(?ev0zEHVP zf!e_iS|o-bSNMeGS-wl!(YFx{To>7O=Nj15Z=Z35W{L@(*im1)f7beP%#eVw2#~6!c3c|E-%cI@eQ>COByee&n<9O(&39wK^^;JP>KiX#x$~h06vLjX z2VC}UK}Uj;li6L8$4OsZ{#Ra+8`EXaC#!m+V>d1e_bgZW)pr-GW}>gxPvuMUq2K;= zK0BbN$2=NTr_9yeET6+`h>LgrB36L^+47C_yl!EYQV+kF;I|+F@_{C+LH-#e0%#$-P1N`D{+b7vc0fh`;uzSQw;_VWt1vp-DQW2Ax-$yrJ#d%;qTIrt-ho4 zi+l;M1rg>??e4i73OE}feqyfMA$`nWEY?YhGpYz>FPLkvZ8lZ!4}&9#O1gt&8+?SO zQd!QIfnWJHyP0qxtt2d*x28lop00ad`88^;7{9gSk;|{GrXmh!P$f#%n_u2B1736P zyM~S`_V?5SQ>tnTmZw-UKRIQ3<}w74%`Iu)bmB{o)x%)K(X4l}7}~xDJFpmir586v zxiPmPss$%v*Ur9Ww|L7-XK;Og&ASLafk_e;%+6=DUmi75VnWG182F5-`ZZ&t(3{|D zu*ANy#>3dhyqWiTx^ZaN1`*HqQjrx0MV4v@VWEXJcacXcwPGdkTEqaA=2D0V4(q$R z7t?9rYR^jA`C|rAcXt=cI8T)0LFQvtG&T1i-*3p2z==dA7B_XZhn$3?V?_6`z6g(=7o!3VuIG z>;St-Wj49oJ^kaN8L0I13jcVaN}~DIAH)FRgvXp|JHwEikyxVLs;fIAGGv|^px?5b zt6A0++yV7c=1^cl^T~Xgv}Nr;1rQ)nh!SPtgi!*95W%Pq-d7|{Y2_=Z^rJ5;0M&nj zR6bZq)FO+?!@ZG9vU7GZqCZ&=*|J9`!}kRFihlHxXj52nnRa{u(%&G)(dt8NZ^~L# z`bw!hhzT%|QRy_?)&Dp{)ZJjfvEHBZ<{$Uws);a|!DaVFUA30NWH2x&s8(^feIKo! zVrvP1izIPx14$ynnI0n|LgFGxS1_>7Qwm;axKO6))u2>*bB5Eb%2KXzwTFUE()Rl> zJco6rS2dATVsn-;RsL_o@8Lk7<@%C#bsQ~UiQU&ImAxvLw_uvtwo;;?*!{V&z(N!Sy^TatVC-i*=So_aOiqZ$FgZ=18D{h!(xd za4Li8i)3`Y%Jw{>WqM}RfK&?`=om}c))0M;*DB0IKN77*EX*@ zQ;UoFtEFwT=e?7pX!Qr=N|V*_{eF1QN(bKABxTyY=C_b8?K&-UF64~n{h!j$1%tk8 zt-IPDDzHMjcy5fXz=eYK1bRTPHW04tS*Zcr)T^!pwJxc}j~B2U*^MwNu@+~2yn4Z? zbN>QsY6)LN>}LB%F}(W2$8SWHM%@RIzBgcKeF`V~jX=n|SEEkvVb=b?8`I!HGW8ql*?EP~ z&)-+gwPKX`3(vNChcc6j1b@r`kxP>HsSCw9(>#h5meygrn@H{D2{*^0egsc^ZegG9 zTEGoaOFgU5tRw=oDAG(~Bcwj=U*>7VI0=-Arz3WXi;`Qb@mU(IC8mP895pwq?36jM zJ)|79=>WY!79!i!GNm)ePKG{QGm+zQlU|p`8>$S=WrDhmRW;$I&D9W&qx4NL3TwCA zdo#~rQUX{MftO6uOrD(dv#2qHw}rjU2!bgehoCO!`*QSvh~Qu!&w(JXA7PpHL+zHD zHZ;;m#NClZtK;z>mu$}``Z#j)WxMhGCDvnJ|bxI?op0b~@x2JqlqNyAy-Cb`?owOhd|J4ULP zpcRms31zQzP+~HeY}ZdXa+`iZeF$OwXKKVG$9_RixQ64YML*;+wbQ z6*yN+WgOUb6h)V*Z$8jpNUz5+LSa#%MJe^5D&BR1FcD;6Dtus&3?R@t#Fb*Q$qT+# zK!jq7QC^cW_{2a{Qc{vdP(I&{o(_*%JI5jY`r&!SHzeEOus6y}5Fb~y7f8|Q4Z(2= zo+1!hYhyEm^^OO?R)-^33jev$eqkLu-2gV+q`F zKLE88|2>k@enVw@K!LI|BaxzIjz=!_f%cG<+t6J+zUz3Nu;j^-{8I?tvIzN4(jqI& zZ1SA(Tw!=b>jdV9qx)<*dFaQ@S*E`2jTZRVy6M{U(R)WG z083aWpY&h&u4Ct{$Dw7qZ&E)OguV0UI_t4BD5|bx8sJSdG&Q2aEegyk+t+OU@&!^< zT%4)-E`4V;wv9O7$gE%?dhqFdhkR?HnsT03$BcG!2DUN&tOYN@8;Po*{ggd{Aie}0qf+o>>`pTsNl^t?iS!MszK7+t@)7f z$xvAoQ{Z43fkt~JVX>mpyM$hul;$S(#?ZI{(n+B&&pK(RMUe^z`W}Y?LS8FVz{$TF zv;`L^wz?mBqwpa}gG zG9}Q_1{PJGZkQEWn1gQfo0^zlH5leGrQh_#3J(X|VFL6wmw&jPPCPkcXkp>O zY9an|wd}<7yzgYbPhx(b#Bz--{bs~?dbHYTDnZV9eHzrKFME8B{#4;$U+CP>h|gl% zN#A@u-BobXE>NjNBAxk?(ob)#H&dsYV7^$}QMzw4SR$x;iVQU^esu*^VgcpS2&B)G zc18TPST)5MB+j`Uh*za6lK+)`Y2k4>w%6ofpmNr2-8I~eS-hCvl4sL(IgzbF9O6Sf z4Furr>AB(0em}ekLpww&78T+eXX^rPQ{?#D) z^*17)UsESQM1wgh{Vz%DGdL@~OscnijH{7oFXS6;8u6j74r%*RnU`~LPnAhz z*#WtVO9+-J+?Xd4Llxo%r%?uewfnZ)gxW!9BOW2gfGPBc(B$XCA7yz+sZZi#V*NTR zYv@Ke9m7rzy}wc?^ZCS#{ri(QH>l5U=# zjp&I5p`l8ayWs(6U6uNI^k-5J$LOu8!Hq7`DyM+XORwM-e#rMn`M*v}w@OYGmRt=9 zKJ<#2V|eugT??5O#LI@>6(9zjYMj%0r&mLc!6Y!67HSsrD?V&` zwkc_3JkxpTsh`h(t(&{mX38a=I@W&Axk!3B5SLLUFT?G`&iuwxi|Es)L>i(%yHSo3nx1(V=oO8lxQtnr9fS^ z!B&jB)i)PBVOD7~{m|PR3d+ng(G|J{F0uSd*tzenn>9uR z*0j%R38(N2>9VJV=K6X=nM;f(Ix)#}czD_0TdYkJX|pN3@4a<1#*54~+3I|tq<3c& z=jA@_xkJr2iA=olR0WEz@}fNMF#a+~~*Wl}Eq%v}ykifgd zC?9NW{AxB@S1ud!G9Q4vAqhMb{J`|snRFqlDo0Ti6c9>ULQ(_+m&Aih7qqKH1^0JUEfH6_MJg39wUYc zExt{%LycR&Mps>+hcD4wSk;NXNYxk(w~XA=Pc*AhQhwYRrFZbCF(i{e2mX;2w^#tC zRS9e=`@jW_Wo@;WI^DVP32$wTvcFYwe2)};s1PJC)TX>MgY0;vX{7J%2s=TtvC1FC zEmuC1$*RhdcI$aD(?V;QS{(>b7U+U-YP4U(#vR-J4V_M&^prh0sFxZ1ipakl;9-W$ zQ-#s@&6SAw;k(9rhzZ%WlR88mmK)<*(0J4q-+#CeV+t7(o2@K-doLJTqMOR)b}y5d zRZ#LqXVFp=rnsfNVtdX=lT%UG|Fc1xq#<6Bmaxo$Z#^;W7uMx z#=eG2^}hM3AY8fR@hhlZkul4(c=C+<;NVAL45z+K7q%^0hpK-^meE7|-y6(4E+l?5lVdugJ@M$I@@AMnKo={rt26a@318r+d6M9ZZ| zL?RCGtRKu<-M$tsj&H`~!5WP``4NbkNlbv44Dgqrmk&kvA)^Xa@G4oe@@4%wEb1Gy ze13CIX{3LZ5}LnNd%twFdTL?K0wHn??SZxkmkNjyGb;Yte>@{lYsmEL%>ZQxQMa@M z^%~9TM=AE4ZTEHc@j$JenEDuwb`s`y#-S>V77FhODnp+3-3q9VVDCwL;1IB?P~U>v z$YrF;8on{wQ7?$#qJSD?M$jnJ1L^DVj;WRw(gfbcaUDN4hrFc98I* zm-LQde(=HGfp}47fMi{2@!y?+zvV58!F=_SxG23LO%Y~=+7oV^BOM3S?~awA;#vB7 zy4uV!ac6N3l?YZj)OaT9<3}@=z*?*98TEv%s)#1_OP-z%X}r8Dby1Eyfw=Fyg1Xbe z>~qTr>}pG#Y)RkBxmTR4zP{BWOU<4hS#Was+jZ_-JIgaGsN8gw3J_%f$A{u z`{eHmGh1rz;#Xy1zfSl+a*f})!2Pdu*X;p88S$qJRw?=EVJ#Nu(I1%U`}gLb(R`KU z6g08S-m3{X5PoWaAw8UhI6upN(|G$$lq?Xi_no;KfY_OCPTQN3gTNW8N0B7OKq{#c zpz)Y?D?IVoUYSwS=x9bzR+f0U!d~xQxR^A3zuVnq>d7HC;F*9|UdiVR0)Z}LQz{OShifn_1}uo7g9jQqQ2_s6WWgns-{xC-dYtOBxp zu})~H*t9r%lMxGGy#L-=IJc`GgVyv|`l|p_9>+^U4kOO3^h<1Vvc=(2m7{J;TY!jQ zdceu=lhGx4N|8AQ9Bzp%hLn~@X<3PrhPG=+ZMcz|v}%)gyDw!Z6;SV&rfK*fyi&Od zzSTK?WK%?Wxv4Skqf(3WT5WrBan+`sroM_zsWcCP=TcdKv)5n#pS8afcMZi;Pbrg->Nc*h;-z$rx@A>EW@J-#>~b>TO;hAFg=Seo zPEJmi?^N0C^YhC(;)Nu@QIo2@@uk&ABc{FHssNU+`!Tn%b!;~g_fqcxfQ{NVj!#bd z#<#_u10hY*Ny{cHYJ2<(vH$;O|KSq(N>PBX4TXe4s-wZoZS;>1*gd5pBobA)Iqe|5M8bzNG`;$29PCy*fs+x*+{50qebf!MyJp)g zS4GQSyZLzPYLzs(Dd@6hprL^r(vX^_^ONQ|VliklhUst+8xxZj)YTgOEX2CglaAxrZo^q>&_orSZ7l(z^r^mWU7{=1Yy>iFulxn$R4A666 z+Ozq!{Yj%j4B6sif>z4yCTlz{^2o5W_gC`hl1ypKOCk)kJ=!h~He@LBMtvR6*xzr2 zEHR0V@#Lr_8Hx(44#=gw)d%D#w*z8d(c?Oe0lDPt>{ttXOzXu1FKFHh&fID&Pj(T^ zb8{18DYMW(0R7_Oq_GwzqnOBtTIV-8J%ZaA;@>vKnzz!}3qU{(pDipZCdX zPe8L3D6%u|bwJXhLJA8C(%Z%-z3rn6uUCK$IX3Rtr8K-L_F_@o1~}J@AP!5nZ`M&8 zEGuDDxN2VDr8?Wx=Uy@G*4M*n?}PIXjUX|H+rEzP{X&sn1GvJ5k{M*qN7x}LR%<+0 zhfmH`)HHc!!~j}|Jty6)|@Ksy`-fh|-(S4LbtjEGmZXv;!H@{Le{^Go#ZNsSYs zG`bj8Nz(oAFh|D9{Z95)*F@&lNj~11;%z6>wXCFmY?81Un>&f}WX#d2C6d?I*K_() zhwKd9O7q>s&pgpC4NelwtJUw{UrN}Hf8pTv|~ zUJOH@hr=w{?XO!&dBue!LL01d2K;{PIYCn%%~$o@?>6dVNnUyC+ZeH7f#E}!$J@zU zZ60G*}_R-B< zo~@VILHFI+!mM5hM>nyfZT(y1agNJ$F^y6^`rAYbrjuDA=;1_{yY$)&DtbaojlqX( znD0}_>wnT$s_scwr8Sup6?7FL1cX>_>`c*^L#PJV+_gqlK^wR9B&*%>m2)vfiI=AsfcrO0l!Bn^UgHM(72Y(Z+*nn6gQb#FtEKoVs{EQz!mRFHqYo>7_y6rFG z_(YA#V3x(J;aCIqHLtGM2uJ0|+^OZpV-;#OyjTvI#J+dl(?Qe}EEX$hh^WHiB4077 zL(!2F#ik9c2>c}PLer+7p%K{wvd+R1v$8BXZRF$O>yg=E7<*~~Rj>8Y)p!{08tw{n z}poZ&rN_A+>*ihpa!|cPaqnh1Tp(rFylb1U50U((_usI!}IbGe{$b4EiM z>00)lt=n+5Ahs^N_#8U|q2G5RE%D3~(U*CpBhMkbr?%j-cF^BPTKbkI^+z^h_S7R}iGd(+ogl$u?sYxjiJq(mKA%|2bZFx?Wm%Vx#!7i}X7ad2Exc={ z?3dX7w7~xHk%2L6Cv~Ra%J&0b=P`m5mW+Jy;qye zPek_Q!u#U-x<3u|jsH|gPmi=HSXvX@<-v^*cXf58^{RCAor<>vx7EOr6-!HRXE4EZ zx*+CqO;P>B*F=a|rW(rVMuxYgB3;!ws!Xl9wrQ_NmxeONN(L~}@t?{&W1k8yZQBoLNC=p{bzB!qjyT=(0ecjyJ~J2C#_eCpvrWA!Kew4~l~Ej(L&dg!e6*%+OER!S7orqv2(bGBfcV zdsbdpasfoROA(z43Q1&(11PbVQOy1jWoT$zw_5bCg;Vd!K7Kq$7uIUP4AwKlQUEiL zRWe2`_pC-3l3rFfxx^ zX*Q*&ru^NBDt*V}dW8yD)F)M9!gVMSR&W-w|Zwbcfea=xMD(V2nJ zH#$jWU5V(_YEo)~D9Ve1NPG`mol-ba%B)JpLf>Jvk;pYwV2zB&*-1%-JRZV^wbXTl zh?CA%S63x@A2K|YR4HqY3L=>lIj>Qq^{UdCj=(Um4Lqu3|<6pTAScQJr2I zk?w3QO|5VpMv%{QI^u)_qX;}+#*8~X0$HI_{s33uZWSO~2$*@mC7+;>z#O}_= z8XbNyGo%-9JW+m@dxd+Fc?1!SBKwkDLGn5)QN^6RuP#yau^)>gL)0s&K3@JaQ}Pci z@EZ$UJpJEpeV{-MuYj8~@PK0ZmGqF2B$pYy<4gzDtv6a{qu+mmCMl(Kqq_IYXk7_b z+qmH!UUb5ey*8}IPByIg&B^uC&bH3OOwrc32*rfwWAPw2)r-P6=m=iVJ1XxIv_M2V znUr+8K2lw9ZFkd>+v=M3zjXz~2QE5rVNs=MDdGEpc3r)VE-`&feED%lt=17w<*k9x zj@PGOB?jIM^~Y`YccG-zCep?f@1LMakpUra(UMi5WkmWNslO;LaA4gsqdz*KZ#0yr z%D&BWfL^0Pw{?<$qhsS%Ti)i%Js)-hc#DW1nsq$7bfzqc-TzqK+S)3q4$ZxhgrDYA z#K!SggZD3};Qwr07M_{(2pT@i$!aX8pp(r9YozB1W zlIO5y+iBV&VH)S(Z&)leSE1^+FMP5PAGFXQ*v~&g{W3pz_tNC9C5YP~SDPfPl``?k zVhH~ks@!FrqFxXA{BVg^O@xqgWX7iUSZeQj{ixy8yXrU zxuNmmTQJqzRdBZd4T8c_0mFBnj&t@R{@{Gj(9mi~IWY>ZK)*OqTO`>$#dYW>HzY)^% zj70tp1OKdz@Q>xZ3v2>6nlEXxV2xLnm#ecZA5ZSqrTwX8*QDnwL<$Kof z!0YB$HyPj==@0yGZ}Oi@%Y_PF5d@;kpB2doft|wp)@l55oz+z?9?Q>{{7ABE@=dyP z>zx-lD!&nM2IF;o2NUS%)GJwO zj}8vr+bA@yXOiVaADwJn%haqkW0y%Ff2uKJV`EF8SFdq|U^7lP`Pcn-1Q+>-%=KV~ zl$IdmBfYwMqY$hyzlizzxPKIvR~+MyAHlEA?^zWUOZ@&Euk7W{XDWifap!*mogNr! zN+f~#Aiv&-H4bNNEHtafyzbe@$Yp0plYhodyMu}U@|>>NNJ>Eg1+GEC)J!m@_U}s? z1~2I{2W%o*bC8FWy5P-6?00u_BQrbC=|_fld~DUUUV2p*d@gHJ#Jn zN$ThE(s=*JidmIZV2zC#)M1U&1B}@I#b$A%cL0B4*elGnusR9~3YAhVa}m+&0shwY z$kXrqUkg8tH4;l&9U*A$?SIDni#cHFfU7pFR|=tbAHE|()HwS7q_X&oZ+GbXM#fg3 zH}y{D)-vd9)JjEoVR=~#Y*QN1|MC#96l!87_yDrLz!#`jGBPrPZ|?65OCc;md>;HC z3F&Xe;a8<>mflMEZ^mGo4j!)ZNavSd zMTVi3Z}!n>Y#$jx%E-uw{*9pcbltbGcoQn9;BuW-3>I(3@FV5aHSy$&Gpr1@Dr5jC3muo?Hpc$+V(PBZR#iYR0`Ed5CBB1=d- zbgET{urRT)J5%Tvn$sMQR~umnI9?*RtLdpUacm_<$`?(&wjxZ46>x~Nt0DhMQ2#NU zGC?rx3u*%l@`6L2B&xjsA2*P;4Nh<)}#F|9xNUJkw{NF zCKqK0mh)rO_~TV4VZaD6y>|3O6O$r7d(9!+&-dLK#5;3bFU$`{m`lkIj5q(M}v#ytQRL!zgV+84WXupw*tv zpB=dKr75R;|Mal_@g?#ZVBsBx|LnpbC8>WUYxE~6r2Z0Bym)@yVh(Wj8+i4W-We&* zupS!&A*ev7!pKSoPF20Uyf)6xKw!C4d6m;7VRZ?J1-8E04gZ})y%GsM3uzAz!cNHM z>We2Bm>h@UchyaW1SV~tu`N(iLh(Jh4XLwp^0IY&qGl86{_SjZ!S*n8R<-qqZ!ATc zWiqIdz_>pNWoBju|5Z-4(qN}s+g<^xQb0f;nh6|2*^G>tRbh>Y66o)}c9Jw^>EubK zR?#}t1f`f&fCR9ade3JKA@eNTc)7H2vFA^tTLmsvP9I_13bIIXBsN_rUiBdDH$pp` z`R-u@vc83x6cA~Nt(Dehc-?+Rm;0R^+y7XKhW#N2*G1f%_4ah$fBNc2zog6$g=@5h zT6RAt2*U+oZyjv(sF$!WNsHH{f%6&9qg$4hUHeBR{!JV zgnoeCOYIi{=he?Jv{^XODW&!?!s^@|Nj%?@hBK6@pC@6Ac4~)X!Bh=!s%to-QF+U1 zG?vaEIU{&H$LKP*A4CZLtGKr^#W+a9(9=}F<|rcvR}UjvX8wUr2dIx9I~`}aO2Kp6 zbFXkmF}|+vWVDr}#B$Z-Wsr%I=f#5%)Rw^@`O&h{JjeRl+mtVGZAD?F8yE!a+Xt+& z*aU6(_t<3T)hY0nmGui<#C{ypOW+==o9kD-=r3iM>GJ$X4fC&){B8<9KDz6zy%F#= zP!!6fq8q~L_bJgb%3@cIr;GlLxJ?c|v3Dx1MkXa1MOpQa6>n6>opw8x4-&XMb!9nL zSatSCeNq9p3@H0m<2K!Ve`lKO%jJ=ab2$xCr}d+vI-br9Tbu zIY76i`d0|SH`bO}EV0-9uT#WQX^+QN(YMLu1ZTbS?Udlm$@l=wB1lj#ucY_Q%*<3| z;s94|>Pb)AEM7vhIwmFjs+o@?Xos4gbEb7PRb43lRJTc>2_*~r!+z{yy^^qBXwRa5Zjpvo#KeM>NkXTuYG)c}K-`%Ka4&MHfmu0Lu;Sn2Fifixc_wvz90U42LQ(VzS#-9d<`M6o|u27xfvv0KmvqDLuukiTMoM0 zH4&f%&c|WS1c7nqc>A5@1?ZB6w1RYYgJFMoOv6g;!P2#Auq^o0F142KO)IjtOt-;np6DFQ$?k+ffc`8nk=kfULPH3x^a51m7SUJ3j!@uCx?O=Vek{&;cKi2RW0xx+6 z4lrZ&p!4&$^VIHdGabvN>8+re#gbD9Z(F83OdmOUCx)(@`BB&0y&bHBCXHxgKc*%B z)6>>qQ}v~0UK9XpRSk8G#xiXl4I9H_B~0zk2kR62gH!D$u73u;|Au3Cw7~hj{p&mK zKQyLi_->m;Gfw8iYoh(ZvDr8$L$ThnoE}tpB;Q40oF*qNgbyETuy0k0pjB(?2y_JW z_a|z8JtY6O^ljDh9bUHrQ>9@+E3yr7|5LQf3xma%OG#0F)`4XjwTK}6>!=XeIgNRd zGb=Noi|ZA3c6YzDULwf&DsgfS&Al1ha!RRow%2A}V@O0BtsWSZzp1u_g}uC7eoi@Y zx1A$fvaUHPIOVT)s(QT+txTthalY@QqtWesnXpb-Q68Zmy&|Cba!_* z2<%OFcW)$rn{)0x_k`yi-~Znjk7GRhVYykSBYCP&uyNa~Un&D<*ejL9~WRxBg z3Mm!7&#Z0V>g%i1bxi#SDE_B`gO!>b{}3rM!&^5%S%pz=h(_~4L!FJ?*5RO_MuT^= zYk{JVGG1L(G5lgp>)qLKozZ-vFBLO0u@z3~q^pOAHk(y#nxVl^sX##3u5+kcznyqh84*pQ3*m*Q7rD(l1AHk6BrHQEM9I zwHW3JDKuZ#gfW?w%H=S7U%&E+!1Q>DpMZqPQmtY><>Vh667q#Kw>8^|R%GCQi6QMwbSbWIs3!n$a1!5)NEaKJ7pJ3= zS)Wlmow7qKXLt~$8s26pU$AU$8XL@X$va3R^+6HeqKX7{WOu4uQCDMd8{9y9vD(i* z6l`wW7MF&KohLbZK9X4ha1<)Y=>{SB6MwJaLFSC8`d z{89YllldXr=8g*Kmb>15JSfrZKoI z4-4sU4}d4(jS>sNjQx@x(P8P!ljMrB9592XRt)DIl}?4y(Tx`BMdE|v_P~rpS7^4n zz82KgVy)r|dZU2t6FTjnuE{GB#I?kFv2i>gBQIf^Sa@7wMRz+eDjlR%3g|@(E4USn zW*(sY1$tEkGYCUJe=iI6?_@?8%^4zTalYcn_6(i$M!J5F#M9RP<|ww_4x+`URyJSV z_vbk~tL#^c#^j$@c1;F0e>_5$J1xT1=a&1TwHoMPY+~~-~lIBl{tSOPPe(*)a zv6bU+BM#+n;%tsj`k?=hIX$PdLCzhVSDyb?w{aGimO%vxc~)5O$MXF>!wAV09+xSu z2Imo*IUYq(B9|Dj2+8)J)cyJ+1kF_uTFh7O=R&z1uU0WtluH^Sl2BU&nUCEZ0a+Sk z+nxC=MdMMg{#R}9kGXUp21MKe8!(Bh5r5l39WN*wPt@)gXHB!cGc%!CCnG&#Ol1Ru zLt+V*orV}}_^VrQ{t&o-Y`H%>*qOnX)5G;!znO?CFA-+|jlXCpvInD4mFcW!{lB{| z{^;bt;lpgOS=4IIm;QSM=8u{F$rGFT?9NFXizxl4#`xdnIyGRj#Fg#G{P!mDa$xBH z@Tlbc2kQQJsDKEtyXQK4&z<7moBRO#0JQm->wW>-|8!$N37)MU2eJGwVx|9SqQD2% z+TZW=0{%Pwe{M6AR>xKL_-5GeEdt)ZQqV|_85v>7T^j^`pq4xzTNaD%uh zQfm8Na@U9+S^ADSJ1y1nwjFpy`a0A(>Idn$6M||={pL&<+1xQ(3sMw2wR*>-gFJb2SzUSR;?{n6e2cWX^?hx} zB;xF6ct))0qX$dya`?{^p%*y^wO8%5yk9MNT=-soN)SXN(9*rL{{D)Jf|8pw-8TRM z<#cj|1ek_JOFJNOF8r2va9So8_m(eg(DY9b+z*!Nk%MDs7ROy(1P=FE8+CNoCf#i^b3Hx2HvJpOZQtra zrk!YF?Xx9yB=J}_EO`N8oHT7f^}?~|?A`|!6ACXFPfN%?dKY~U4-5C5$`7-&P+hlF z+*D%5M?*DBR%V~^7gt&yuyE}78R52qEJ*!A;R1wsyc|(UJT^Tx!&+;bk^4tzy!82l z+TbL=#3g(Z_#Aljfdwn|D*bxgRe;Mg+@mKT`EjqgfF^L^K*$T5^dUL(5VidZeFSgr zfS`dMCE(8@$>h0~>tXQW^GA_NsJXd8_Xoci^09A_8af;8zFHr%2tjK>KgTI%hZS^` zNtzJ?oXld3_A!mll4Q{)^weSJ!jiAM;%41}v@-4u&8^hH(YC-tdQu3%O1m6Y7Ord~ zdFRN2@OOPpKpoe^#_IkGJ#gW$z6tZ`OZEqAYU?Lm@QntjU9v|^erj$Ww;d+mN%|T( z18Xf#e@#nTQ%cTe*QM|7+m0qqoJ!|+A`tB`fdv!-aO!Xvz)wVoVf1iW@i;HAs}hX%{`VW zOH^H*EnCvUEj`8yP!GPIs4K5cP=m)#H1vFdIc z+Mt{E4SrGOL~JTJe7JFAvrtpH3@9!AQtHFSiOyfE|BXX30#3D-OXttlfrtlggKxw} z0*I#j3~ZzWKlzVD>oyyPxH1#p3V*`KBo*uCBVVU)v9)))5V1EGLneKKODCR|uyQk4 zdPgKTI#JiC+o;QdE9 zmK??&8^=*$WtQWqS3vt4HmbH9+kdJZ{bjxk9L6U~XFhpYi z=M{EbQFI{B9c;Zl7Xr(ED;x3{t^M?KB)=ZFIIdV%SqW=Hk-M6&CtokYQDXOc?nKvB%X zNeuSRX6xflmjDq)Dfju1M>LphUrY}Qxt`3$OzrK&iybekqR-_~1@;2JzHc`EPST^K zYoKFlEF`##6S9Qo9msl^i(Bb7TP>}qMYUGn9-ZCEc-_ub+OF@0Zay;XBy}YDaxz;J zI={_VA8;|AOKo&_&GU`N=KT8n<(r^TglUvAiu5##uJ0umJ8PI&-iny=X>Wysb(>wo z5EHA&p8B&UbY;YWEwCvw3Kf{LwfpCS@9>iu<--@{+5p7pkZ@I*66d*Y;@sd`Id> z`iR@O?xf%PLEAa9#Og$)*k^7>&LD`%K%+cyFXa5@xKyiyrA3zgX5lLuBQyQWyN?T% zafRDLONu#iJSmdXA(O4UPl4Fnro6D3&EycHl-imPB}G7KEMP2Xi$sB#QA;9`M>Nwr z@9YddAp@L#DUh`ha0-Wx;wKqFn7XVSy_4ZL73*@H`O^%3;GIBVJ7#nzu(oO--UWR; zC-@p9vONex#CmYUZ4+aEF%DYcXV9!pN_I8UoSng%oG%HozJqcA;m4o+^ks}ameOj zjb7&N6zRySr!FeR#S3DCbPvhzGh-3cj#A8rF3fS-fPCtDR0;Krpyb*c^=I2av^siH zOGFLebAO$Ke>2j#X(B=<*?J?;RBw@a(Cs<1niz4iBj0zoa{s}nqh&^2CYz%H808wn zJKt#6{rZT0N5n_K@kus1#q#cC$L~Z#5xb90V3sC#<08aJd zon2A)2?q*kw6A2f}o* zC9%j1!EDJl{#1Vl%6`iLnXA+C2(vX{Zyw_U>(Kc9!8$v$)#rI_ir-z5RvDtTqkYWz zhTCp;J*H%Oo<^^Pd`&TWFsBpy1iin#7)TdD%TL=;7JiY{Cb_j^aj{>krEjCH?U%mA z%;x*x32EwGr)6c-x*pvrFDtT=N?Gc9&@W&DVAr_0begrwzrHLD>Nhf8iJq-Ic51na z#vd!9$-MKYIn`)SjgSGjUiXNOq;tWx6ARcl1vlY`R+hKXQdc9XyV0K9R$}jXP&}#& z@LHtLGY91gIlY z%C4(bXI%H2k)w}puH;=X6@5Ij^6GPm0$e-B-X(=lXD+p}WnkK0)d)$+q2cg*M=tq) z&844uc(g&u)Vzi^5!5$L^%Z`?_AVH{p8+ugG3$Jz`d$4{zv|NA3XiX|7s!^%_?hND zMQ{g4)fD-a2r~h}M(@TTx!*=D>WXAFf$NV(8+qET>)#!`&4%OQD-Fn~Hj80NM+p-5c!Ori%#tzm=%m*PSDc=vfY35A)Q#AiM@i zg7WhCqOVE(r3^3y9^L(>i;t05)ln^B-9_Qx)yGn-u_J8=*%7*r4^aGq2%{t3e%@{u z#J(Gey97sQ2(&o8;75y!McIcFrVXs?ePhD`-6(d29$}wmOSQ1#ty~K`;y1a}SASwTirwX35gxgdVu3h8JzV?DOhQirpf}Ktl&-evE@nm1QcXvCoNkdI(%hTB?+ zaZS77Xi7 zN>T1I1eL~UFt2+ki=V`c9)=S!ynbJ>4jeD~d zhUh{pezqoX+usZIKRj-BO0d027#s0(ZuDZYJy|435GR|M>2G|SO;CUEiQmffwF!pS z%B;rT;LH-P;7JQ6uDD0|8=%7U%bNH}Y1zo`ohAco5M<0oryh6r$^xcEHgbPG>39#@ z1&r@X%N?EPBA&KP2dlVoakSWiBG(mri7(ga9_>!`C!fC6FaHp#zSt=hm0Dsp zyNup%5*(k{USjoolpWw{C6$ly(;f76VddzZ#y47}@$IBcXSpxdfZB1HUkv0w$dJ0? zV?<|qWcobpp(vLtHNKEgSL&6>M5wpt@An6WgOPoe0Icj^6ZnY`fvbQjw80vSoJ6C` zulM)s|7gq8jZF(h&F@GnD@GhtmwsZ7uHTUyFEwTn`jKQU^ zJ#q_^@rPS=Z7lG8LNR>E0|0X`)MekYc2}FLy#fETB&{^r)n(Q=ak!GLgV~po>lbRJD?z3pH-+X3PtwO9{JTp{Wp(8ismJbj4`h+kL{HeY%okwkgM($f zQIhCD7|2Hvstec}5$3PB9LLn+hR*OH2DzGN+W@1@OBYYP%rsC_ElSnV9XOKA`uzHshOrnA#F zd0*GGCpUsz9Hy9~rzix}3==jSUU7@yiiZBVU;9u5Ls!iC##pV8j*O591KFirfL8dT z-TUX)A99Z$kdHos@?zd(hVb$n<9|$FchYWG)QyZv%c*()TWF?57Rl3!hMxWy57fuM zi}hisqee*WUTtCFHoH_7v)rErnTV~&wA|w2aL=zcYRuZh1m_~e}!PIwRJ?|&kNUwn}Yx~MiTq7P%4c8ZV z=q~JfUj5K90<020?{3>qD6Ips_re+0y6Dnu}Q@=w;3!~ zoTX2ZV$GkE(?5AaCaxBmct;EBE=3`{U<+?IDvF3@j)$m_GT{6O18cFNa`)L!*maK| zA#o2`R;p+wtgE6wd)o9b5y=i0nhyU%7m&1v7}zydOO1v`5Qe%V+aFRc&!kjeNp^?j zdwcA(Mb%GC%#PMg+A?M7$fW7!l#6qS+!JSX%!DyppfiVEkL-(V1r#itZkAbShLjq+ zRNUtX=4e8UP+L@Cc)tO#fp8MJ*2&9>eD}GOyJ{DFAd4SZJ`L3;bmf(`GRhdPGrqJ$ z8q^>C=GrU||A5kR*j{$Bx7|X25l1tB0J5E6)WPgdfkB0V&7Oy~*EYEHD9q!lnf<`G zuShoWb*19w_IJ!TRL9B5A4_)q2)4dU^%cq5@08jkAdf6H-Cfyva^H%lve8_%4&6P+ zumCaX*@r@{HfiqEZnWcIqu0#rK4Nsc#A@#6K;=WNL5VLiV>76~bmbwEbX4@iL*+W) zYP@=exEsu>_dQfC>pM3d_%~iU$*yH^ojAQFD^4%>W2RMjL1WdtY33Vs{S{s^(qjT6 zaz-nR%rG^*q5kN#w*^WxIHcBZE5db~u84~rIiowYrwSZOBp4YCdpj^RUVrP6kP+c< z;uq~ebvbJ?VZex2%*A;#BYvSk`DJAMVi}TE&1cxv_XFdkXbtNF#VXO*R@fk9FGWxW zssKANDy{bQ6U%J~xzfQC(fN64MucagQ+lEkQWfKYCFx&wTtor~td)<2mvnkPho9cvkjaSey}Io&_>9XuCM;MJpr;!DhZeJ}8u zT(EVwv0#&qn#-}%!HKKj8&UtHqYyW4U0gV``!m~a&N$!K6&gVfqd(kO2E$U&vlBN-SzFSkhsamtZdZEczDqo*!cHWD?f+b(Cxi$F?VfuEok=f z4$ixAUwtW4`E)}sW3>qx~wn1ql+0SK71eDNrh5(u~bHhOcDm)}=A zh`C)WsJlO|#vnbX`sj!`7S`y9;r!sDxn7%^rO2`j+9JPDxjBWqxu%mnNM4o$Q1xi+ z^X_iWGrPp1GD0ddA0xA>bp^ujV6g2nZNT3=s)+)VMA=w9=QIpQk1Dq~{%2L=OoPsPwfq6ZmoANh|8~fNjlgf7Q=)BPM_QTMh|Z7gz5v7@HJ>z$wj+HjIjn5@GYkIhcfo8Giy z5+_q@OYOG5rX5K<=k{232|l|c%R>Dp7f5Bb>Qwc7PDuSF*z*lOc^ER`yFVB`yXG-h`4d?6NYi-lV!Rp@mLZMxUsg+6QwZz>nw`mTwxSN_bZ8 zXm|C`6y4zx#@4d$4p-50Q%M<5&ZD{}-3BHuVAjeWU=ucQz^F`FCWJF@^N;K^T;VaD z!~7gMA$j1l5UckX=(y`+cD-P#J`M z^v$OA$2gTmuhmsfD>~YDzwBN4x^ZzxTF7AO2|zgGjzQIU8fLm|t`z;;$J8}vj_D+r z<{~*v?FzaGjJVPAr9!`C_bfsO-_F33UNrrQ@kiDyIeQ$)dMTIKQPiZjm|M0$Dx05kwLTdEY+3bz%QEJ zZc3g=kvjUzLn9th(jM)xXVPsl@=)ELFRIXiE3O>PQ$+iQo6!P5xWZys?&tzW@#yDP zzFx;=On!DcZ`^}YjM&P`+|&A5Fj!ZHcU$yh*5WFAsZYx6?vB^H!$+zd5{=Q0vi{dt zi;f)Fh02`IbO(+~yl&}OYsjeFJXpaFkwd*NpAGx8xa2cgru+)Py!^dJp6_d3%N?Kq znisdJZ9_OJ^0sr0l_SUS^IZl3HpBHy(dYV9`T&vc$ zj0!G??F@1;%GYC%__^PCfwhwH;PCt2Nx$lmJ7`7u>HBy+6JC8+(-I|Op>;ut7Dwgl zRp}w#5YPn>RJ=te$6PfM=<7XW6`U=}sM!n}Vr=8=su}mT9eVqHJM`^L%aNbn*sF(} zmn9!mE)1(JYJ=6yC48@oW(rDMZ1(|#ITHT9pzV`0fcC}6*Xp;kzAQh(VT_eyNGIN9 zG~iLN8eO}84AW=Z#r=u&kwtOY=m~o;52*k3FDX3*8c;yV*Kd2-c9y`725jlofx3)J zmwvS^PPb0^Uf*18!0}??aGv$tG}f!q!~HBDO(AX*O2APCOr|wm%wsD&zw1fIu}{cn zdNu+RkpVH8OB1a(6S+QO3(E0FrNR#eZtd0lK2Q>HMIM^%tAzKdxp3q&t$Cm&;c=-9 zA)k2Qa7Ib3kUM_8rIgDXqtYj28IKLj?^}aKInhaept4^0740f*Z7IMEf!D1j8;_sP zX=`^IhTCIs>-?*?diHLd4`%fxJ6`Up5LgOmsX8a8v&zrhYn^7tL3haWGElZ^b${QOcq$1^9S{LN;GRE`M0-hJecOk z=v%&cvZ2GHl3 zkNXmb(IQ<~3o>SgovaT3BDS_ zACbB9=ydk>qZQ*<;VuD}VFJ7V;BVa~uE%41Fc)Idf7Hz+G}I!o-tO(3t$)O2U7G{h z^8q;!fgZI11C>j48wGW_W%oZHpuDZq{iT=G=RuNbo?+q1`&FdO{YO^S`Ki>iNDm94-LFgy-6*1qw}#h3!w_UO^e_(JKHhmX;nS%__EhQA+Oc#>X`R z4Cm(UDnY;4&H1XUXKhXdn6 z(?CX_nVg)IPl1491uPMD2SboNVeGdw8_qhX!hY6^EpBVeWi3v+rQiaA?BJYgjHfO| zcwwvDgZRHhUG04kW}hBct{m)Ieyen#u1i+qfxAf11S6bMJ@$CBO}Y3qs-Eq-p=-WS z#3~>$KyhX-kjS7DsH{azg*Kf>nr#VhxnVcCLGm$739dgu@U6SYrNXnZ-?Th|hMzBQ zuoP}ran#YSb(bE4EH0aa&c>q7UJ|Y*>@rz{INN?e;%ui&N;}et`d&z4QMhp41Gkw1 z+8kB*2PU(h@sOH8qZudM5@twe%t{EK>dVhD|CUMd^@r+i#3IsmJ&ivLjzrm;~Orf#e%at;RivW6QEVn8>Ma9QFpuyyF#Ls z#j)_zZ5=7#00Dh>B@*>oPg9?5K6Ec?2eBp6)QGveU<3-JZY3&1|gPTqY$|06dJ zD(YSknK0=$flFMR@Ey&>@yH_)U2)lYh)U(enOHv|ero|Zl!KS$Lv0O(UNtl0aX&u( z#U+sm^&AWjAmOqDQ*pyNR29>qSlmiadrb7CkBcBIy-)^?-gW;5x;wNUp;t_!USVMr za%}6(@vyt;<**j`Wxs_rBdpoy=xZ=Bm?f zIG7GN;Vd0Kd&!>`##{WP;<}l4*nLTN7tV#{CD|7(UXkUz1@!`HW<;%7w`-UgInGqJ z>w;4M2ldf>l_y5LK$u-hIOcjDX2v#X@`2x|=;ux~89%y{X{!|{1FjfP_5rTJhV4|j z@8ttOJC~1{6ix;-cONkD?#6)jEX=zYST8Eoir8(A=h69r)!JRnUNFYK4Ls>PU}K)9oQK1&gD zLsWOj1v5mHG%}s{gJLDrT<3_^{@l3U{z8UbEDOE83NM2)!h0K@mU4`%2RHPV6Gh&d zxS`s#d--$g(DOfz2O~eaHv2J{%6Y)a*4*X+)FY!kAgYB^BkI-wngO;HsdBnHt2YF; zlJd3q$hNspY1zm_*PiZBrmaGgYk0EY;}7+|-Ic4uU(Hu4f?Z`F!VeF)CV`jg{rmfk z``Qqbtk7p?U)&-V%dJ%b7bc`t&YfbIW(Iwmh`W=8j48F@eT-@RnPNN3?zg?bv%Qgg zbkm9x&B8B8Q1`M_Scfw=@f*z#lenkb5jki@GvtZts<>{>$5&*_PsXgaHXrCTvPc;B zmWsov299<$;r>)saLMC;Wd*e!pv1Ub^Zc6A5*_ltVcD#H)C7ARLlhS}$3>0vg_4Et z*cWHY0%m635mY~Z4a+|{-I?4i1Vq$MGbZBhzw#BzmvJ9CzOZ)gwlT~u2Tsr_jq213 z)qk(lTnhEbx#&1s$Ax0m0@PX5Z#XO*1l|2P*~VV*g^E_I=hY`@coc(?WLDtD!&&-s zt`>v+TGuBEbp_Dg%2w0u7aFW^nfET*WyK5oP2S9CaY}^?KY#ul7#QeS@q3C|ZuP=# zH1(Jxx00cLx^f6`9h}lBiUQ402TDpxh-RnYpQ=#_&adab zPaEJFMc>KI-RUrQ7Sr=Jxry-CaS&BoI7l?*-x#ql{x&RT!i|oG)v2ZL=ZClSo>ZK1 zl=J<<^<|h5&+Rzkw_!KYOgF0U#@m!E1$_I#Aqk!(=f30HI34}nu=wk(??lKVv%LeV z-)oM$Ij80LmGDT%K8Bu?JONMB zR}M!>X}qJi8~&5WT*2Y-r_9%R{*INkIL zG4$=`w98MuLM1AjXYe`>?AP6v9Z$6nySRKlYWRZ)1J0>g#Jp3hK6D44o}Xh3@-o>! z>W6O~$?<~KB5(phrvC_EiDrJ=`Rn1+#i%v}obn$`>9`(x7Uh%+cPfY&_4VtSK;{E*H*OcFXziYVvqYr9 zhR9Fe|3q%%#UM%j-Yc8~drv3^^3hr)<^n}XnN8U0zf<0wo-LGrDCQFVifU_(uZMCH zFZQ>LDtn*j(^fu$^2;xO%f?bc3y{o4vFMkus$iAyB^E**7V^|?*&H1v=BzYBn zd??h5$jlzdZ|FoKCMrY$4tTJA*o)}cQqDS^#P;H_Dk=)%kWc8-nVJ3~SV7cPaIs{s z7~V>g9r($+tQ_y}%jIKMIftAG$>$dxdmd}g>=l*ErBMX<(};+2t-6uZh(NtsJ%M>~ z;dtsLm#)q(MwyZ+F}xj$fOw`=Ue&df`h;>Jh`&GI!eNTsdi`F1S^oyEn=GA~0z*M?w||uq z;=%ktSTFR5;}{WM#Hp2!#4K5pV)n_ zcj<=7a&-b-WNoX{1)F?vEU-z+Eb4BIY)H{vyckjsw(2t)-~a}RO(Typ(jYKC}Qn%Xpd zWs;*fZDEeJ^?tMni1^Y?NCO>XU8mer-dgk@YZ8IVr-pn{mA~z~QvwFrewfHx#mfHA z-Q7m^S4W@^!+D6aN*YD`n+9Hh4`Q(iJT+c!Ct?;BycBZ$#AY?2qQ{-BHx3u_Jn{M; zv#Sv9&&HD|>KtH(hTfgtEw}QhDFs$Y=96c+d^2k4%9)$>T4f1*(>1}B#n=@%bhZ%f z{N3yjeEfV?u&l*W+f4vTusJPiz#f6igx^gA6e0{s)c?8#R>dykZQUjFvCfTmXy4G#489@5O#nwM#;htX+w{^@4xvuiQ} z?mIq`(m_s-=koWgp7eUYZV7`m=C7{qg2)F*_?s}@Ry>mwxxb&0vba6!h9cH~V$^u( ztajg<%1~|A5cs)|<$c~0bmM9lP)OQJ5Ye3Bj+OMPmYq!;&37X`>}Cut+=bX+rkS}o z#-{nfWaG4}RP5U)9m-!#`Bd6JutbVs$p{o-L(lAhAtalgr3qrH7tDA5M=yTJ;h&-&+X@%3*4SZ>@G6_mL*;>5&KeVrQ<}y=e65y5|7O0tWPE4 z>(xz;+N4*NZfF;=EkyKd_13>p_VT?tGI;+BJmIND;K?u%tlb`+`vPVnBCTi$h~P4D zTM|0j;2Zp!ZSU&Om1hbGJu{q|mRT4#9Dt?j>EH2?z6oDS#^D_tK8~d0cH{8k@O-Yu z)bu!i%{*RMQ^SU;Gk%o({#O*n2I*$9s*=~)823CFBc}V&8hpj$J*gSP7292UZ`y6&1C11G`GT-q9XJdqy zk%+R!!AOJI++UxfxBh|FoSl{U&p=m+5h3xtAs>A|Wq*GWV1YMZoYT*ji@{O{_oaNf zbUP_U@=W2s3j6Yz)ng+>`fPe2AIz<(B){H~{soX;tp-5o?{7iAsQ%k} z{_-=E3qc{a^kvcEZ!4FBgd!)uN92WdWzYX-p9aB6Gygkl-+eqB0pv3NKxW zU2`askdQjvuHk2K-c``?I3ku_@|jR9|Nb4~q@87smXObxsO`ZeBWFaLUy7>ipJFCf z#2+)0jBu4dcKf#-)x|IetULGH3wxixIQH_SPGr;$j%t709#{cgSTg9fPt7thE{4Ho z_@2<-32yMWTu7w&@FP_(>jZqMVl!F*j{^TIeii`nEPgxO$VR~wd+G<(OJkM&gFZsW z#~gAheoN;{seWX0Y2SLa&9n~4r?w*mjc#RmKDj!e-SDuDhu(Z6$NDb`k_AkVkS!PHe2B6BPnZZVUWistWfKQWa=vgWxog58A_*|P z9$FjCMkCNUYd?++mHviL_+c8w4ltW*8@J6!EXIXWJR3bANq+4qi$=1~r{)ZfYh9dg zG_00zMYkE}T2L+|S1ngv!0uYqLx%QY`yEoxNrEr>7DnFP++;ns^Ai^jwGps8a`s|+ z7T$k*$R-eB81>s)?!i}`_Y%7;qVGCoJ%9z{l}M(J7k5e@z+*eN|Y0kB{H59!@Wl<51g%5MSt{q@o0ao+j4SrPH%gRfU0tOD{jS zsv!Q+A^>Qy7l!#7r!=H$Xr9+=mEbq#CE|mr(d0~rfr*JuOdK^ap#W1%7<`VX$UT4A z#1Ir1NVHH@R^RK}TAIW+-V*PU_MHUte@qXCAOKg-9nuVZr)Ua?h2b}P)k6wwbM~Cp z-=)6GJ2DMjZ*C=0c{+_A0K&M5k}yTro}!hlz9zquZrL-6{p}GU!?5?k;Y2eNN&N+= z{(u~r2$))4#u7`g{~xWOG9X~*I#xoyLH=WyKSmYtM+4(K8GpFxGrRnk2S(_bqqn2- zLjQu}{zp~^K!CXdmxwFY=(D{0mj}Tc%zL2yNFCvRsTKYH5%LX~&G{eFro8f%s}d1Yts~ zF5pmFF6bYG{>L;ro}Sg;Cm(U7{{wpoo`L?-Sjv&$&r77-_sRZmEr36N2fshc`?DH9 z_>oS&0RtB)z;rZ4)3M=Sa4103pQI|FGQ*te|JYGzG7-@_$U||tfPY^K8Ot*vMm~ts z|6faifRsX>t6%YLhLj0W21BvH3TkU>3mc_yxa7Tsf|{CXO&r_LT^r4m3+Jz!q{6;L znwpx=Jnc169PA&fbP-!kwQK9FvssuZP^5%`hbPR)%p~hqDv#h)Vp=$#T<8nG&ABLf zuWPHf&$lh`C+;GW2{v!6Gmlv3f4OJ>A*l)&B9f}^5LDFJw-ffyDk~)!NeSTl#mIY2 zAZcN_;D@WG<;2{__{7Af67and9}WPefVBqM{}QPJDhyN0=^N+cMf}OhNd!bh2lv4g zV69onbtX1@@33m!Rg?8W%osa!RQR>!4zZ_!{|l*FD&La>ca&$(zUn$KTyyg#xlmAGT8d)WoP>H&Sjb+*0i~qjk*pj z|3M-}GON9MsQD{X3O|ao|q|^KX;> zW#eFmRaWr+p!vh#Rgpos5y<{>-3le!RS+AzxL*EzV_gi zm!r*cn~#@{*HLY(iOqL#*|wa8o}Qlh-E^NXB1agRLDom-CMSPc*KfE|`^Mi>rqtkN zgB;yJ`X*EHOI9_R`9>$2Wxpq%MZc#98VmB&IFW8jw2vK1#&P4(;u(48B5&y0-U~*n z(hLzU%dJKJ0pvfwcvFBCOBxw$^&jb#)n?;m4N9Ev`l1NULaS!Xhp55x@D-MH5bP7_|Ofm=x8#7aN5wo<9q;ksjlzC`9{oY^pc=5A?(XJnxI5qZsxC2R@EVrU#VElkEI}lc8(;WkpDALiO-^}4`f;)*>4ZFH|U43gJ1XarEJ3omPP zME!LE9i)h%c>He1Iw2N(96J)Yx|;(V??y2TI7MAI`l5nsYtgmAH9CAV$+R!}-#lDu zcp?lhCkJI9b)z2#!AeM!+K(OqDMVG5Z-07wxA0;fdB*hC;`ZN7q^J_01c<0FTVE$7 zg%~PjNQNrNFX0~1_goU^nlDg5Vctot9hzp*qNgUK@ID2@YpmX% zG^c+0M4cl($4908N>4qsk*yVo>p7~SaH@D<2SoPwqI_MAXP zC5nv%qmw%Ck^3TuREE)~dCC{Ws>`HuZp)RjJp2ThNbk_l5s8)*Gp(7bYu5iO@u%4X z))^Q)ZP2T_H$nAyvT?x%#!n~-gb8uM9w$DZpuCzJjwxBzDbnxMP{y9DjD4CBB9y9U z2;sxgzw*H3z~9;nOi$K?gG&3qfdE-N6eQhtBms4j@dZ#NPsZo~YyNOOV3foPV83Tr z{)?H{Lk~}iD3q_9NV;u3^&rwK(YlHXwDQ(#@O^W{;nznC+W8wUUOQuHH=A+t_7|hv zISw0rdItdGtTxB;L7}KN%hxgiG~JGljshm^%xH*MTLwS*hbwx`7Wj=$8G%Lf64G}D zD2X=Ed>IamuXf^PBsAThdh08j(RLqV`0d{k>Kh-4P`e-(KBYqUJd*oUf5470Sx5&~ zAs)B2QElq`ez-jmQRB$d+4nVExVzuJ=})J;0ao*B6n%W>grNwUaVTY}vZ8dVt6b(U z#4jUJ3LafKlseCbN;>z`oq^lni^$Xrm)!f>V5&kGc}TRT1RvVhi`(;IF{XXvp8K4^ zq;B;59KqXNUf^*S@UZhepWx}F`^D+{ux7GWKmq*`?xGXl<09Z;_9$%{OC6QDlY6+D z<=rrxIxH*HnZ^pk15W9cgthgK7Q#qkm{6 zbIU1|xJJS_*uYtS2PDv1HGaRsOySs=CeOUgG#6aJ(Pgbj1;q{Dce#tt zrLA`zfjN;0(b5`S1;c1R@V!l-YqJ$~0V20CfrrM~zO#2mp@4)DVPD%zrS#(d8I?^1 z+r=$snLVYmmhAcTVD4jPiD4SlW);t^^g6sbz#iSclDRcZ&O&eLnb?FKk6)J3@zLJL za7>uld0iJX{vOWqo1M%hk9;Fg8o4>>9(`%C&YB?XC2GB7e|RdCEQQ0J52E>*H?{5D z-fQXz{)6Ct6|Z8HL$-IcOeBjqD^e$&pCYWYOWs$8L>YE>1H>TzYxHLdA<~KtU(v7= z(^)j)%`x^xsA@`U?qM0_8e%fnYGU!gykG;6&Garhd$;itZg}-IZUPo0sk$mW2a1m4 z_VOfKRMAl4%xYelEa2qdfDJpgmWS(w-PuaY+v}qP$($<3dbknu37A)=B`C_7G_O4Z zzVxuGeN=sG`k|IhUb7mH-o`}x7DKU)>B|AHsBYu{t8^w5l&;ir1f4pSio%d}49rMi zUH^-hG){Ntyc)%68>Mpjj{>sArR%UpqwI6~jJdNw^k>qq$*Dh@V_ib8UEm8oMc|UwrkUE=aIQJM$Nsv_I&?`-d+#9nt2?)ES=u-bndK# z2)t&WZb*TLb|@ln)#eOgj((dYNqoa<9pC7dLMkEmQwX&=LGP$*OjWNqJTG@3xj^$N zEnpjV?MJ%oS&T5ZQ{;-`Cn}GvX59u8eZ;)BDtN{OE`Dznt9#yM>enZaw!(QO%#uhh z^6RU`g!rmVOi*LbRk=Hi{CuP{nT-yyzbhqMS1@_Irbiec9;w^v z$q6XYG{Q5+Hle2n#b{21H&Ku=pMLo+hP#{OIWu!Z!yo;T4vkf{N8@c@nO-q~;qy15Y`RY-*v}Zs)uhMbbA52m5Gf@=Wxx3%rVr}hE z(&#S z%tvQOH_lg(ci!UuNUv%~EsHfjyD-u(#szVW^R_B*=aTfo7xte$RGZCy8aJrnGVGaO zHccp*R%*`SdEsV4xp$T0Dk&;Grx{wFJ|CkRlL5{<@GNq#VU3!0k1qduFgs@fZx1*a z%dwbhqI7rCC08rD7CZ{HA0IZHG#VAPR`Rr;&>XdI+`u1Z^S(GHLDnu`sZtG(r)u9A zyrj72%4!_#qn=EjrhoP%FVg8OKrgh{Ah_ft#K6lDirt}3UQQMnnjxMZFl z6}a{Wh&f&HhH1@WOXz(EUbu zi3W-8Z%*{1r@wXX5^9U`JJo%1`nFEAjk#mExoy0WEZ~kslouVxv(hf#`Pn>mck44# z<#;dCOgo?HYhhzY2M$p3ks!G<$P*4mgVTeBQ~^(j3)#U}y7 zyT0}0>6H|HiAhOD%Pk(kKBkIwRgUecXfKOY!JbWW$(C7>aC|E`irZB8+WiS=rES^x zQt8OjcLmTFH#55VWCxVIc7`SSOvdo-PmgyE;D3VH?B$7wnrcIrWJB)YKs+!4oTwo(xe-7hCT@3jt+?dGK zZVqKC@Li81FM(Ci(3g5S?+9-Sn zbAXhMq2_#pE^I-lH_3vh8{89))*DVwC3$GlhN&}Za{v!dIrvA2Mh6+Z?CQ}E2@!N9`yuAZOOZ&Znc`pZE1J^_t(K9MWo)9>kL;&8^WVnqF( z;K4Z-fUhR{3t4)e9Dd91%obI>e7(m%;JIxW^uQOG;>JzjeERAY50MaoO;{Z}z2c#_ z>u-Q_)Z`*%F8TU8G<2IBG2i1gN#U1EoiF_PPz-*?6p4rGtRf*RA!o!tSY2-aA7gJB z)n?c2{kF6eC~Yb34#mB=7x&^0h2UD;-K7L~*Fqq;ySo*4x8M?7PVVP^p1sez&;9Ok zzGRGKT*)PwYfV}6_g`othz=Z)ouLmzz1fM)ET<_+mExIvECm&T!VRbL&{!%ENkUqb zSb2L0CaxNtFC+G^p5Katp=?OOnrmZS(~XdvCpB{Bt(X(ZlsneMdB9F^olR7%m;D%F z!1*{|zzNHjH%A~%kY3lc%T#1p=gnwG#r@g5Bj<2Ydg*D#Ly3C%$v#nGa+yx0tjs9khS2Y^xg_DOQed$!u%fWL(PZsBWAW;_Px>v2s56m9N$cCHs2m)@WVVDP4p7 zxS5zL5ezk1AZqz)kcxWad`8jBH|hBK_br%iH9bHKe?}t_W6k=rI1tzGQzAaf0xnJR z%Pw4gv-mcvRtV))Z&^K19DAnlM?adZr$wVoIbESb&-+1hb{sY$!gpMdn%*8<<%wP+ zyb@O{o|Io5(>^_b$x9~EQA2=iy+MO**N-H?VsD50>cl1}v@%n4VQA=Z!Sj;>oa&c} zwpQER()Q3wR^cfH!-PF;rjI7$nIG?_ovQk#&Wt@5CS_GgK7+;n(AJ!PXSeM3)Un&@ zwlOSK;lG+Plx;fU@oZh&__Duma9j=enUID<*Q?EP+&3KU*((P-DxT=x`Agq&GY&_X zti8%&I~J!dOP_9JLREnF*+@@}>jwT!oT}58;50Da0b`$Zv-L3ZL5XR0=9iny>188l z&9xTa7#9yTK*1d;y|**kmo`(>h}Ih&g#yZfTY+u?XKMHKmBP%U-#Z3C!hST)jb)Bq z^`-QFOO3!wxH`Tynt@!m$i*VlAA>V2$rGdmrd%LZi`$daPk`cLI){MlNWRCThFfIe zBDNk8P41R?tUh-z&#rsThi*)3`m97!F8c|$4xTxkC0qS8OV<^=49(~K(lO!9ZjWE% z**l*^=xhI7fBR1SR$ytHv1Oo|_l5HTi4)a!Prdr=_6S%xx7B_@Uz+~#_W7y!xwU@u zi_=M~>tX;7U4bTk(hrF4Wwa`>9lhl%=fjgEgP*x&c~|3BOj1?OY0vefl>MjdfM4VObu(?kWFH-fye3Hd@Z4CgU8RQ-jV<{IP2n{zQ{*Dy zoAT6Og;jQO_8NHTUrB#wvspp*`V|K9D*T4)$_t)K8a*fJlio7SXG{wUn^JE$!uP26 zU9_#{3$0YLA)u;nIw6+ey&O6RKrr>|w#lZjk2+-P<)PGl(#NHvbZ67LQ_(g}KZaIX zBnf>odo|3J(;MHhounF9oVl;3Y?)3rVo`S?&`ZZolYZ=N$1(1or*qoCrHs2m?u zOFYt3<1$-PCE|KpcXw;Hp|P*b@1UT*%1@a0j)GLW*3D-KXGC$eI%@hrTGq#rK2{}r zh+rp(*LwLYPVBA%U5utHWfNYMX9)9N(?dd}rOcat!LZ69bapkVI_)`zJ_g_@=X)$c zM`U-VJ4CNk9(NaT4URum(TXq8F+kDLjBZ!95k8_`>YTN7B-vMSPbUoC_RGfi#MD!x zCC?D*=JEpqzsIxPP$d9ETJ!v>zC)zfKFf!Lm4$(|)FwC-{;yMKaI37A0<7ikXh`gN zLA=N1leLENTvr3~W?rd~-6c-?tb_)jq|uE zD8}PXa)-`Rn%i8m(u2MaMM~}K8!AjwFx$c^vR&|j-99@7k!2#1E_;0>TqNJp(dL1G z;CXy2BR7&=4&{9H9o>khL*wWrI{?+BT)InCL2s@kt)i#10eUYp$-;rL;PEH^W{)8M z;E7G6v^}oP2H) zKFMf)>-s@aAqulNx$@gkK9u)fRq1DKl$Yf`zc>f*j41rXaY_}T2VS6S_T#?Hi8H*l%xlQPK`gd*u0nwsfx!rcO$ z)xJGxK8=pcJFTAqN$DZX5j7<+v^sZv1HP^E{`wIh4(v?Er@M`8MnV@{gH)D{EnjsK zNHq9)ta_r%>E(+`Vs5cZBQ?IUbw?|YJhcG1|7_!7`QCn#_;ou6zCk3cXjC=r=Zwj8 zzzauMo%GubF9i1*#dGxpPFv4SA=wnZiOGQ3ua}(k!E*MhuMxkD_r@RIlj!w=KLRbH zz;F5t4?yTg)}IWXO*41dK0B;6B6y)~{j$r|a_S{i5Im>=lszeeZ?7{ZYi}s`0jFik za}*R5&SG=dkoX#AWPN-%Fs+px1DJ4PCN#@({^xnE>rN%QoUAK*lacz^*MPNEy6V2@5QsigNE8dNjxQ0k z%cZr)N>o}OJWir)W+i2W%zycXTF4lP_Mj6K(w|-)5pxkB`E%h`7KyViKGY*CBeV_D zLd{B#W>*%+d_QT*+>lUKbGt+-c~jamzx1$|o8N$AC-p?|ZF7%iN%y0w|DJvG`uxs? zUg!r!&fmJ0zss!XU4BCRA2LBaMfrzChL1ba)5_;OyvR;OKv09+{ zd;GAHiVGEsrLnw8E5#ul2y`oSRiq*!fOWTcAqz2WAia&&(4h>kDRq*Hwlq!_Yt z_aQUoD^UPKNpch6c<&i(e~W9;aJ140LUv>0@%!;(xSu%hpvRj^yQlc(G+9e>Ds?yZ zi>n25Bq0Yh5p%q6Z6pfK3x@TJer!(Y(T>?rbddoja>kkY&Ics>+hksT2J!IlQ7j0? z#YeA7Ul%V561s12Ts{wef9MCFdYBz^)2W9w;a=y4wk6+hyE-aFpMrP_wVXObrIZs; zs`+U)T!BYJ{#IsLNfpoNEbiGn@A8ZoInutYvd^!QU@!Spdv$K{ItnN0wNB3J{b6K5 zB2?j9VkDfdRe&!Rj~ac;#s=l*(hfRmP#mYmK5%}ZW$t9EVrtw*dpx%FVY3N$yNE9< zU1s_sOm2}NWNuE=_H?cNxF`6+B2dNX=9gMSZ3&Hs!W{3snrD!n#5Mo`fUTK`E)2#| z;b#e7O`K@A*X$E7}z8Fy()i3^3l;g0Cw6{gAf@P2)q#wW{Q6JEEiFdV^tDCdRQ0}WB2UZC)}J56r9hS9u#PitE$LcSn91PX<}QeG8Z&+SqBa`eWlc&N@p6VBILn&!$Ks`2`gOHLHoC z(xf<;il}7o9|D3W$iPt06S zfHG-KeRyX!i&n+pH%MIxtz=>6p(Ql%p7g_sZzsQX+_3J>eX{#KCtbS3aq*bK40qO} zRujdJ)NgL5#x}h4cvp@th*+^+a^X$%hMPsBR^;K28+T_MrN|mp%OhxFX>o8I+mUC$peR}#lUub}p1)ju*KWQcQZ$0ty@PPI|n zXROl>*5k=^<`1yo0KnMFEUV9B#3-T_1mg#EIKL0aj->?E%J*qJoCl&G#+ZaXfjj{$ z_wM5lrrV=l$Ap*w-PDaY$43pZwWZTDpUxXjlQ*K$K8%^z;qYs^8K4jccZ%FEL~RW) zCVxHPh-|gvBO*A#DEP(E+o;hlK3q%N@A)AW>=iyE_wlsYBx)4ZN5+}AFs-gehs~X{ zhe?_aT^ClPi;$WK)grI3S>YMU;KfEOQT~^Cr!Usm_r|kFRJjX4k8wfAKOc1G;GJq^ zWo5s<)#T4~9SpB8^`r=cHJWOg3PT2!>QeB&_>H|JN2!Bl{39yNQY>5>DA8IPTd0Yf zudcDDqFe4%0ieb)UTV4!0-_r2Icu?Jxu^#yBoN&Ap6-X-r-Tgl_8ni+Of8We@QniuB8GSy)Pi_$g2oCr!5REd9oqdY>}L&lK|}!$LXGlx1=<4c z?>N1TK=aUCQXH-yuiPEgiE2loGcZ-@M{>3XTr`Y!eQ)*MZNmDnA-^lLrnEB1rv6@v z0&|da1ubXWaeq5+1c>IG-|h0AU82TfY_TghTJ`!aPrI^hGq#E zW${o*6#I@d=Gai1XmEI<1h}2{qHN&myGD<_S+Z-n5AbMD%(O}iKHizX@IZR^wYt{U z%Oo&0t{GTv<0IZM@@Zas`(soX$Y$W*RfsY)<~6VbzGPMt!MIbpN3YKORCi;dMe%CX zDm2zlvg)M`^RcOOQn$}v!fr{zAb35`NmC@4djkW&VSLm*U;{SH%zGoKFNMd2INzY7 zSxls?{yyEB2(lwdS8bI@^+`B3{h6oeFj=uvagXru%B5&?7R760dTf$tG_{N0K5^Bq zWD&_!wN>rNM6%L7a#?TD;(O4h*~r4?Lb72XiErp6Bh9<+Sccs6_(|&Jj>1@rM$JdhU2AN5U+(+@xx0~`-EgN>FYO5Nz zeu)~bGdo0+?%`+)DF>*20O+Ef@xp=B%IvG9E*P8k$?82#rV0Gqv5mxxpo!EI?s-!c zLtWi@za*|G35056n`lEhIQh)b#jSlt;oWtEP$xiDr5Y%#b0v-|1quwWEML!xSkB!` z->~!PmNgRLsm0D{_6F-t*x>3VLqE*gIH;{&9J3BcDD8m?fAk%{QMJ;1k?*~4Y2C** z!ggl$Bz;;kEOJsqQp^{-ldMXV%4Cd#hR1>(qzuV*ELy+~1o&-CJ*=aHW*Wgo0;A$v zx8emsN%gmsy%~*S&0~_82%D?(Kgq~2p3%72 zzWP)9eEE{{mq2>Y@e9xV=bl)T6;*z%t%QXK$)9hK#*wIr7ZQ`jAeCs`|~2IgxaPXkcfZL zwK$2Rq{?0wD1(NG0hg(_USK`PbYC)lTWJ{4pCw>zq)Xqsr7F{3b_ISJk&+m;%3&`z?osQQCQ4$VAR>BOk*5t~QPPZtzO zXRpkDopAGsZcflHb#29Dr=zcwO|vW5;QIKvbI%`&e0ThcoWjc*b3MgV`sm0~HxF+Z zw!~W|W6I~I*){l41yqKgx3!>n+vVDFh~vHLrtxc6O086tTt3$UR901Xd8O3Exu+fC zP_7QnTx)XLKEV0mB1(PahGW{Y|M*T4#aMV_zg+*;*wLJ*yVN^)^V&mey#uh2Y|eu- zF4#_^hkMjgO1qo@64g#)7-!%Q*JcbAVLRX?Lo0s<(FC`rTIzhq6Dbxnmcs`GK-7_& z7K$+Ggl9QAMt}}>rdeDy%(N2gel(TyyvNK~3B1R&yli+V3%we}iE#{i4f0sOWDmpk zXn5zg@mtUTHZ)%!)UzGj@J)ZX_|TBja7$bxcZ|D7)UD`cwG8@&)2##SfWZ&ltg%*h%FlEz~SH;F$gOZ(OdlepNP1aX4YOkL8QU3u{DEwdD--)7pE3vDhFM4 zdHCI2JPmcd(9JNKVpU$I)sh(pj?hCl+(lYpwMj+2ZeHf2-A@{=N_EpYxtaI&D5eG& zcYDNP$fYe_)->3V(QAsD$LM{jRLRuEJqB?#A*czUc8TJ}RB||)=N8*o7 zbBswWluX~_U;$?cXGkn|8Sth>+o}ravO@v@RlbmJ|Df;(smM8@$q4V>P@7)?zO;M^Dx@K)v zlYRgEq^OCtkGtQ_ah|Epjh>K$mzpnpwAa3p*y|Z1BEIF0uS7EUxI_iPtQQZPH1Sva2bxXsM9QDOeiW0AE?YIXKi054W)~iPy~fC1 z<)dBJ#jL}%thE!r^hrs*Q2*Hz?#=ygHkSmvtc4FA#1?@GYlPiE$U%LSDSKBIQ>Z^b zt#659}!XAZuWJ}Ts+jR6hHE!J|p06G(tT||t+ecXO~Yfj#4{^9S>9v8{@R{LiKYBVuS z1m_SrZMlL!6g0YUH?z2>8xXy`-DRlOKU)|b<0HGQbbAqZvWOb-z$1kU;eIOI+bncy z(|KOv-Tb@tJ{t>(>uK-W=YjkJEFJiym+LU%|3S8KPYk99Fi+{SSs=K;_i9Jb%|L_B zQIYBD&mieQqA|IX^}F}}fXT&cq)0?E=` z@8+_qKIx&m+wvN}wZh8wfYsu_=ByhReA+cow2IrNtkoIZ#4%}THD#iD731^)5V5!1 zD{>os1=C~flXkK@R@ zveK5equmB4nQWKS)jnSyN59ZYo^l%o?z>4^G(a!D+8<=5mRCNg#;uP%S$v549?`cI zZ4{_KY}@WkwnSKFu?=6V6*c9&Czy(qxEbcb*A7Ws1sd~aYy!bbH6HLbsgKM=-uvDo zI!VRVmX2>H{00S^81_RV>L+~@4E%DDo3b2Q`!p^Geu*b ziwA(0i>shrTR*)k+ELM^Iiok3%_Ru6uA}#?ihjg{zc(gf8Dv2;Div_0X-R9sSKHz0 zPk=hOpS1oRj?nAjGMt_fLi3Z ze}?Gw?uh2Z>a~)9-o}1*ZYu$nnqruZ)OSlL`uCFd)<||{d%?8tOmSC-v0}_Fn#|(6rQ<+tN>cDaOh*b%_F__ewm=6Qw zK%C*G;GT0xu+VH`tp=z?9mbIyh70O@mbD0s!bO3s`Je5}$hT7PnYtgDI5xhwy(iDs zyG=-GLPM7T@m7gLA}txEe@>STCj34LAT-=tH0@u1cB6}Nqh1UB=wWvAWu(#JLp-o3 zrf+p(Z<|k9&Hyj5y%i^oweH8TypxZ%ThFH&ASnkQtp02i_K`MF+L`AMQFqNOHDRQbBGp%4R36OCze7x)h^>lQ7yPa)O(J27XpK1bnp68qtoFrfR8!nx9*%n58+f;91mJ6;H#5BN z(qBC2^pHiy1wYzj`0#tMVu7DA-GU&{??K%27ws>bYnMJ1NucCxehNbqf_Ej@t&2+U zGPAC@l)M)L{NbSU4&EGp)W*7MfX7wF)x!IS8wI@AeXpx3dZnFM)J8$-1()I7BnU;0 zBgtH4dR)Cwyg~|bk0Fgfk1UPAE3ZasYDOWoKKB;KJ(YaO+Fc;({$ZzxGUrW$Rhiz2 zagU^ZqBCyl(TVvn{q=C|*JjlOHvthhcq+Q`AKFTKQ}{EDt&{~!p6}VPN|JsSQzeE6 zT{6)m^SDKce6Z$yWCaq{L_e{u)cJ&~4n!<_9VFijsFY4V6wUl_EFXKGwEk4y!LLBi zeBFMPm5~yxS@NRN{AA5^YTDDoz>}juP|f^wM>!v-oZYr&K~(bWPxZx6G59k0WwIL* zBbcF5XVZAUMJYKfsjfG5;^_$066Amic{gBGI>8zl^m;XHcf7eMQ$^wQkW{|(LHdrD z9)Q#!TRHP3i1C380j#*~Izd;b=d6(N(S1K6rQs!FC_RjERTP4!X zFlBNwz5k0rR0v~pR69CC9P-|cM(mF+E}Mo%}WTw-F}Y14r=HADm9Mq z(3^E3Fjfb@<}lyCTEG38zI-q za6+K+>xP`B)4jpFG071>K-g=O|B4t#Gf8##uCy@5weo`JX%F>ZSEI7M>Ov@)+?wLGT!%V~+T2{Ol~)K;g?^)DHN;jkCF$r-fz0_q zQPymhAHjkG;#Y}p4(co%i)av%jVh0`Nsw|nus?;tHb=A-7x`?+Nh?r=MW3m%9CRb* zDhKY?DiLpXO$n~Y4;>eDhtFe#SQS&Hjj}*a4m9rX6Do!)A@G0<1JD9NrJ^2!()ew1 z(+7nP!f|<_JuF(AGWj=~zi7{~*ZknwPK1eGlmQAk zr=cMQcb;OHSq`H{%bXCP8RkZgO*Ob-Ba@0{=qzexCkDrH*m0SAlMI*{ZGhxuw?xjS zawIiw$K}N2U28S{mX;)dL6bYssWUork&cxp>E?=ztEmQ4o{jmu+{~G!Ry@93GeLAz7&}#@9Ul<3mB@bI0L$*3hi;Q1z9aW2*`3@V+rjBsyOq zmtXaIk8kI0xmju4l%z_8>1yUt!K#bs0sV!wwhq?2wV7;0h0^aiLw^6JpO(cjxgYQv zDS*Z9kJ<0vN;WiYOFv}YY~DBRi+rC!w49z62;O_zLSqpMT1mcN_QE{zsXR=flE7Q7 zWNjc|0Ut2^+M8|TbOJN{ zCN7;}sl2+59sKh}Qv3cWkG7hVfNGg-#=u}*{k7@J*uVgDmFKTDOKW24B{7&T&fqxP z$S*U3U%PUL8%J_MGF*<-JCRLw{pM1Az-*_(#-GHGkU%_t#pkAA(PhNM^=YUtqd|xGz<(*n&U92VYW=$ZV%{F^J(yy7R_}#t7z+*u`X^TOJD_P zL{1@$$!p;B_l%{S+Htw(6*iW^i?2{ARob||{$mTEm&6yQ`+NB9{JFo#Ky^P8img4~ zrXkrcp8Fu(*@7CHfzdui%qpRwRMB42FGKpqpDXL0V|OXArtztuh+fVoicsoSRiwwG zEYla;K+-qK3mi-%kxh>xaJ7;hYgagpCwlcZgr!W-_wig+yId7*p_RM3me*h?#h=u} z%%l5sZU>UF-*Ty6Sq!h#yoZZY$-|>l6B2eDEI}cqfmAr$_W9(peptrPDgjZ=EUNBs zZxIqc+V|%W<#HOn_oLb~O;+w>{GJ4-yBzhTU2M!!Be z!%2$8!U?nU+A36XK>Y8#mK)D9eNCT_wK@(Zb9X^vWQ?--VD+; zEwWvg893dz7^!^NR;DWse`q(ZD~W}V&H(esP0 zL3~)WEH~Jn$kF2mlwD4emAdw=dR~q)GCfw!mK_{xp&Ru!tM(`#ADFW*L%1z}ky~N` zYHv$=HCm_dX4@KJFxW%~5)MWQRV7HM zvrQ%cQOCF9jec%b@YA;Ro zzbLi0Z~b8RPPy&dulP1V6v zINtjeGVqoZ7nUgC7^1lw9F^rw&SD*GstEr`HKlO>Kp049d6TW0R#^Brq`m~j3(V&~ z^i#7-P&a{raDK|Mf0cA{x-raN#rCT-|AifuMJ;TST7FVpFGgV)l1_13QP$m!fno3} za96ulzdaH!$^ILSBmKPQ!)Kz5@{{0$H4~m+*bL$xPRay!y&U9lKjdH1BtIx8nq6$k zWkMJ~v#9N99@;nWBHkvDfVKwII9l&N8;#4^43yZ>H& z#!~z8`ejEW-pKC$n+E(J5VFuK7@>T)B_I3qeH@j-b!FX)dYo&kEXC*FZ&|65-jy8G zr2U(3!u#-g2h<_@pFiNc7~C|V1hLdlP0+YImviE2&>VK{|9p~HNVhC7+|;|p!R&7; z{2vb#>V^Sobq2=@W5NF?QuY64%{qX8!L3^vB2)kPeE$9r59=?u)zZhF<8NdC$5(Gz zn1BfJDM9MrT|oaasQ=^Gi3%8hYOV1QSN)H&DSv~7X8;)a_T;)Z@%0}W!@uY9U@?*! z1G$juVrw`Nle6ez>%P}>K5mU^gITMZM~VF({%>FH$N?K08AT%?-3n!cP@FV&RH%MD z`6z)!wJ#-Zlk1IJOG`&$s1A35@kxn^oAZ@``FdO8Ps9SACFHx0{~n6jt4IU3_8J;E zFo@niI{GuLv6hsJYkr5^jYq%yus~J__Tr`#Ybuv{QR?*H$SI8ZmG>n@e)K|_6!^bg z9&8M~6Y1C>U4j9H@7QSM^RE$0Hw~0Le!i(OJ=d!(ys%&L%N;f{f0p!8AgWaAKfwi#j^Ow!ANG1@vmGl@BYmXhG{VitGPF zxEkwH75D#_9SXtuiT{8?W*EOriOj+yaQ-i5A(?%R$i-)5X^VI*`)L51A0k0uS7%!T5;X(cXLs8#X@xA-sPLmz=mx2fR1i}9@ zIDFrJ3xfesVI4UlA<=1R5uu@oJ^lR;apu7c{ZWM7&rc7i7#Q0XWi2fP){8a5dE&na z-2O>GwNSReX^^&+wT6L2%orK zyf88V0mbm)`k0!Q)_$AAW*Nsc%Znp7HZCv6U?iJ^hEhOb>8>TWc*_QkXT_K)9Ekon5rR6V21}!|8mpOL>|U z3kwT|(aLXF9Qn^rxI>y`9e$y!>zl|~e3&W)4iUHg+sy?txmcImGXoKfR3o12@+y87C573)+H zSO0!^e4MjK6V-fFYN+RWbJLJqyT?L`?30I~0Y-@++11HvD?V%^wKkCt>}<18J_a#S z1{xYW7z9*Q#m9gV@l$t(!a=Xuxr{VD;`=IWn3XsyntPr5W5#G4q1ROj{>pnZw z;Z)UIJ&zlsAVGnFTzssx$)<#h^e0kY=d>R`I$2DTaoNmQbbdA+wH6z|v{RxwUZBm) z=LxGQ5mU&Z($h9O%=?cPK)iOnjT5X(JJEGB{3o4Z33u2}>K(F+1K|AcxLR4rSIgOv z-U!temolk~8eP`HYXXky&w6Cc(v5Dis2-fQt4I5PMl@KBpBL3GmF`(@PWQ9%=*Ylo zR0q!Pni&EuwdN~L?0>BUUmZ*#AR!^GmQ?){7X0_0w~WZ8Dpj8woI=|58;eSe3zJFh z91?$ZSl*rst7=Duoi0@Ola`1}NaRTXiNrNSJ`oaRCU26`>SfsFh2B9HL0M-Y=%CcgrA?VOH@fLvp#bd@bxS}&_sB(MNhkMlDDpIpi2KACIgtu zFl%`Gs281pO&!Ket5-%QpJ~M!VMaFA*Vl))SrVGu4Qf~HY@_yphRtHS zN|({h;;ws`Jvt-qEt((=N2jJj29gBCZn1qVmxvHlNWdn&7c^ro;6C$bT53rOh5(p*EOJynlewX~k{Wn}3b%9ag&OS?i&MG#{S{ApVImnuxC99CH`#Ky zD@|8cXjg2H0IDV^*3nbToSeSY5PYSHEj1r8VIdz&<$!Un;_>v}V?lkE;-NQ{DP1%= z!P7FO2D|(Rl5kGk73tRCISJ?6lGOax&_Q=bG>CAQT4;!qH4(OIZ5;H!V%h&OZ$P4a zVR6?5wU3%wVt1|~)W=jF;Z^`)wa{y9SXN&p9C90-3!3tWmIvA|-3uM9ON z%MBZ#$~Cv9tTrpQ{>&mr#V~zf?W4tEySn^?;!%`f7I=ir>yQkuz>%ikLFuquWgM|_ z3_470+~-3z6wAJf7cDK55?14j9Opgd15l%8&Vh9;UEv}+XoyjHjX&+BJ47i;?4GT- ztl@s>xd!VtyR%MFDu`NcP}C9gyH9_%p!^zq7T4xTjhrMdU^Bon4N_+kp-4>o_@^DK zs#ipv&)4`98RC@XtiT0VRAttRT{ogl4?fky7IP|8hEOZL!xLrY_3kyCXj zq_`!QFN~1ZdbA6~cWt{`SC_!busYO)XkCS2P!672FwL?K4beJ^JMYb#g3MUf%J5mB z5b>GKm$h;^5iTGs=Bex*6i|(^-lSd|av%?}7P^9m?8q-M6n>zx(n%WvnFdE>ArT#x z&--3SGWwV^F#|A7biq+mio3$ql=h5IE#2E_5?q zX==`q-I(g(uQ1dvSo~kNH9cZj`gmF2RxyY@Z_-)Xq*tTHqSTkrR!Ua3KtzMysf_GS zwkehQ=xffT>hQFvgYA6rjp@8Ao&v7AqLe<&>|jtWrTJR6_L|g7|7R!s>=E7?R^2AQ zg}h-BVpXis7<)`96+zqk#u-BG>j+PybV6QdoCjGT4T}{WdMb#QaVbV98=ZPU-L7?b zn%-Xo6@3S9ig#j9{Nb-rlTC^ieVL{p_%z*c?%9i}zAlStQ^FC;=U4Ni(_fkp^=jUp z(PPDF4wrM?Nl!#`h<)_owB0sc;Tq-v_&u&m9WAP|1Rjpq9`6s!aRfYF%Z`hrKN`T7 zzilDhv*)Lple-YzXxz&@oG}+eA$#!Z4*qz%_VR4nBBZ@Htdwql4?PUo-Zttc?bG>k zh!$*pvfLD#p=oUtcOjr4WrnEx zKVv%m1TLz3X+cdxRxC+rL0v<9Do_pfN~@WY1iLOe{m)@L5Sdu+A*te;7+}kU%zg0y z+ia46Wl7Zh7K0nwWa~`%Z`tbDGsFvEBV%lOk7V*E!qYm&zHOXm5t5sAJu8(B&NhW5 z|Hp6IBL~raid?+KMfaWUuaFqL9-i;VBQ4fqV`Je)TCC~ScG86;w*-HjJT`yMd-h@Z zJDs~_dVSvTu$yKZ$*fFvG_4j}w5X)4>~*4Na~3hbJ}xyDAT|OEOMs-zcVt?Fp4$Wt zD@{((*c8K4nr(lnev@-N*dIMC8+=rWKTR3YZ%b?9+sx^g z*o8~Alc-QHlMU4#eTG*uDe}8ccPy9C5b^r*lRtdmI#5*`g?C8>Z$g}#;2Z}6k~&F$ zv$tKk8z1+{VvYIM6rr^PFBsvIA9@h??JYFvd@TGI(XZ9p6^oW9{p`K$_KjJePZCyu zQ>t1bUh|F=)L$Zz3t~Mb*tA+U`|RuH4i>Qdril7As#=dnDXU+1*7*Q;6BpI=wA@wr zu7$I2^iR_SZmfNWr||pBBu}^cZrJ=wU{LN^DWj2GuI_0L06VZg4AK9&1FainT4tAd z@Q&?h&3OJIW%6u;(Xw_+*7c38$|61UFe#Jy9hyNI#>Sq{b~^<#Fy)i4Z`~UO5)X$L zs!j0?<6U(QjrhlmJW?smDXazJ zYu33B;FCW?rA<%MCcIBioR;J>gbI#?cf?=X-;hg0mD+ID&WBjG0wN+qgE0jReIBoU^~=VOOdPG|583)yuFhw~-lMtSG{$>78X_iTQl6 z`0y{V_l@Mme`Tom3StJ~Mf3hblkSScu5(rH@9o89x?;^TQ?WBsLwN-k6!dVuy+%bc zbAoy}y8Vl8wNp_2B{Ic!8K@?Q=K*q;PE5d(UWWVfSA=Lb|CY$>O0gSXf{%MAxU2}f zjKd0UCT#^er*F$=sMR|AJTvrIqi3!4WscKj*)GKHiE>VRM$V6fOV!2Zc@~_zrIX2# z0aJLg(`A^ODsQ`|eZI_k;Ud~dYQbeQ;p)+F>v;h;pV&9{C7!+Uxu43aa6LC9Pxl*n zDyv^*T~#21(n*umg{xbL&HW&|f>>^c-~Xo92WOnLT*?DqPFE5Gke#7uEu9r)6!Gj{V-ligF3w2kiLFtg-tQ#G0@VLh84oktEH}Id zp5Irra`cz(bN(*$X0w>O7J@YE!E1h$)|rQuM=h*|^0@6o6xy#OMHTF5uqV}4HEiW# znV1S=DRL9jYusgaeLg8EoRC18h3v_40OjE%bd_fLK6mG6r{dKOv`mJ7q(n8mlEmbV zM1A9$eOVFQzUt~#7|Z`zJ8gfl2}EGtL+EO1e-WAaaQMwCvER2RPy4zEYY%!`74OMS zQ?W?KiM7pD29Y@&@p9m=K=gbX12Gy}J?JHECE^E@=g1NGD+Z^pv7HY#J5)GAnfiL9 zk(JMneAG7=cwf*o&7@k6}sBN0WQ8 zzF8i9pQl=O(9n{7OK4nt5x&ZWE}FuK1d&_MzIv3pt&|T+0aLZQms8uEedHi|du&bc zcl`b!0-(JPpthin=vD-Ms)(5fb_roHd#h;Jykgw!#tZeHQ8U(2Iu`-_VV`KwCcK#Fjtv zv2URAc$kIkdjE-b&A?oF(i?QdDKcJ0>wJ69oA+QNDbxPhXjEuNKGAbKd!?YoWG5@i zQy4ZBtcH?AVm-OHLk807a~|1Z?=Jw1UTN*VXo54#YAx71#K{z>Mg_8O)sftptesdr z_95u33~0jyMvNEZa?frXe8fSz-fmpJw%SO?34dq&(d0*&*K zR0v|0A?P{8s19m0w}YTg#rsr9o_CU86SwLHVE9&bC|1Bdhe=b;6GUv6Gc4wt|a{g!X?IJF+`J zM{`AOdVR?a=b}oF#0JQT#8COcwlFyOj8ovljg5{kHgP`ZK*Wub)L+-@jY{4t^F2$% zLfn3o#6Ka_Hc8LDnEa$PeaY)$kg5-+cnr?058V?9{$O`SIrn-qhkDQN0ukCz>~n-B zqP#c=U+wxd=oA|1blQ5uv+ByUqwfVxIFGUXP+gxFKO>5UMYcKUxr6EwCP*taRZIp>KnYNWAekP2CXb?pHJ%j?Z|x{eE@z$WU5*R(!`w|M z+YC9x=jCCI#d4Ou+gu`PSjh?#$PT)toU?^x^c)H zlTW*XkbgOorAuaVA&0FPwzErlsvb?N6hKGWiej1t#h%PYheF zmt(x2Ohs1ei(V8jUK9;mkS&okS-tKZ`(M-#T?X#)Df&~3);{p-sUDp{UBquzJ|}ro z4Ok3R<&AUi5df5XzCVe8hoOJcZJ$GOhs$KR7ovgegMvhMlblp{{duhpl={mvwZlzd zs@$?WaO!r%ialI*KPsx)+OO$j&q~!fXi>rAk5Gi4Vp1BRXBxy($wTvt0^H`&K=~^D z{N=Qc^27To3}H3Hw}&hvdQ#+OARi5jCP z@(l%vlJqkPDJjwmw*y;RV_NH=93|3P(wd2>si}$S*x1P`zsGJGfBa8X>WiR5%&hR4 z->OTq7&?_L-GJYOd-8;FQ4b1K6sSaRafu8KD@{geTJ%09^lae8S&5x2h&_-+g?SRi zlTN=+5P>K~sEtxrv=nuFT1dFNzb9O6PrH^N%E7R6Oj0@T75M$0-E!6c8{I>(5jR*B zHzca}yEGn#23Vz8k&C^UxKF^uK{U#R6)sZ9T=dm9xDks_3AlRMS~X^hWZv4o^c~0` zP2Bfg#;`cRndza|ubFKd0pjNf;Y=qtCSEQqR&)%{?>Sv}S@W9v9I$T_fBNL?8A;hEY0WjU4vbcZ>#Qy3?M5dPe1QMbO?#e`bD>_fA*{2=j-U0 z(nH#8RH@w$c#`DvK0OnjvKIOH0~*tE1(P?VkuCy}$s%}9t<&jXuKIKD_euzFS?}o) z6-^vLT_1m#gHdq32L#cIxJXBqmZ}^ zKsXyk0z~&iTDJK0QtTBF2?}LXVvp}f$DMwm81rGWHB?dWHDOI%*?Ww znVDs=#mur;vY45+x_jo$yxr;9Uv*BMI$wR685tQj;>OL=`#qN_L0rLsYW*HP(>m<} zfdD@!s$akYV~6+h$kfx&fH6?c#ZyDcD3eYkP#%CaF)`0Fa-5!b zeNaT;?mmgO)G1SrKiD?p=@!nhF9v9d_-;o|?JalpcnzZt9#gn`85{@&PrCj!5T^yW zJ_qJ)(G18~)wb`%MJOVmcJEi^_vlVpbF%sjYb(1v+61F6%`#mC9vb*#GhE6R`1nwT z+yu;zOd(L2w$!m&Cod`*0@dY_S{1C%I0DmGY^cL?zN8h7mkOpGKalN-uI*6*uDcCy zCriFbUMBVpFrr3h>h!o#dq3XrBVR~g_%cNz&}B(C_^umhUT=u#7ni)aG_R+A_sH)4 zc>FNmzVM`dcnNYTl-w0p*ce?LT_@pLnhkQeP+lxScrk*Eam#|dvos?tv&mZS@F(wP zCQEc$bTNU%bv>775a5{JF8oS>PNSf6OaGnqm<}lKB)k^>9P6U-aVoxtCFX~004{|H ziUcX>9kz*?CU`i>bCFcgU+oG9OzKfB$UpK$Z*~J>v)q5soO%SZ`jz&-;ws=nF(hHF zgeb}YLM{^`HlqRCxdEynn@$QnKXSW+^kuQW)jRk#$=)GCp~f3gMn2zty#1O@M*@ZYVd>83^>1~3Rg@3xRnvgqkmso0mFzE%rm zr~959!;0OqQCFpQ)7IVoTz_@B-JdWm=#!-&j;&lG$0os*xyy6jDzaz{%$_T; zMRE&1!R0~z+Ml;`SwO5MJVYyJqNEo3YCu>CMC;c&e(OP>_U7aTlG6lx!HoK6JoCnN zqCWhXei8<*GE2Bg9b;_zfTer5sn?@OXl9#sh`SnW&;@ zd5GIx+S_HboE<~X(GON}ER>ib?{H0YBL+x4rHIumjf&W-h+xRYBbv7qUdw$Q#(FhY zw`Py1!Fe^pHc{^gYb|y;q?t2f2L7Hgs=i`cI&+W9xdVKF7V#K7i(ARU8QC64!L9rc zB8KWf_nU(mAnzSe!;negOh?@F%g*6!=RN8HO$43y+VhsxP^-2L7oJ;~4A8Kcq!duD1d+emJ5Vw~j;aSv5=jorj}-)`rw zu>-sPzeOLSN|=-y&8Qn5fA3{cz<#7z=dj-tA#}Zk?|V{wQq`-x(TeTlH@h`XF0wBJ zn0y26OnH0`CZh-(=k4k5m|nRI6x!%z!h^sh3qjv!XNADT^6A|M?VEr?gxBdEv04aM z#m%%xl&V;K1c@Ru zjd~8&!@7erHMGnjrh2wh{Ghsha^0nzo}2Tbuww#^`b452hV*GB0AiFfjtFq-=ut*H z`jx|KF^a%#3uM=oUXMPnIw(M?YXoEe>aPAOAQCv2@`A6;P){I6pPhrgf95R5w4tP0 zh_nQ5iG4=%&fM};>sMRwr@Yx+SHQeDKv~E`h|4Vd1+-r@vqnp z3^7O~a~!`p3H&)WntQNKsp=I0*ti0@y+VY^X=wVD*gG)()+yIjtX8rOmAnR9pZ$=j?mv0f{P#;QQ*zc{g}Uv^Qll=(t}Xp z;(IUDKrYEuytNL(hae?&0}776%D@YKlI!o6$GALH8GwcV=To)3=0WFAIyY7Tf^W=? zm`lan@&}E*`@mE=8}!<%&XRfJ@zi5)z=;|*f093kM!iY6lQ*;~WspYuw%+GT`?G?n z{?!&cc>w)_``jE!)O+#fw@XE{z95*PX$PH1fRTefNOJR9YQ!6J(&Jgke^@fj+{ttFoDx*?a;hbKqiZ(+X9FHh6GEmnjgzmT9q;Ql0zK?)H z2?tf)Y!JZHo#LcILwS3-lSak`w!MG;xK~dgHO3+I7b^G%J{t6UHWEmn4HQi!s@n4&+vUcf2L91W5 zWAFeT^ie4Smrw_HYbXvEyJGaq@DD^Zq`t>hzgN>HmNNF6@4#cE9_jK5u0T5j5)0YW z=OgwKmo-AI@+D)3e%VU}mnREWhjm1wR8k<5N1y+bK;|h1u?#AHzzf z%)aNL^BuZ2$>}b%8OE;Gr-JV=E+*DkUAzuB-ZUZ0w2#*8eBQpUBm(4Y8SK8%bv6io zQFrjxVl_QH8zUbIt{GE2+N-*^b2(7sD{dLUQDFHqhkiO>^E-xkmrTxY;KU8zYy>b* zK&n!O`6XBb;&R^u{cDv*xvY)5!S80v_@_lc$|SIm+#{kyJ+MX~I@9`d#aMf``dcbJ z6jQ~6Gx_-=S4Pp*!QTPeP7*MueKZUy(yRmvz1Z1jSuyH$-&?F&;Aj)G& zKo+qtuFW)<$xHqwl6$(Je-IHh8(QOaA~+J_>=k4bEHh)rBZPyuxZ@^4xUgtPG-#BK zujG6%XGt0_xATMdzYv8FY-vYOIJjeP1kpHplMxVTTaa&BP~^UqM~XTI1LwE>?LOZ& z{1ga^m{!5RTRI*vwA&x51eGx+tUtHV@YGgq6^_XK`$d8H*mPS1pm9Ycny#vS1p;Er zhK3EdjmpocQ6$P0<_pZCH0Xl$;`>+{0tW1LGPU<>Fc0z0*l?fQuJ7Q4@gI21#(_3% zdgLv$!GVm30AWH1f0o1JT8-zNE8%fVQo8OS>(4`l0H&vKa11vhniVCw*@P04et`|h zQ03>JDME0nv;6-8AT5tk#K5!3M&Z$1ta7pm!GxV*f6@gGO^Aw z$K$@VDWXN|u!P{reNqFzqj5OdBiPzP07Sh4~s;U)(Fc`j%5qe0s(-W|Dxt5sakOA)Q90?a_6Xm zYfo=LiD)TY1S^6kkvVImkU)LMh-M=-5&Z45C~FubQu5b?`EqZ7S8cB#q#zTd@*b+* zy+0;Kn)|iEEs^Nf2zdGjnt#DgZIy(55*LsVUDgc7Rgu9h4iIu8Y>_Bf$NhaIRBC|2 zffd$>$p0u9A~f&`Dvp)xYMmMdB0?mN^*Lx>&0C#)bcfLE3(dDe?!k8;lX%SVfRjGy zMImA*(ydE#@A*6cWJoSd_6p@74|=W`&{w+?e!)=-zUE-Iw=(M4)D)x_9!n{D}&!Iyi{ zfI*s5gq-f;Fzo{ExvE1vNZz$H!GS^LK|Sa$p1QRM)YnvDQagUgvZul7P4C#6?-Hb; zHk)N~v4OPs+xbKf>0;)|05l^I%TfvD8ky64zgcnmesfOx%)&fby?FG~>~~8}Pcoc~ zQ|k?~$MXz7mt4&L@kUDa@zP8+p0%4B`1Dq)_*{tMg~au((Y(IX>nos~@V7M25-kVx zLdpZbsrXQN0QG{k$P_|*aIsf|n%G;jLk_74gFdJ5*k@*rxS^g#Nl_VY;_;TL8!%gZVl=St>QFh4tS+Fl5ed*|dtsgjx*D5p~=M?v{R z%Bc7K(%AHy-@_ot{@tm{A9HgBv=xSL=9}7fU1VkqOADp|vpT;|{-Ee0fzH>nIxRcv zVr$!T=#ZzipFuT|T@@BdCf9u`xclTwnWHeAO&;y@s>$F%ppL+DmZTse46i2frWBv3 z35IKlL$2!nxX*TWn7vvbDbbulC-FBVyc5gP&-4?VWkV$f+F(QbBM?Wzpu%MT%z5-l z51e&%CsF2EL!nHPWX9`)&+c`dI-zaJYe4eAQ#^z%eo{NC`#kt@>%}KT%D9C$juvLP zdO~_IJml)OWUFqo-`>jJfYB=WZ-nDxPwcz9G9L>kfu3DYkIz14{ZD1$hWuukRc4Yh z!$H=Pyfiu#fB4OB(2r`>(hOY!Igp}fd9t`1GwlM4vooy&)@SRDJ2b0}JL)(bySkRz z9hS{+VXcQ{p7}Pt2@FTm6f^Fvd=9cnuf^_d+L`f(s@Dqy;-d zz8^=-US3=HAS(~|kCn=yl|Cjkif!1TQ!`TnnC8(2XvtTEyXp|B1x%$J!XAeSJY^E( zzbb+4k<807#;J256PK?iw1+rajKmQ+?l2pGIl}R42|e};PRr!*>mo3SX^BJjNo<4X zLyxM`B$I|QCxypC$2=z$7?--K(nE(R7KoLZcd$(&PNK#@Im)ZYlzXh2BH;p9g!p$? z`%Lr{M2*r|4q*KAYJ6{J#1oR};2lLUwETRr_$!|Y_?7$~1=pPN<(_aSju=M@ynYko zk2;uenqd(jI^%hX?0_MMd19%QkKP3qyapp9o;pmFBT~mqmiScu5wNBb8#~B63PD`K z84(;i8bIRVVP6YU#k_ph3Fw{n&FxfwK;&aM7w2jcMLruTpfPd2E7T+CTk6OW){KGR z_sXLk@`gBtX@Wak-aSNlK3a?TLp(hwu-3nu89ShbsZmfD|B;n7MJfRUox_vBIZ& zA1sz?V&l*LMexQyq05;aFlLssTrL&&w)ctKfPlbfzExCKi$NEvaJEhQ=gyDJFC8r_ zIxv7Uh6eI5(J51W{#KioOA=2SvP|ADS7HfZtX`KSLn*t0yrOu~sV4S)SCy~)M5-g& zozVMBykNM>s`{SJB5InNh2K0J)i|vLLa{*piV_Sa!H`e_AwN?)I@8919|aKgsErD; zIY>*2zq#&ye;X`SswvTE>;TW)u*AnnT{V;VR0Gw9nH|+l#%*FkLlU zZ4iTuDF9ALuwT$t$UBTxBNmT~S=zF$*6i7J-#(JB+>f$aRMoF1z4^S^eDM#TR5dgIuAH7<_rM!(Ig-9`f{ z1gAgA8AF2ZBE&Qz&j)+Mr9AztKlRG~G<#PGLiksJj*AA80}C==D5~wTmtNQSd#uf= zhMfsx24vN1tC5WP=!h#ZIys;Uy)-3wA1NKhSG3gp8^0RD%2C86AC2s;zR2-noR8_Z z(bPG9bvswJ?gMb73u9p5kBb5VzXWk~1uPdzndZuoVvqsc>IUq!E1d(SPJm^W*@6f% zYf;`k7Xt%`dYBNH*`#vBcN1rH>?CoiwkKd6aTL=ao$7{=F-^d?o3x+*{n0p(bY^ak z!djG?TUpNMCeM0&_B}f7_6At(X}J*y^9ES(I3EY)veL{-3n2Ewo4~=tu7N?-%eTWU z9Cf(<>a+=djbP`dr(3E;XTP&E^QHM28{Q4 zjCJ(?*vW~|ZZA-9A2oJ!gNHfnowRn}+D&d#rNbbNfl#IB|}bPK~Yk?39C zBUr~v)dWQmc{E(<87)0d(e^XC>TL4`uKZZC-SkT%?`C;zq?qNzdMXCz*_!l_F|Q5! zrM7lc2Z4*3YcuRL`uIfsSHMHZo`m?*0(O#`0x~+rQM@|dRUeEf0a~B}&$cNc!x|ve zk;MMmqjG)rV!2KP!M_QozUcm1V z^-mJf76SJl2r$Gr%M7`yVE(2>!whQ4i$qR|c&ucm7o$l3%9LNtW$4dbg{EUk%tC3v zWc*eT%TK)!55UVC0VDbh77xBp3IC#!g-%sGlC2%A9k%KFp<5i75eU>F5Ht#Zhr32% zsp?nI15(^gIR!o#X$eda!YJoK_Q1a;LJ0-&?hsed;fAqe`~ zaF)1Kf97I$XJ_w=4!|MFf5c|CFnraib*Kqkw3;|59?2yBSRR3eyAAAYa3DBse#{zh zr%Kq*uS27j_#^#h|FB)Hn#m6x?Z;&--07AbCLx9jVSim5d5MpI^A`U#kXbTTK9SB6 z`pf+=%X*26agfwhVLHHEtPQY|6o4(IU-TSu0`2^st1{&5$EkB+fB4BrF1|xS7PH6$ zd-w-5cq_%H#mm?TA80nNb^fi)ofQZrlm|tmkx?6v$vonUiNmTw+g+UAyTWXWG#vyI zwJl|!rw@f?lLV}OdacS%oXob{>-r-}dS&0^v!AT~JKZch{*Ca#q%=zCyw9HQpx7}L zhUKH|rR@p3utahDbsjA7`;Y7EOvPauX)AJ*vDuZq=08IGaFMO)`;VEvBK9WnrBH%` z>S!AVdNuUm4u2P2?V0a(>?0d>B~#jD1->qL`5oGe_3NoAF5xkFN~obvN*W6hJL36> zY?jz^Jzs1R+{;6Pl$@Dvr!{XX^dcD*Sk!2<{eP&CG=3K$Y*sUUhFFU0*4@4bkiA0> zl9ec=)!gk;h?H6ueG=?UszcPEVdaYX14e@2f&z^4RKT&d6|QS?)A~w^i48A}icMI6={JwfTn^2;B)OksjS$MphqtZh0qd9 zDc~*T<5-u6F5TjACb1?%xhZ0113SUDE!kyYAAmkmni#6zOyF?~>>Em3^m_@k0DP#b zGbB?qL>e&zG-(`)!bV^2vGOQCcKj1!VmVbRgq!44g+E$g>}ohF#b~7h56xhM9!3~U zQSrj=gkd8T_%e_JM+8HQl>K#9d0(g<*sGjd+rKlSZ~<)RSgemW=OC9>BIT4o7C*$? z4~!Z_@^rREE=jytUi`d-aV{Q_G{8kCqmy)@_Lg?QSiP~`AG)@%k}0-1Ip+KsZ@Rc3 zAU9OVqI|xXS@;Et8D)=}JUXBPPJ9taPM4hD&JOT|d!5p1qwl@5cJ9jGjKyN=>&0GL z+xii>AIgmP4cO-6$V5o!+;>Al0ra61j z+2H_vAa5SHV(EWf1;Y<){=~8~&e>vW_@7!pDukvuEhzHf@SL=4(m;+^0v6ji(3t zf@Zq!i>!Sf25X3sM+$wSe526f7q5xUW^(0ZkQfR2?rVs|3?H=mKs_i;sc_*HL(`v_ zax>NV9ea+a;}GcsgA za||cMQFMH9nO+g^-ueQ^OY*c2pG!vEPS}tCfeCw~Lq2(V2t$A+KqtC!dT>!A=m_Fy zP}%1C1#rthl&Is~IUHb>X0+*r^;iBHwMCDRqY>!_s-#K_4_OL~(8M)L{eap*q*m-) z);hq(Al-~nqc4hX7R zUgHXcthYXqZ@-}~$Kb(+xVDWZX;{#=2uHk1QS+qcU-GDDy(U$?fF&WyEhu=b-1@aD zAj?b&c>P);=knP!`@C~;{`5o0XWXx)Mpwu}gdQ=Tr)f;aQF)itgo~Vqt!fT6GoSY; zvQdw@XCFYI;=TcEUrikd^KXJ#+Ixym_=Y8^6`^^HgQYNUdXZKzA@BZ@5A(x#e1v_E z%VF9l1|#X%9IyC zXPioHdQ(?9OA>7 z?zb(sS{RCFPYF42Wj*%;<;z6yGd?Ps;C|&jq%NaXOKhR8CiA=51#J}Smyonf_Y8O2 z$n-9hE-^m$AiIuU)05-nV+L1%mg*SNU3f?6;ZlcCwY9Gj4}263B(m<8#Y5(;orQD! ze&V;;d;h#Cmq(R8s>`&=*u{2Z(_WU+WmkRH<11=6sgbFv$M^iW7LG=&hh*SOmoArx zS^0DQP>5tmK2NXe_^WM!K;g`BP4V0~neW#jwvwqHTyg)MP`1au;B&g$ z!OoeLOOfJ8nE3o?V^iF3Qf7EbV1MCS1#m|28EY&YgnAHI4l^&3?>Cr(?Bsd=qp%EW z3Ip50@L!xtvp$nE zDZpl}(e0hbs%RJg^>1HNG`Dq9cCH=Fb+k$ zzw|l-?|Nc1yWq07@b`&4`E-c+aQHee4%DRiC~MEtaJEy#!nn?>)^@OG2yp4U^lBuw zsH>@+hO3$~}78(uV#v_DxuoW~nv-k<8M15!qJfVQm zU+ot_6rvyjX0j!yQHCS)=>-tgg#* zEWkI?qQ*zW<;rR%*CV&9(i;yPIp*iX+pkW1RWXw5ht_ftPfzlo#{V;6$n-hYA?~oEo z73oq{?IkFPZBe&t@#|~mMPIi*kFtCPt9zNa+){$-iYZmK3Ud7s)sfS?254J*hms&2 z)2C(=FTm6>qEWy~!^_k(+qhr$(;YtvT^98s45@ri{lg${#WtQ1aB0M$dl^orB|pR| zLZgejAh&Vk$GYESXcyaf!Pe&X>cCFtD?COc*aE1w2dI$I<@F~T?onBdUcq5&EHBKe zy*JH{%37sa?FKP4b);VTzrRoNcbSv$I_^loF8Xx(PkS35Xy4W-+F`@4vq|^lvPnnN ziUD$u_*e_ozZv5KF(c9KL8j|bli|lCsq^4z!AZ)`LHfL9^JyDsJ|A(o4)YS;pW)gy z=V3&$r5?+FWdy3A1Z*%F=MSK><3Ir2rwN%^ z>&tu5|In2poYE{TQ<%U4pWQkPnd95g;vqGT-;FoZFVgxM&w5kP<|Lz>Y@|Pkb9SU( z17AR%x3bVwU7hVTRqLSAGhxSi)3t(TgETM#bCaum?h!}O*~1a6R&EeE`>tN*j5_h| zLH~A{BX2%qr`^QYY%qv3@q7D6V5#=nPztK!le(So90o(KK8BB64uk4BTz$k9e5JU2 ztlM{wW{V_rD&hUnHl@K&`o!Dyy$d{{vD(6eU|pZd5pPO0e$*qlK-@t7>A%U)KptI! z7$hDqjES3rvPr8k{`^`r?9;kr?FJ|G*cOU*O}{W zX{yR^bU2Uw2Gob&ADEpk#|@DNx52a(LKH^G2gwxYrPc=6s%1CfV$G*x9w+#Xn@g6y7Byn3&lMRhr5!!a8$zT4 z?Cu17DawNb{H1PYblNG>)W0VF%x(V^H+X%#BI`-e5&4G=5sQ3!?;{~0k&c?WB(|c& zq($Dk@iuk|0!|agEn1PjY^taZy3}GmBc_n$?f0)4)|7l~SqF`;e)L)0DrliQ%-A4e zxk<#I9GME$_}cb*U?PS{%eT}OX`g7yj1(AQ4jG=95eWrgF{FJaCi+9m!4KuO4qCh> zhyQq=KT@Ut_()O%XB6IfI?Q3HS~&DLLR!d&ufwN6nM+8jph#@8h@)`UA0O)XNOylyW|FnKGlwgO<2OMC_RbcVCfpf+xr?ZxkM2(418qKA zbhdL$xoRLY6Nkxc34iV)Zy+%|A6|X6!-V7P!w}K%y2|t5j^fATC@;1Jwn~wO>TW9m zKfCZe!+g$p_D1S^cGu6e+=>}**|NL2GmD?SH82DAg>Xp`qAi<3AO&9n2TBmRS>Ww znHvBUl4Vaiey}xfrDY`4w%NQj;VGXfBX@^-k`TuDV*BvZRUx<>z4T7`%wqTDsPvXQbuYXXI^NA5Nwd2`Sc-!z z@(b<5#qnHdzEM9ZzYyT>IUej`uhxHM(QUVv#7MGd_cw~kHW6mOsC7j6ualKK0NBz9 z(fXn~K&tzd$DLHGoxU~GoP==VWn%5}>3jUS#tv)?M6ls#4eflby|RLi%e6i0*=Boc z0>jG7oU?ON*|*3F0x!J3`x8i()?Qz?FJ#) z4!2+bc;?@I_|FFSIun_6jd?0Z##HS&9=p+=p;}HiFqx4#rUps5ygb`Dmg#iCvZ0}R z2G2J?h0@WQZ+NZ4RZy0Ua&^(92(K-Tq}-PS3P@bVm69|P5>FRuZO_kv>}MOx*V0XiBLD>H_c~ zoH>51G%gyzu;#c^Q#!semL<}f_gGD zq~%Xf_s>;1g4S^rRs-4FJ`$Q(rhwjkK&GjV_spPV^J$1UAAwkg#q z<^f^wWy;gI-}HJC=%gI$3F#T{xq5R(n=fS!b}5y_R-gM>5J2Ise$77W@?c-WEqg50 z0$v%yX0ZL=b^`GA50EICf+}OI?V}C)Ko?H0MvV7xw@NNjwym&NDDFlr@)=CZy|s0( zZ*K~d2GF!PEShvwejqXsQbW%%wxug`sST@|rY&*s&BVOFnuDBxzPCE&*t1lqFSFfj}GcJAD9)<|QvN)JrNGpIe&4V3i#zB3zp2A2RLuTCJ+*eWuUi zm;LNXx^Sc?A4@(DrdH=DN^X1>xBdCQ+nP0rg6&`g`Vs;GuLQ7-g?^20e-Y^F1>*sq ze8;~kJ3QkUHUYfF#6s%+0{?S!bEdp~78VvxS39B+z*dBgi|#cqiCoLLX7OwP;gtGcMpOg}vNo<#lwYnR`RC+VLj!M^VnqAbtNz~)NRk5A zAkwCm$5sD>S@++1tZ&~^Sm-a7cZsS~si^+T^Ox*K=s`u{z7o~Sp-x{SwE$MC-z3D5&q zK{FC*Yfa((FSPZa1}23MdMdKGlcdY-9j-*LlLz~wd++GbB0hglj7&^Fw?b0=XHAGe zn`cMrdW0pLw7g`=%`nQy!bUQvCCp~-eq$CHZ<+^JGJUoTDF*|`H6k44cGLdx-vu9k zEUS(kaB-~o!Ir{O_?m+F&n}T|vfF-iwtTVEm+h9i>F}aGA-Iuu3a_vlT7Z8(Oq^&0 z`W+`rvr5ID#}Q7=!zu2G;=)H#l5SS;d!G*FMei%Wn%`ROzj^-(M*pL&0lySPfUXr@ z1kHq1r5@4XxR`}PRH>s1r`kI{u$-ws!FBf9ReXM1NUldAI`F_pr2&kx%65R?cd6)w`;mPuaieepTk!u~u zt|NMzqO2MXM+up=o75JlDvhf;F%_pj5CPIF>8 zX8cWGM#eTHbK$Fe%}6Xc>Pg&_9%^X_aSss&=jsFy=4P5gkNU!I9D71JZNcJ89D3}j zbB_3bWM1{v-832=YjIOwKZ8FhNOUk-auqgZ>PX3FxUfb0XkY8YR^dxU+gi$;69jY2 zsC#H}i=OfdiX-CX*?N1%rN*+6lj>AdfAlofYoS}I=YQ9=JW*xstIn=Ya@nUo)2Y>` z)uuYqNf@X-vDzq;i}euW?(n1Jv0M;Zy+7In*KY)P1mdU_XNWr&Pa_z*NY?pFw&ru- zr@G~=VvCevDw}*SpD0&M1evgQZrF(!bhxKomDE18EsnZ{zeYQ3KC8|6IXc+)i_Vks zUV}Ec#ZK%8TR_8tKgr+CJ8-MhgKwqe0y`{J+8j-@<=AO@Yi_~l%{Z6$=& zki!)_h^e@!H1iXP!jv1{E|QajL|dwE-iv|guz0&;2dIUSp`ZX2u0{f5J1Z)vz}RhG!5L;l@6p!=9_ zGpqwEQKG~(E1|Fu_&bTN1gX?X{X!t#8!d9YqnyR)`oSvE}!4FE259AtG5$jFru|#3*z4K ztT?8mqv|F|{qwXhN!jjlbpUVALJaF5sm_PDdvLZ+i2r7FO^fmz)b}~vhVusH%K(*+ ztGYp_%TzFzC;OPn)4n!1@OmD0LK(It zIEfDV%jnWzP@0~wmeHs-=>0-SsuH96qOPoT)EfilWU^@(IH1X|yD-?`s2LxL9wYuQHT7IxJn2W$PaC?86Odss#^(#1>TSd`{0&I&j8 z-B%yqxyw=Xl53~_h`y36&3cf0%LXt2Sx1}E_3cpZ`D&PuiktiU)_d>fW==b>ywm0R(EKgf9;ny` zl#J;a>F*bLt~i@3L410A#4;Tk9Gn3*2aBDbpF8>jFBU57o0m`!1}!TqYcv{!1r zomqaQ7?zkx7%5!QlNiQQaii0_v&?5I6tb!#9;~NB1`T`OC1Lew;%&yM;H#ADtEEx2UX z0}=`A621O9$dnC1r$qzOw@Y>zlPLdUcLPcpw3w%~Gw=QKG`7 zrdAtD;wVuw8L@M0O#T>NDFIF@dj<_cRUNr8EVPSf|@^xW8ug-=iw9n>}E6Tt5&!O_nLR=U1PBIxDKLw1N zwX1hmMpg&JW4XYTT2{0a;{dpOYOrz9s z&Y>&_nEGn&H~eq*@UIx&pE>qZQWiwrMfXdLp6{D;8MG)@j_ov%S3?@{E4ua=L7YR1Y9(v97zqURE!XLN8aXzz854n#>W9x9hsYC@NWNMXHE+ zdVa=v)Hrh`x1Gx7b1|t@CGbXJuXw{t#rJ2H9vK=OT8Xdwwck~CM`uI%MaFi&5`ql{ zycod!8Fd>e&n0+gPB$Z0S{6Ro>0|s!nqG`R`BS3X4~jBk{JiEjs{_c@Y)PH(31hM} zITZ@t0a5c40E(3&!g7mgfXP#hYzA1kxg<1;$Ci_ z*Vd@v9$+IThJ>jlno1Z*sjD+H#vM@1lXRh4H$yI)mkRwyU0vOZj>|z4tfFG`%+C?1 zhtE=`QN{(YqLKCMmIqCzeG(sMEt>}#SCwnrf0yP^UmiUo#abESU`UXrOMY3Enz$qxp<5N`twX5Ikum zb7ueD$tz2nxMh;Y05&biaNu|Kn!>liv*zJr%t9*LJ1mXs=IFF6Z{0PR4#t(dSlD zEzuWL6e`M3xnA$i^UO`@Hd&~enRE_cgB;cEccx*al+Jk zr#A^v9I#Pf&(#)_Y8u3awBN^7K=M z+CM)}^iT}!z+EE?)>4-JRdgXCTVM7iwlW3?AKMpV!ek^niOIX$^C?md;S)m<=jMz8 z=$+>j!v$g4k$vQZ3{D_15$U*_6UNGR>-w5N$nUvn5_<(M?(f$2KzkZ{5j0LPu5S2` zJ}^waRpi;+>IS1sB68uprOJMW-|Xx%`z3v8Wt9f#lDFk2;+SJ*8VXUO5IOSHdrV|Q z9m9-SL0uaGQ%8#LAfb|?{V92GsquJJMHhBKZu1>O%D4Y&S&AMM&^-xDarkpZ^juDL zwL%yG0cFbfnmMX6ih{q{lpxl{q`v5J*=oU>YtyB)7_d`Cf9bJrgRA#t6G`?XhPah}MT0spiB18`WsPhnj^sk*~9@K$t%uWBphZn}e--CpkH3Pe^W3}KQ; zyg+KOET)lOF*tTS39&YRUfFa> zs?gBTst8T|aN5n{#Kb-$x9x6yhTK2lKk7vG1p9V1XURjnxY3_w$>x-e29Ho7rXgr8 ze#!|5-3VL`5puu-#)=+%ZctBVax%#-q7uu%aQng7kxs@^t(4r}+}@0&%q4n*K%~TF zNTDg?6voh*7pWW&Y zPA4ZXk9_=&=74yKq;Cgz;5eXjf49nyj&9-ld%2;HPI{xVw6nRbmI-Q`&2Ii%Bmas^ z51k~br(WGp;igAnh%%B*yG$PW>|gBY-DbI%ZRpp0hd>EjN%S5b-mWgqvy1hkEtP*} zOa=3Za%oJ2(1f`vBs8Jtc6N88jgR)|TK%+;o^^RsxCJZ92ExXnx2uH zG?O?Zn?P>gpHK;?bCBC$W@E(1_kk$z3RtLL5|PZzhy;0zQU#v5%j>fzXVjziKky{c zOeZ2rt&t)(o?S|O1%v(X{Cj0-Bb^o!96gsbIbX9pW3=$K}qul z`P>p<&j-0zbifTVCCu`k+F8JSJaB*KS@j6;^@w1eMlv=3LAskU0u2)gqbV@qE0V3l!3fsFNSZj^_zc5D$F(@VQ>y2OrLak!Qh+-NqUsti9$1J-O;Y zBpwHPma;a@=Pzq47bcmsL`A=^aN2DDYJZ&(QS-fBAX*!~!$lf(XO0?XXzbfvoS&A` zblF=6!x2*6vn}0*-{D0MU1Y7vGCbx`OT_zwV9FSvg)Df)y(GVoczLk&qz^N_5x`V! zwwNaR9#4jtGr15vihXl_ol#p?lV#3Pw3pyBqWT;Atv31Za$yd4{tH~l%e#S=_iAjW zE8R1!+I4Dhugnd}MQVz9USbs#Qdja4r#|UUgNuBt&sLc!cpA4!Ssdm%ziTOTeJ!d% zWBITOv@i~~urb^U2AY5Qy9wvp@*&T?A^9rO`SdW1ZZ{GAyGy=v)>5862_Mm(ca;f> z6jP=it?PAy#mg*MT_1w@yV9<7$MkX2^(yZU_l1R5pPz%=5$`69IW*s=9(7}`pP3!} zBoY}v64+idT}(`S(5V8_C{Itc+OM*~9;eJ0zdbuA7b1p+|1_!?32=$Q>ZK0bZ0=3V6V#YGgI zRz1CNef_Y;uk>#Lcq);L{antc+HQcp8!`nelF4TWK<%G3*l(c+=An%aE;7U+9El}_ zhj0=oV&5R?-Tg$sZpYkvjgj*jpY!u(_TXmCCDL-ae=*wIAD>pzbpu@QjoS9L*{GAx z-+oNBW;$iMYIhDF4@1y0n?V`6)?r0ut$oaw-QGyLzF5weQ#vrgl9u_cICCFxKebW? zodlPaWluH9z8&QJ{Eb&f?}X~;rcbNw{REN&Cfy35o@GseF~UYsvC|eWo%+7TpDCS5 zq`1Tr_eWr|Ik4q`+0F99#AF13&S(o%TK}X=3n3}{a=K%+_o*kyvG7w@ZD{Uu>jMhm zlU~eE&RGuLnHXtJEEvkmtTq8kq!}=++m!7Av1(+6j^2^@PLXOvv>Qa3sjRZUM(+o) zK*hPn{rxDUm!~r+I}Bs&9bEhujb{`1W&Gj*=MKoX!U< z)}dB??u&#-w2zPZsy-!BFhqnNuDt`gvFZNBBONBq*tz>b! z+O`E2bn0+A&9c}g6t($|8NjI&3X6R1S8rqCz#vW@?(RF-l0b(0Mn+Z@Nco9?TXKY6 zf3l@WSx}PZf!_G_gIZ`ii&Jo8nylnIZj{(c2?X=yVxEAxqKqi+mfmhv+fIR3kwx-D zK~dpm?_S)!60kjn7ZKar+?A>6EHtLa-y_+b=85c05jFqG>fdJjdD%hpGp4f!YM0&Z ztMtSft3C2ID{P7QJ`g`XsOgp<;*P8{OVr4GCKmw#y5yZcs5-ze{u^55-eBQyaR$Tt z##SBmyp_spJV)WW@pZoAWpBex{CpOo+1RS2foVPBeZIW-G%7Z=X4S*j=y<`PF05=T zNJ-Z0FoECbs!j1J!ahEq^GU9Kydo_}S9IfwEk44lPKCP7ZfPN=&e0n<`_|;zOFQ%) z0dV)gWsC!9RE$Yu_I?+p?KUn1nfS)+ed*?^j=+-VD|Lzg$>_O<1`%K>@MJU9n9lry z9a`E-QqplH{%5p3|K^1VkMS_B8$eaEBWM&d9VaQ&>9yzB4cw`6+0Z}kjY0CvW_DcxrDNah9qSWw^zz(O~&99CTl zSo@Uk!otv0KP(YZsGiIrmCKu?o`W$mFyyMT;4*@Q3GaIyk~bM71jhITKbfQ?KDqad zC)Za4i+_E=fus@P;a#RF3LeuiL`|8A8vNpN8??V;auKa70<+o_NQjGh9GO;7E~i)CXK8=G59O&;%eBTu$fzz*Dc@2cS0 zscnG1rr+*4o3zOeQMHNVv)NYimG6U@Wr^f;x~k~=#t7CxRjVl<`4}$Ws=NlvZt1#3 zb<)MKqti@!k)G*w7G-Bqj+MU4kb_x{@QW&l$kFmX!cv8MtOfRW$XGO>ORxL?sX zX9m;h5ER_+ugna%JhFFPaTV(8d=c1`H0PUg!O5&#Y213*tq7g+O+V~gO2;0etB;3DG6zZrVH$yeqY z&zR&8+OZ`95|cOVxp{7HdZ%1OdJ`ExdBCUyBKzigRf$+>mfk+JMu-#0WJACLW;C_h z-QgI&eERq^-Qz|nEHo!o2`--b7W|B#o7!|BZKG~}yCt<=!b|URCvm1$vr)`!rnUq$ z=XV^dZCM1Pbcs0Qz7kSKoS$Dk)lbCSj4~Xqvh%r`#Lj5dYbwP3S4b?XHVH|)hWIFZ zKa_np7%7q81TR3XEFWBn+SKT#xWv~u`BP49@X`GywO_oSXt4z}g#Sr_B^Xni>j(~C zvhl}>1l!cz&w-}G_Xjf#gF_7GZb_lvKdx^{J!3yH5%N7hKSdA3obpH|R~ft2dIViR zJ%CO6w&i8{L7vwL7m#mgH3bRRzHFp!d;)wIpdexb`Sk;VwyAzn6SLFKIhuatjEpdl z$i246QXCv^_8d!|1Hww)8p_S%1MP-V1bI`c`c4foeEe8rEkO<9Iiw|MS2@>ptu_{A zzhpsXc*1FE&5Jz}Eg4rFBX#>Nw^RGsfAQqMgbO6nfk5t$TxG{r&w6*vc8Msb#Y7`I z!i0Er0SgOj3XrV)2P)RNu;H1g+F>^eF`C?n{43Buo?dgBuuL8y1Fgu#n&?6GYOHOx zMM6x>7>guu6Iie_D%v-~6DSTT&D+@R_*X#TilJ?W%hzP=7AA2Clk;*`$=C$16d} zcN`;WJPb)t7}pn5ZRNWq{!}hG6lireD{{1+OL*`u=H_HpI&~{deQ_s2`SvTt8A<~< za+9Z@n*{&_{|ViK4r0E><_6#N0_PH;vLy{`E%dSLpreUT(dQe6z3JG?MBWWCv6kDd zVdjHT*{v#Cml2~Kn(>Ryy(aOGPhmM#hNS$uQj{-h>!yKv2l~r)>4iK%L?nl?(LD!x>9|mM|=B#@`R0_*>sW zA@fw0{N7&?8CP*rG_cU|7?o?qP7le#6hu6BuCwBF?#F|OTS>#LtFrf>Cv$&HC1~-K zJrr`J=O(zMtTiQVwi_C0+KIBCu)eN)HrYb!!l8@mArAS_zu%i;o%sT>t3f$ov{oZ$ zZceTZ0u$<0U3XS=#9U#um`e>x5?D2@OK%IX(ctiIPOVDU*TWOC$o*z8p_-~j%%ZVi zb^AKUS=VKp=FYMkd7}<9)d^vbPPvO3z3_5J#-Yh+fzBX5F$kT*%A2p{>3&OG zch~{l9y{s#70*_>IEjsweQlWdc@Jj(s?!Tk78|ma*;<}}fSJs|Yl{K&cXJp;4>x|x zBtu{UOiyN-{C5b!q+z}Zi07!7Y#br(uTQx|L|`hzH{r$;11>|+U#WCKgVFh!6{mPf z{WZe;zFSPPm9@%=HF10>Y;>8xlYU!8RP}!$YTLxVzHo@rMx4_NNH{s3&yTmVILr>> zf5EJBV0_WwQUMBiNt>Ih#e6`k?kr`WF}wLnpy>cr!tOo)TgN{F3ynBaZJ2rn2qUYY~ceRg|5mDt|GQ5 zwlUs_m%vZp(+`Xc#UvU7;_8*zc_wRh_9J$F1ZJ*ar8p+^ztyD-?Tt7R4BN!sw5MA-+q<7)n{<c;U9^|Bu_HnM5%1q&JrE^2hASL8ws_om>soufc$LkPRb_Cr zxhXCXh?=*i79RQd{IKfiaHlQA_gv+c@c)epX?T!)egz1vK0ThSKzRyD=?(v#xUa}JMW#(vxE0ZbY{akFU z{n&l2vln>m>a5GaY^Jg8Kw10yZ+-rdZ21FVSSKlyMXwg+&zuj>OTB2%dxM)Y`;b2@_#2N}PjUKV?M_$A zKZ4k{49vh8Y^!)o_#=SubTZs!&L>ux-*6NU+dw;LHK0gs(Sn1V}{8bzmq<*@u2 z^Vdz25!UqkA)kdR4+bRmvkEZSs$Atm&{Fc3N>&Oym#E^*`BYkGcuA?EyzabMtma$w zA_jw10p2~e)R>h6?Jm}&~&UQ#e;PbpsZVBzQTx4{^9CI0MV!&SL_Lv2P zCugigsHpj8#CN)?=Y5u|C3}ottu1B&XC@5T>OFXl1u}VB2en#!3M+>qbndBh0TX){ zi?#e}mAI@l@#s8+hi+d~Vjj~!oMwcbNprjQpACI>@Ciis>Q+!>6ig)x>%|{*wL(Pv zzbIa5Bv=Tkfr6uIe_RAc|IB~D2I(Y76ncW6rqb|5xAI2v9w8J4m+l_i-XKq$WvLU)z)i6~cQB`g^Bg<|3BhC~0KJ@(!Hz@I0rq#nHu3Ip^ zB!iM-)9tGY=Ht5Cs+c`*j+#GMgY*BsI#I#GUIXgYfmoH4m&tY||H0JtW5D8LkLEfq zepDcR%{%#c>zFeb3){amBqOWn=y4Rze!gYoN;kLAO=7fkMIfx_)E2%eo09$GvFRYK zjcY0p#P^zm9J%a=P0NR{TyMeHL*sjCN9Cu0DyZ3@`}2eobg~7GI2}9GJSxq`l|>@~ z9paKRF-@Juh9t{ap(H}wMNB(!BGxP4=5$TN5s&P!-26De9FJT(-2q6VJRa4JkX9YI5{7G<5kE%{w~vcx7>3)%U7AlQUfV6@ic`D%cT_%4FMZ{jC4AqoTBp*A>#`Up4`U_tq+&Bo(S@CID|KfB*a&(1WrX<1Hx>Zmh{rAIAEhM9JGG95mlNB7P z_fT>}H#KnXbb4YM>Sfz8l8Xvbdfo-hO9-!PU&KThkfqq_$OW)yGf4kJe6! z!pw()@hu2BT)7nbD!7m7+@~2{GZqRQwu2i3OKcy0oBONUH`>Ilrgn1tn`W49NhUAP zik)9R^u2O{t6l{da(#m%eerI3>Nk8Y-pXu+uhG%-lU1ydhX^@_tb~%GVYWJ&!X}pc zSk2k(e5DMrTjd(4SD$~mimI4}Yy@Vmn7!ows$aa93=*)vQavEWIy=Jw1)6a}7M+5gJpYDg^VnAMN=gusA}-5SY7#` zT?$pV#Cx43#q_+=Li@uAak3&#d_Ea{l0R+10WWN+zOS2=HSKNEAiReQ(}Ox3KAn~o zMrwv=D8oG*mR;JAY6rh~%>Jb_VFlf=SGuf}KH%cfQl(eNWSyE#;Gg{;c@WwBE)%W) z$b&qkwOqa^%amTblfZ)!ErS)^Z*dlRgNaq~MT7pPCabjZu(AHIv9#z(XQKDAc)!+zA-DJuoRqk*BBHC66cyy6bBZPCH6x8(7 z<{d!--~;&aE%*AUQ_AOO#~k=UL7}gwD$w&DPODx{thi zb+Q! zl(@R2s!!bmE7Zk^;G_E1?&;F*D)`((`Rz_#+kriA6X)^^WR96Sb2rFqB}&8RkBe&> zEUJfeQr&JzagQ{02}j3h4Ul^+quoP( z90cAqj?2BqxS9F%)AbGhcvSs`?v2DL*KWL^6oX>Iz9t=(O1gc=H>jU{*Thm}K;DxJ zEpCCu%LI3XrJ_AA?IwC!RyOq9_gNrDMqX))Y<-~-TBi?1%UlnF@1NrLD2C4INB-@b z8i5PHN!k0A!$IRq%G8KV<@U7~v!wI_W`q8Xm13*-#)+lXYy961{_8At9&|&knhY)0 ze7g6md?e+`5)|^C$T74^;$Z{>&mj`!9_|hKemG(zzS-IA1#{_%lBG5K&rbr{*rS4S zFP+Q|>ycLI^;)30!_^NKFKe0R-!gn@LOo_qV;VUJHJug38_qBGuwJ3(Nv@b<8D2*< zux{q48C?^pe8ZE>%dP1`OH{}T%jT&e`F6a-53;V`L~A%aw9gjb`B|xdfcpOYNnPy$ zX;xz<(RJ&A_nxQ0eaP-$Dc5(}Y*wL>y^I>Gh%<7C`G`5ZId)5NeQttzXdLjz=(QM& zG~XHOpKK5s>Ko~8I9*MK%zXl-l5M#D>W5^JP z^T4=;Z2T*!*zG%Cp1H43rP1h@qt6gJC6g5XZ$rd6&kONGK13r%L6?3b&RIf{2O)Fy zN(2ro@&#(GxUC_LY)EN8uIzc{O`OXg&d94?{$tFF$>{6yv*I@og2vGUWzP0{)Oaa6 z!3pXTk5Mrz+8r0S;;F7}1xX(+^RQHN4cC`V@MrZW=@!<}$V#XEEfY8i=OdDPSo4`f z?HGpVTte!w2G$Km3jqX6g&)chpR;P=nBy*U<>Dh7!nev2Fa7wBn;$w=ZdVVFyxO&J zn)27|Y=vAOQqFVt$5Ur6E~=i9^W(HjBd^TeB&l}pQLjgvG{&N{??dz&v7=F_JZVv= zg4uZ?yyX3vRYWFhG;@Y0G4Xv5miMc5uC4r#G6>Apen)vwpj3*Tt2G+CkhXT6hWnqL zW4bl=Y?8zp>;2+O7A@J6OPHOyqu4=6KHTuraKu_KAf~^HeOO4CVvbF7!E@g=pys^X zdxfs+)Rnhxi|}GVYYeD-w_?iH^h)_Lp4=}*xj7M9c3)L;rWn=pn74?AbZP7HTHF3P zkYDt)8dG80f_MpI$MUKD2y8Y&hnV>eeoofAOB5)xjXWSZta%efG}*Ye zd+ObLO($JE(xgb~YUhl+w}a50T(U~b|4dt<+&8o>r1rRQ_rpgxo69nCHsnjcf1zUUyKUATU=HzJTepAc* zwq4Ek#S(Fpke+R7#k#0Q0P1|&u77rQrL~vl%&&AWt`nV3dXsJB=y?*0{WFuDr=_x} zz?n;^Y&T8HeJZ(J>s2l4!779EbTZ9M1>ID{@p>C8d_ZT}PP6gF6`4R_`XFIgP=*ZK1XD&Y@wWWYrq&R(q_0 zL@}1Jq)16~h{NrN>6$%NyLU!|6f!e(SoT$P(jz}z_iz#-b;ow5W`e%0yIPI!esqQA zQ15(BJ0f_DFIknhu7{GoKR+&kd<09*V{RwX?=OCMmfZc}HW4VfW<%!5+R` z-VxB48?_2qU0JAPbT5l>E{v1UYCTxrX8_?34vY=(OcdFeM6n1T$L#LAMq3LDI zGU-Yn=pkQgWHhi5!!Bi48Xj};UUA?Z3i-j_S%)85$fNj&&$6#u7p7*5uPdj{1riez zDQHJsu;|s|DkCjLu?HxA*2`vFFm0OkSaDmPR$FP+8cd{28ENb_=4;ZDXFhdR1ov^^ zOnekoe#O=I1{6}AU$23+&5QJsjtHEANU&Chh(;J`xc8V;|X}}P689Lfp5F1n-4!?jxF!vwvooYn17V_*BM|Lzdb@Zs=91B znqjpO4FAV|nXz5pIP^p%!7A&`{SIm-}cu@ zHP|gOinZ%SUnYA-WovQW4j4sKx?ejbJYP|0oIkR5P-)dH5tDlcp+_W^To%t9SD>Hr z(Xicxg)2}h0mY6u z!O=i!464sRe!g2wx2o2kS`20N?)6wWgSwHUZd_m`VEv^9AhX^o;0_1B;JEsTOXZ!W3$G8ZX{7ZvY_A$wORVSq+#<&<^rkl?T5Op?HTO_ zrsSSF?STUqjz(}{;P!})ot%yyH^6I&S&Jt}l3iPuPWzk*VMZs}65bz@d}E7LWqEa1 zKh@eSFePyr4%|(w$!P4oU7@l{k{*&Rq2OR#X8gW}`db3FN5Y58qNgvFJo?3d&bBZG z{GA3NGUe`xc*OO~)8ud@@;sSai*n6J~@{hY*@rT6@?6`w

      +WpdKlL?tZ^WW*Z}N5X6YBaT%SW7^J?4oUwCh%4BEKMd|2D za61r)-y!Blv`{|1p?fq}=cMp0r98LR8>D{eoMyMMz zCz>6#bN?4XHfi7J9~|{cnMSgQ1iL5FCUuIQt}9x~Hzh88QN51vu31^OOoJY4U5ZJ2 zQ&Z&oq;1t+xo!LhjE7k?Cd+q5J62NL6KhyIQSErgUgC(%UWXKTqHKIU}g4l1nP@4Nht|iFdAl z)n|_;UYw{Cg>IU{Ya0UfiLBf>6VrSRdhHn`r*^t-0Z#Q!<7*u>#6$oPhQiYY;)^uP zJ*m~3Ab)2Y@F-}1z>lsk_Ugi()NlL&ijp7_+IB+0!HI#ppS8urIv6cPT-JE&YL9>S zmrG4|VM0~GxUt&HiHts9M0_{L*U^=whApyYMA5|1`zX1vA@RpdTU`4~Z|Rw)9Z9RU zC;hu3c3aC!QpGJeO42mqZ&PhXL$DfrJ;T}uz~uHq4KBY)dLQpzpESXIFOL8JZ@{yO zA@P~N^J}#ZhS=9mOn#5Bn-R;&&D8>x~TGeY;JjtL+)>t3;SSg3`C5%PG0;pW(JONF@VA-sCryrWM>*q9#$j{JlzwrQNa zkc`Q|oEja|OGsOL6X++1US#t%MKyEhc6gDuK6MKxN+aOHf^j_O1l(9%tcPeSo@>dJ4ql$DSsxbAWlbHQ*el zmy_0?c3X%HO1@)HWfpoNk9m1_>PZH?lAxq(Z-b!Z#X}W7uVaxCjMQseP-m;G6bX^R zJ;wtB=xC;zA~nTYbT#D9ki^yXet^*=;$=#25y<>bIr1Ph*RMy7XFC^O`6QR0X!e#4 z!Y+MMZ?QirQ?XU{bU^C*%g!E69i}=G58}Z?$DzU*|NRLjy+6)*ZXs{+>I6!m;`fdJ zjvDLZ@YGa~6lN_So5`}cRVx;7K%d9MUp$VL_skfeNYo8(SKrK29omwbQ8BsD7Amy1 z$Y@HwmJ3zd6yH7jS0U^rayrU!7@_zGMzhj3SO0Z8AGY18_bX_!y)&m*yavla0{2z_ zVFA0w@sH^&7*xpAqTr2#R#^W-i<4(sDw>>0RBK!3Q%xpFx^IY0-8=1S)?F!UN^_^_ zQ;1Shekf-)(dbQ5Wi$7VO;U*+mTMY!pvI#{DlyBhZB0Wni=~n#9Rl^@-Qmb4q{4;r z(CA=9+`IYv!*JKl-s){jP$l_r7KK1V`x>q{@Jo6 zNlP=goVAdT(Mf!YSLPj36lB$&2P69WM)g@yMm+wRqf3#m?_64Hds zFD)9qEwF1s=uuqBLDOX&)L+f={@v3>ys8Hj3iD2N=HAkOT|^ve!{oE9#kvxhsK>VE zqe$l3GNn%0OR$%Ck5wJ1MrS&e^pwIHciKZkYeZkf@x31wtl~YLUb>vaO7@_4=Dr^- z&h0l{T|gE3Hw~HN&|f2cgEzi7w?)L*atLiVCP%hDy4+YX7<6A$s#k7vc`k!S)Oljl zwudhk{4ouw76yLtUrkCrDE2-nOEfg(oY8hYY0C@3x*?M;PFw_Av5KJ7I#xYjdK;lw;L012)Ay<{Kp?&I-_H z_Q;cr1Ip=}9KfKN$xXChXMTgtuR zC{Y6O5EG^R^Wnlv%_w%}KbfgaHIT%Lu;^o% z0(uBXY;`n;^h3pyn=!2Wt&x83)=wJ$rV$Yp8jN-Jr{B{{4gYxNFL2)QIB9H1m$dbe zb@pTd?`$DcY5~)DEL=^L?9$nZM|URBJL0DpbjNuIFH2QKmzz*};c#rXnMCRxcFs4_ zps6-;4tfen;dne}^_N#Eg}5>cDQBJh-WQKv--+9;)J_S{f`xd=38ru$>|XV@f_b>F8!k6AkJ9$ifj|Gv>+Z5UI4`5;wINhdQK+iMw+|M^FP2dv;DP7oL$xmd235i_i9)EvdsB~r3m12Bc z+k_*=RoI^CbpL~LiUa{MdCi;e7{7x85!M$mUr&4wPd?}GXT;r!Q`l{FZwel|&Cf4- zT#w0g5ma~l=Q7XRt#MN#=vr7Et(!$Aex={{$M~fFL^8%z)|@cF%=L0Z&&Q7UhA`0N zgiE^$gyZ^i@40Ez#)bR)75Dw=C8_o}=-u4z@bt$-1qj_qbW;o5c>S+@_9I_k->q@D ze-OPNMM8JmM7ae=q%UNSh`u}}a%{70+sz;@*{Ij7+3Rd2fn1U9&go5M_@wbf@}~a} z+P;wz`yFO@WBGY`a?qm!gY4qsh`c;DyQZsS0&}7F@()AXPFIDSI_WQ)=|8r=6`>&p zmz=xWarfM=9IHNCO~$|bUkb!GDbnvSb8Dg;9i6dT1FxI|1cB2fsp};s6FYJ#ta6EW zZaW<d8}R8||w_v&nnDMP`O1sdko_MmlYs!UUAfhzZb zS>3m8<{<;010xV%KCFz5PnZYY&Cmt*X67_fHj%a?Wq*aBe#gdaoZ}{KSo4BnyD~4IguIvrqoz6-s7GoS^qel0(K=aR zbR@$iYH#2Jvxy^NZqVweo7HO$tWnNm#w7sx-n`2x2eZqll9DW~SjW_-n3$huDk`@% zFXZH9$4%zny5EtrNJtd&k=7K&H-LVEB_-BP(I>_}$DXxe%e@QQ?7UO}tNE_u%)64T%KRZ5arex7R(wK9{{zb7tTsHI8}M z&YV-qYx&tK6E39N7#%0a$H(`YF9u1TpAAk?m5CW?Q5*`(X1<@4)9$5c`+|~E#`E9s zNFY2!^tlP?T`Q_T_dVi^V!DSFWuO0QWVb5#FP5w!=cj`Dt@QOpdAG;z)S!5U{9C(zE^#>3n#-Ko-LJ6DbTkL)iXl)35YIs5*& zUDDj`Zy93cMg6W@=m-5ykkvI4Es8=auC@$Cy+nU}zG0xi5sB>>q2h5DI|-Zfy(YDj z9jKDVhZ&h#q?I~)Pfr;aYGwbUBVSJh^5ln3pp!pQMk7y}OvA$WBEYu#^XEbqau}lp z?z)vVqp0L7&Zz9#;@j%-YN~b{)&>2e*?!l;3+^R~_xlx@{VkI`Bv!TvLg}$WTEQZ? zU8xW7h-v;zr`v!mhQmv+8)19Xv?r#M=wOJHc&(u^_AOcD@aSl7SWN|Pf+XH)yx4KC zUzBoR3Ifc=%tuJSo8hvD^JKr@v+jcLc_ATD|8zzJ5Rq%pX-fg*`ty<3YmuL=tQJ8L zcWG@P6SypfgvaxJB&tn^**qV>cv^fr6F9}(`DhgwM}w%}c9uh-Ip)4q_$+;?fqyy} zORaNVp0>H}5-ab7qv;Yz%F?bJK9Of7IXZf}iDVx1Z^4+9|HG-%rcAEa@y?dnFusiZMQ z`{1!||15fzz`5bULAQA);xGh{zPqaVb@w)QaEwa=i>^ZbbJMAx%|M3EY8+IRpGpi` zA)p#O66koJPrY?qo8O!*_dF46zR=1^j|F(D_*|d!4yv*xK)?JC5$b}Hzl2b)%XzIR z!DDZ%B%KPei!?aB`wBf$BW!whT&^m}ktMRBoO8J3#Z&twI+J$YW1f3n zp>#ZA$6&{%MRQSCp0h#_^1Ivjb`^(sGr_eR?yH=&P{2*bl_Be0h%rQ*~-E zz8IFZS})R=zLS9DT|4Tu{Uk_H$R1)59j`>Q=7Ds;KbP z^#yp%f=Vd2*UM_lBp@x*|43eaBQtQEtr@%4%WG37W^ApjigpYe+bn8TX(~b^>zr7= zbATD>N*ms6crt7OQ`>&RN&lB(8Os!z(i}|D4ENPs+Z|MPg!gy+|Lco0jx%^wV|Na8 z^R-@ivVS?+>1lg(^FP&$3g4#Ms=TiB5_p=^U&Z*y$$e1}Ep-(am=fol-XD5*!rX zo&y2Zka0xA@)c_)GhpBAA`WI&EQ?vp9Ov`NW{xTQh=RSVcBnj<2wMP=KyE*Sz>)U- zft`XB>~0lUxnfNS%)-ej+LRCfCF|pi;^LhQC;Q18T|ovwfB7>HEtvrMRQBy#xUCKt zq+M)+v2sZ6GzDyEAXS|UMwn2_8Jd_# z2{0&e(4D3^6$mW%BRkhbu@S{MA{?B9umkqT_rXZ`dVQX3)!^6Zw^FE+7F@*OoS`4t zD}M_&^Adh*p7&&V0~l!I;}k%@0;V3CjcFC*E%{W8zIpx-T$?z^AN2Gn3z)xG7lR%0 z^7aOLpgf;OrbqaXg6|e+l(cUiH7@-GGiY`%t_T|M6blEue#P8^zo#>=M_^Yu8Ws`3 z$Issq&!yuamfF+PyE(y9nMK2G)c+#3lIOGqf=+&puF3T(_829sL_9E1)6JeU$EnaN1L`uEq*lwpwGj*ffa&fhWq z1JaO!PemCBMEpng03!-u(8gM1dmbqOq<$*W2JDBw0!qv*ER=L~%yf}UZgt>Y0v|Or zNbd(w021HkQJHx!6<;DDVAh-2*o5WeFarrK;IXu~%T|m6ZAC;vZ>%afSjKP)@D_%z zx9qBtZG;r~5*g_tO_G?wVFB+?LoPi_RQxpAF3>AaQq{czy0=6nW8I1T7GxEA>~a5= z_H@T2XUVnj*U3q3ut- z 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 TzcU`e1yGWrav~){`hNch+ep}d diff --git a/2-ui/1-document/02-dom-nodes/domconsole1.svg b/2-ui/1-document/02-dom-nodes/domconsole1.svg new file mode 100644 index 000000000..db92359d5 --- /dev/null +++ b/2-ui/1-document/02-dom-nodes/domconsole1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/2-ui/1-document/02-dom-nodes/domconsole1@2x.png b/2-ui/1-document/02-dom-nodes/domconsole1@2x.png deleted file mode 100644 index ce0fa0fffa5b3566bcb60852a77fb77f7ddd4752..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141140 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