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 600de1fb3..e45060b38 100644 --- a/1-js/03-code-quality/01-debugging-chrome/article.md +++ b/1-js/03-code-quality/01-debugging-chrome/article.md @@ -2,19 +2,13 @@ Antes de escrevermos código mais complexo, vamos falar de debugging (depuração de erros). -<<<<<<< HEAD -[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) 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 exactamente o que está a ser executado. +[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. -Aqui, vamos utilizar o Chrome porque tem bastantes funcionalidades, mas a maioria dos outros navegadores possuem um processo similar. -======= -[Debugging](https://en.wikipedia.org/wiki/Debugging) is the process of finding and fixing errors within a script. All modern browsers and most other environments support debugging tools -- a special UI in developer tools that makes debugging much easier. It also allows to trace the code step by step to see what exactly is going on. - -We'll be using Chrome here, because it has enough features, most other browsers have a similar process. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +Aqui, vamos utilizar o Chrome porque tem muitas funcionalidades, mas a maioria dos outros navegadores possuem um processo similar. ## O painel "*Sources*" -A versão do seu Chrome pode parecer um pouco diferente, mas ainda assim deveria ser óbvio o que lá encontre. +A versão do seu Chrome pode parecer um pouco diferente, mas ainda assim deverá ser óbvio o que lá encontre. - Abra a [página exemplo](debugging/index.html) no Chrome. - Ative as ferramentas do desenvolvedor com `key:F12` (Mac: `key:Cmd+Opt+I`). @@ -24,17 +18,12 @@ Aqui está o que poderá ver, se o estiver a fazer pela primeira vez: ![](chrome-open-sources.svg) -<<<<<<< HEAD O botão de alternador abre o separador com os ficheiros. -======= -The toggler button opens the tab with files. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 -Vamos clicar nele, e selecionar `hello.js` na vista de árvore de recursos apresentada. Aqui está o que deveria ser mostrado: +Vamos clicar nele, e selecionar `hello.js` na vista de árvore de recursos apresentada. Aqui está o que deveria ser mostrado: ![](chrome-tabs.svg) -<<<<<<< HEAD O painel *Sources* possui 3 partes: 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. @@ -42,15 +31,6 @@ O painel *Sources* possui 3 partes: 3. O painel **JavaScript Debugging**, é para a depuração de erros; iremos explorá-lo em breve. Agora, poderia clicar novamente no mesmo botão de alternador para ocultar a lista de recursos e dar ao código algum espaço. -======= -The Sources panel has 3 parts: - -1. The **File Navigator** pane lists HTML, JavaScript, CSS and other files, including images that are attached to the page. Chrome extensions may appear here too. -2. The **Code Editor** pane shows the source code. -3. The **JavaScript Debugging** pane is for debugging, we'll explore it soon. - -Now you could click the same toggler again to hide the resources list and give the code some space. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## Console @@ -66,32 +46,31 @@ Por exemplo, aqui `1+2` resulta em `3`, e `hello("debugger")` não retorna nada, 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. -Parabéns! Estabeleceu um ponto-de-interrupção (*breakpoint*). Por favor, clique também no número de linha `8`. +Parabéns! Você estabeleceu um ponto-de-interrupção (*breakpoint*). Por favor, clique também no número de linha `8`. Deveria se parecer com (a azul é onde deveria ter clicado): ![](chrome-sources-breakpoint.svg) -Um *breakpoint* é um ponto no código onde o *debugger* (depurador de erros) irá automáticamente efetuar uma pausa na execução do JavaScript. +Um *breakpoint* é um ponto no código onde o *debugger* (depurador de erros) irá automáticamente fazer uma pausa na execução do JavaScript. 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*). 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="*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. +*Clicando com o botão direito do rato* sobre um número de linha nos permite criar um *breakpoint condicional*. Apenas será ativado quando a expressão inserida for verdadeira. É prático quando apenas precisarmos de parar para um certo valor numa variável, ou para certos parâmetros numa função. ``` ## O comando *debugger* -Podemos também suspender o código utilizando o comando `debugger`, desta forma: +Podemos também pausar o código utilizando o comando `debugger`, desta forma: ```js function hello(name) { @@ -107,9 +86,10 @@ function hello(name) { É 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 e dê uma vista de olhos -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*) é refrescar (*reload*) a página. Assim, vamos pressionar `key:F5` (Windows, Linux) ou `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). Como o breakpoint está estabelecido, é feita uma pausa na execução na quarta linha: @@ -119,17 +99,16 @@ Por favor, abra as secções de dropdown informacionais à direita (possuem etiq 1. **`Watch` -- mostra valores correntes de expressões.** - Pode clicar no mais `+` e inserir uma expressão. O *debugger* mostrará o seu valor em qualquer momento, e é automáticamente recalculado ao longo do processo de execução. + Pode clicar no mais `+` e inserir uma expressão. O *debugger* mostrará o seu valor em qualquer altura, e é automáticamente recalculado ao longo do processo de execução. 2. **`Call Stack` -- mostra a sequência de chamadas de funções aninhadas.** - 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*"). + 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"]). 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` mostra variáveis locais de funções. Também, poderá ver os seus valores em destaque exatamente sobre o código-fonte. + `Local` mostra variáveis locais de funções. Também, poderá ver os seus valores destacados exatamente sobre o código-fonte. `Global` possui variáveis globais (aquelas fora de qualquer função). @@ -140,7 +119,7 @@ Por favor, abra as secções de dropdown informacionais à direita (possuem etiq Agora, é altura para *rastrearmos* (*trace*) o código. 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. @@ -148,72 +127,35 @@ Existem botões para isso no topo do painel direito. Vamos interagir com eles. ![](chrome-sources-debugger-trace-1.svg) - A execução prosseguiu, atingiu outro *breakpoint* dentro de `say()` e foi suspensa lá. Dê uma vista de olhos sobre a "*Call stack*" à direita. Aumentou por mais uma chamada. Estamos dentro de `say()` agora. + 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. -<<<<<<< HEAD - Continuando a clicar nele, passará por todas as instruções do programa, uma por uma. + Clicando repetidamente irá percorrer todas as instruções do *script*, uma a 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. -======= -There are buttons for it at the top of the right panel. Let's engage them. - - -- "Resume": 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +: Similar ao comando "Step" anterior, mas com um comportamento diferente se a instrução seguinte 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. + O comando "Step" vai para dentro dela e pausa a execução na sua primeira linha, enquanto "Step over" executa a chamada de função invisivelmente, saltando o interior da função. - É feita uma pausa na execução imediatemente depois dessa função. + A execução faz depois uma pausa imediatamente depois da função. - É bom, se não estivermos interessados em ver o que acontece dentro da chamada de função. + Isto, é bom se você não estiver interessado em ver o que acontece dentro da função. -<<<<<<< HEAD -- "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. +: É similar a "Step", mas com um comportamento diferente no caso de chamadas de funções assíncronas. Se você estiver a começar a aprender JavaScript, então pode ignorar a diferença, porque ainda não temos chamadas assíncronas. - Futuramente, 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 do seu código, 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). + Futuramente, 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 do seu código, 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). -- "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. +: Continua a execução e faz 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. -- ative/desative todos os *breakpoints*. : Esse botão não move a execução. Simplesmente liga/desliga *breakpoints* em grupo. -- ative/desative a pausa automática em caso de erro. -: Quando ativo, e as ferramentas do desenvolvedor estão abertas, um erro no código automáticamente suspende a sua execução. Então, poderemos analizar 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 refrescar a página, afim de se observar onde falhou e qual o contexto nesse momento. -======= - -- "Step": run the next command, hotkey `key:F9`. -: Run the next statement. If we click it now, `alert` will be shown. - - Clicking this again and again will step through all script statements one by one. - - -- "Step over": run the next command, but *don't go into a function*, hotkey `key:F10`. -: Similar to the previous the "Step" command, but behaves differently if the next statement is a function call. That is: not a built-in, like `alert`, but a function of our own. - - The "Step" command goes into it and pauses the execution at its first line, while "Step over" executes the nested function call invisibly, skipping the function internals. - - The execution is then paused immediately after that function. - - That's good if we're not interested to see what happens inside the function call. - - -- "Step into", hotkey `key:F11`. -: That's similar to "Step", but behaves differently in case of asynchronous function calls. If you're only starting to learn JavaScript, then you can ignore the difference, as we don't have asynchronous calls yet. - - For the future, just note that "Step" command ignores async actions, such as `setTimeout` (scheduled function call), that execute later. The "Step into" goes into their code, waiting for them if necessary. See [DevTools manual](https://developers.google.com/web/updates/2018/01/devtools#async) for more details. - - -- "Step out": continue the execution till the end of the current function, hotkey `key:Shift+F11`. -: Continue the execution and stop it 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. - - -- enable/disable all breakpoints. -: That button does not move the execution. Just a mass on/off for breakpoints. - - -- 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +: Quando ativo, e as ferramentas do desenvolvedor estiverem abertas, um erro no código automáticamente pausa 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, podemos abrir o *debugger*, ativar esta opção e recarregar a página, afim de vermos onde falhou e qual o contexto nesse momento. ```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*). @@ -223,7 +165,7 @@ Ao clicar com o botão direito do rato sobre uma linha de código, abre-se o men ## Logging -Para mostrar algo existente no código na consola, existe a função `console.log`. +Para mostrar na consola algo existente no código, existe a função `console.log`. Por exemplo, isto mostra os valores de `0` a `4` na consola: @@ -234,28 +176,21 @@ for (let i = 0; i < 5; i++) { } ``` -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. +Utilizadores comuns não vêm essa saída (*output*), ela está 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 embaixo nesse separador. -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*. +Se tivermos mensagens (*logging*) suficientes no nosso código, então poderemos ver o que nele se passa a partir desses registos, dispensando o *debugger*. ## Resumo -<<<<<<< HEAD -Como podemos ver, existem três formas principais para efetuar uma pausa num *script*: +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"). -======= -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"). ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Enquanto suspenso, podemos depurar erros - examinar variáveis e rastear o código para ver onde a sua execução contém erros. -Existem muitas mais opções nas ferramentas do desenvolvedor do que as cobertas aqui. O manual completo está em (no topo, à direita, poderá escolher o idioma). +Existem muitas mais opções nas ferramentas do desenvolvedor do que as cobertas aqui. O manual completo está em . -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. +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, por favor consulte o manual e procure por funcionalidades mais avançadas nas ferramentas do desenvolvedor. 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/02-coding-style/1-style-errors/solution.md b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md index 81e12209d..f9b6ef964 100644 --- a/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md +++ b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md @@ -10,21 +10,12 @@ function pow(x,n) // <- nenhum espaço entre argumentos return result; } -<<<<<<< HEAD let x=prompt("x?",''), n=prompt("n?",'') // <-- tecnicamente possível, -// mas o melhor é torná-la em 2 linhas, também não existem espaços, e falta o ; +// mas o melhor é a tornar em 2 linhas, também não existem espaços, e falta o ; if (n<0) // <- nenhum espaço dentro (n < 0), e deveria existir uma linha extra sobre a condição { // <- chaveta de abertura numa linha em separado // abaixo - linhas longas podem ser repartidas por múltiplas linhas para melhorar a legíbilidade alert(`A potência de ${n} não é suportada, por favor insira um número inteiro maior do que zero`); -======= -let x=prompt("x?",''), n=prompt("n?",'') // <-- technically possible, -// but better make it 2 lines, also there's no spaces and missing ; -if (n<=0) // <- no spaces inside (n <= 0), and should be extra line above it -{ // <- figure bracket on a separate line - // below - long lines can be split into multiple lines for improved readability - alert(`Power ${n} is not supported, please enter an integer number greater than zero`); ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 } else // <- poderia ser escrito numa única linha, como "} else {" { @@ -48,14 +39,8 @@ function pow(x, n) { let x = prompt("x?", ""); let n = prompt("n?", ""); -<<<<<<< HEAD if (n < 0) { alert(`A potência de ${n} não é suportada, por favor insira um número inteiro maior do que zero`); -======= -if (n <= 0) { - alert(`Power ${n} is not supported, - please enter an integer number greater than zero`); ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 } else { alert( pow(x, n) ); } diff --git a/1-js/03-code-quality/02-coding-style/article.md b/1-js/03-code-quality/02-coding-style/article.md index e66aa3a93..3c3af6416 100644 --- a/1-js/03-code-quality/02-coding-style/article.md +++ b/1-js/03-code-quality/02-coding-style/article.md @@ -25,13 +25,8 @@ let x = prompt("x?", ""); let n = prompt("n?", ""); if (n < 0) { -<<<<<<< HEAD alert(`A potência de ${n} não é suportada, por favor insira um número inteiro positivo`); -======= - alert(`Power ${n} is not supported, - please enter a non-negative integer number`); ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 } else { alert( pow(x, n) ); } @@ -92,14 +87,7 @@ Por exemplo: ```js // o acento grave (*backtick*) ` permite repartir uma *string* por múltiplas linhas let str = ` -<<<<<<< HEAD - O TC39 da ECMA International, é um grupo de desenvolvedores e implementadores de JavaScript, académicos, e outros, colaborando com a comunidade para manter e - evoluir a definição de JavaScript. -======= - ECMA International's TC39 is a group of JavaScript developers, - implementers, academics, and more, collaborating with the community - to maintain and evolve the definition of JavaScript. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 + O TC39 da ECMA International, é um grupo de desenvolvedores e implementadores de JavaScript, académicos, e outros, colaborando com a comunidade para manter e evoluir a definição de JavaScript. `; ``` diff --git a/1-js/03-code-quality/03-comments/article.md b/1-js/03-code-quality/03-comments/article.md index 5742815a2..a60cb3da1 100644 --- a/1-js/03-code-quality/03-comments/article.md +++ b/1-js/03-code-quality/03-comments/article.md @@ -124,7 +124,6 @@ Descreva a arquitetura Documente os parâmetros e o uso da função : Existe uma sintaxe especial, [JSDoc](http://en.wikipedia.org/wiki/JSDoc), para documentar uma função: o seu uso, parâmetros, e valor retornado. -<<<<<<< HEAD Por exemplo: ```js @@ -134,35 +133,17 @@ Por exemplo: * @param {number} x O número a elevar. * @param {number} n A potência, deve ser um número natural. * @return {number} x elevado à n-ésima potência. -======= -For instance: -```js -/** - * Returns x raised to the n-th power. - * - * @param {number} x The number to raise. - * @param {number} n The power, must be a natural number. - * @return {number} x raised to the n-th power. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 */ function pow(x, n) { ... } ``` -<<<<<<< HEAD Tais comentários, nos permitem compreender o propósito da função e a usar de forma correta, sem olhar para o seu código. A propósito, muitos editores, como o [WebStorm](https://www.jetbrains.com/webstorm/, podem também os perceber e os usar para fornecer completação automática de palavras (*autocomplete*), e algumas verificações de código (*code-checking*) automáticas. Também, existem ferramentas como o [JSDoc 3](https://github.com/jsdoc3/jsdoc), que podem gerar documentação HTML a partir de comentários. Pode ler mais informação sobre o JSDoc em . -======= -Such comments allow us to understand the purpose of the function and use it the right way without looking in its code. - -By the way, many editors like [WebStorm](https://www.jetbrains.com/webstorm/) can understand them as well and use them to provide autocomplete and some automatic code-checking. - -Also, there are tools like [JSDoc 3](https://github.com/jsdoc3/jsdoc) that can generate HTML-documentation from the comments. You can read more information about JSDoc at . ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Porque é a tarefa solucionada dessa forma? : O que está escrito é importante. Mas, o que *não* está escrito pode ser ainda mais importante, para se compreender o que se passa. Porque é a tarefa solucionada exatamente dessa forma? O código não dá resposta alguma. @@ -193,12 +174,7 @@ Bons comentários, nos permitem manter o código saudável, voltar a ele após u **Evite comentários:** -<<<<<<< HEAD - Que digam "como o código funciona" e "o que faz". - Coloque-os apenas se for impossível tornar o código tão simples e auto-descritivo que não precise deles. -======= -- That tell "how code works" and "what it does". -- Put them in only if it's impossible to make the code so simple and self-descriptive that it doesn't require them. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Comentários também são utilizados por ferramentas de auto-documentação, como o JSDoc3: elas os lêm e geram documentos em HTML (ou documentos num outro formato). diff --git a/1-js/03-code-quality/05-testing-mocha/article.md b/1-js/03-code-quality/05-testing-mocha/article.md index 3b2154c75..e5a3ab6b4 100644 --- a/1-js/03-code-quality/05-testing-mocha/article.md +++ b/1-js/03-code-quality/05-testing-mocha/article.md @@ -1,8 +1,4 @@ -<<<<<<< HEAD # Teste automatizado com mocha -======= -# Automated testing with Mocha ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Teste automatizado será utilizado nos exercícios seguintes, e também é amplamente usado em projetos reais. @@ -85,11 +81,7 @@ Assim, o desenvolvimento é *iterativo*. Nós escrevemos a *spec*, a implementam Vejamos este fluxo de desenvolvimento no nosso caso prático. -<<<<<<< HEAD O primeiro passo já está completo: nós temos uma *spec* inicial para `pow`. Agora, antes de fazer a implementação, vamos utilizar umas poucas bibliotecas (*libraries*) de JavaScript para executar os testes, apenas para ver se eles estão a funcionar (todos irão falhar). -======= -The first step is already complete: we have an initial spec for `pow`. Now, before making the implementation, let's use few JavaScript libraries to run the tests, just to see that they are working (they will all fail). ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## A *spec* em ação @@ -171,13 +163,8 @@ Aqui, nós podemos selecionar uma das duas formas para organizar o teste: assert.equal(pow(2, 3), 8); }); -<<<<<<< HEAD - it("3 elevado a 3 é 27", function() { - assert.equal(pow(3, 3), 27); -======= - it("3 raised to power 4 is 81", function() { + it("3 elevado a 4 é 81", function() { assert.equal(pow(3, 4), 81); ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 }); }); @@ -199,11 +186,7 @@ O resultado: [iframe height=250 src="pow-2" edit border="1"] -<<<<<<< HEAD -Como nós esperávamos, o segundo teste falhou. Seguramente, a nossa função retorna sempre `8`, enquanto o `assert` espera `27`. -======= -As we could expect, the second test failed. Sure, our function always returns `8`, while the `assert` expects `81`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +Como nós esperávamos, o segundo teste falhou. Seguramente, a nossa função retorna sempre `8`, enquanto o `assert` espera `81`. ## Melhorando a implementação 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 52101bcef..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,20 +1,12 @@ -<<<<<<< HEAD describe("teste", function() { + // Mocha, geralmente espera pelos testes por 2 segundos antes de os considerar errados - before(() => alert("Testes iniciados – antes de todos os testes")); - after(() => alert("Testes terminados – depois de todos os testes")); -======= -describe("test", function() { - - // Mocha usually waits for the tests for 2 seconds before considering them wrong + this.timeout(200000); // Com este código nós aumentamos esse tempo - neste caso, para 200,000 - this.timeout(200000); // With this code we increase this - in this case to 200,000 milliseconds + // 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! - // This is because of the "alert" function, because if you delay pressing the "OK" button the tests will not pass! - - before(() => alert("Testing started – before all tests")); - after(() => alert("Testing finished – after all tests")); ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 + before(() => alert("Testes iniciados – antes de todos os testes")); + after(() => alert("Testes terminados – depois de todos os testes")); beforeEach(() => alert("antes de um teste – entrando para um teste")); afterEach(() => alert("depois de um teste – saindo de um teste")); 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 9ea927fb3..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 @@ -4,13 +4,8 @@ describe("pow", function() { assert.equal(pow(2, 3), 8); }); -<<<<<<< HEAD - it("3 elevado à potência 3 é 27", function() { - assert.equal(pow(3, 3), 27); -======= - it("3 raised to power 4 is 81", function() { + it("3 elevado à potência 4 é 81", function() { assert.equal(pow(3, 4), 81); ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 }); }); diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md index 923848ce9..d2522f142 100644 --- a/1-js/03-code-quality/06-polyfills/article.md +++ b/1-js/03-code-quality/06-polyfills/article.md @@ -19,11 +19,7 @@ Here Babel comes to the rescue. Actually, there are two parts in Babel: -<<<<<<< HEAD -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. -======= 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 systems like [webpack](http://webpack.github.io/) provide means to run transpiler automatically on every code change, so that it's very easy to integrate into development process. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 2. Second, the polyfill. 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 8b8ea204c..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,40 +1 @@ -<<<<<<< HEAD - - - - object-user-delete.svg - Created with sketchtool. - - - - - - - - - - - name - - - - - - - - - isAdmin - - - - - - user - - - - - -======= -nameisAdminuser ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 38b952ad4..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,25 +1 @@ -<<<<<<< HEAD - - - - object-user-empty.svg - Created with sketchtool. - - - - - - - - empty - - - user - - - - - -======= -emptyuser ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 d974c1f06..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,49 +1 @@ -<<<<<<< HEAD - - - - object-user-isadmin.svg - Created with sketchtool. - - - - - - - - - - - name - - - - - - - - - age - - - - - - - - - isAdmin - - - - - - user - - - - - -======= -nameageisAdminuser ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 f9083ad40..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,49 +1 @@ -<<<<<<< HEAD - - - - object-user-props.svg - Created with sketchtool. - - - - - - - - - - - name - - - - - - - - - age - - - - - - - - - likes birds - - - - - - user - - - - - -======= -nameagelikes birdsuser ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 48fceab91..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,40 +1 @@ -<<<<<<< HEAD - - - - object-user.svg - Created with sketchtool. - - - - - - - - - - - name - - - - - - - - - age - - - - - - user - - - - - -======= -nameageuser ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +nameageuser \ 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 c178557e2..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,216 +1 @@ -<<<<<<< HEAD - - - - garbage-collection-5.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <global> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - unreachables - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -======= -<global>unreachables ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +<global>unreachables \ No newline at end of file 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 cb3988180..a20ad4480 100644 --- a/1-js/04-object-basics/07-optional-chaining/article.md +++ b/1-js/04-object-basics/07-optional-chaining/article.md @@ -9,9 +9,11 @@ The optional chaining `?.` is a safe way to access nested object properties, eve 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. -As an example, consider objects for user data. Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them. +As an example, let's say we have `user` objects that hold the information about our users. -In such case, when we attempt to get `user.address.street`, we may get an error: +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 = {}; // a user without "address" property @@ -19,20 +21,22 @@ let user = {}; // a user without "address" property alert(user.address.street); // Error! ``` -That's the expected result, JavaScript works like this. As `user.address` is `undefined`, the attempt to get `user.address.street` fails with an error. Although, in many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street"). +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 may need the information about an element on the page. The element is returned by `document.querySelector('.elem')`, and the catch is again - that it sometimes doesn't exist: +...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 -// the result of the call document.querySelector('.elem') may be an object or null +// document.querySelector('.elem') is null if there's no element let html = document.querySelector('.elem').innerHTML; // error if it's null ``` -Once again, we may want to avoid the error in such case. +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. How can we do this? -The obvious solution would be to check the value using `if` or the conditional operator `?`, before accessing it, like 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 = {}; @@ -40,7 +44,7 @@ let user = {}; alert(user.address ? user.address.street : undefined); ``` -...But that's quite inelegant. As you can see, the `user.address` is duplicated in the code. For more deeply nested properties, that becomes a problem. +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`. @@ -52,9 +56,9 @@ let user = {}; // user has no address alert(user.address ? user.address.street ? user.address.street.name : null : null); ``` -That looks awful. +That's just awful, one may even have problems understanding such code. -Before the optional chaining `?.` was added to the language, people used the `&&` operator for such cases: +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 @@ -64,16 +68,20 @@ alert( user.address && user.address.street && user.address.street.name ); // und 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, the property names are still duplicated in the code. E.g. in the code above, `user.address` appears three times. +As you can see, property names are still duplicated in the code. E.g. in the code above, `user.address` appears three times. -And now, finally, the optional chaining comes to the rescue! +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`.** +In other words, `value?.prop`: +- is the same as `value.prop` if `value` exists, +- otherwise (when `value` is `undefined/null`) it returns that `value`. + Here's the safe way to access `user.address.street` using `?.`: ```js run @@ -95,9 +103,7 @@ alert( user?.address.street ); // undefined Please note: the `?.` syntax makes optional the value before it, but not any further. -In the example above, `user?.address.street` allows only `user` to be `null/undefined`. - -On the other hand, if `user` does exist, then it must have `user.address` property, otherwise `user?.address.street` gives an error at the second dot. +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. @@ -143,17 +149,20 @@ 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 userGuest = {}; -let user2 = {}; +*!* +userAdmin.admin?.(); // I am admin +*/!* *!* -user1.admin?.(); // I am admin -user2.admin?.(); +userGuest.admin?.(); // nothing (no such method) */!* ``` diff --git a/1-js/04-object-basics/08-symbol/article.md b/1-js/04-object-basics/08-symbol/article.md index e2c9e06a2..17e73ba50 100644 --- a/1-js/04-object-basics/08-symbol/article.md +++ b/1-js/04-object-basics/08-symbol/article.md @@ -74,13 +74,9 @@ alert(id.description); // id 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,11 +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"`? -<<<<<<< HEAD:1-js/04-object-basics/08-symbol/article.md -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3:1-js/04-object-basics/08-symbol/article.md 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. @@ -271,11 +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. -<<<<<<< HEAD:1-js/04-object-basics/08-symbol/article.md - 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3:1-js/04-object-basics/08-symbol/article.md 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 fade3fe27..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,13 +52,9 @@ There are three variants: `"default"` : Occurs in rare cases when the operator is "not sure" what type to expect. -<<<<<<< HEAD:1-js/04-object-basics/09-object-toprimitive/article.md - 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3:1-js/04-object-basics/09-object-toprimitive/article.md ```js // binary plus uses the "default" hint @@ -204,16 +200,6 @@ An operation that initiated the conversion gets that primitive, and then continu For instance: -<<<<<<< HEAD:1-js/04-object-basics/09-object-toprimitive/article.md -- Mathematical operations (except binary plus) perform `ToNumber` conversion: - - ```js run - let obj = { - toString() { // toString handles all conversions in the absence of other methods - return "2"; - } - }; -======= ## Further conversions As we know already, many operators and functions perform type conversions, e.g. multiplication `*` converts operands to numbers. @@ -221,36 +207,10 @@ As we know already, many operators and functions perform type conversions, e.g. 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3:1-js/04-object-basics/09-object-toprimitive/article.md alert(obj * 2); // 4, ToPrimitive gives "2", then it becomes 2 ``` -<<<<<<< HEAD:1-js/04-object-basics/09-object-toprimitive/article.md -- Binary plus checks the primitive -- if it's a string, then it does concatenation, otherwise it performs `ToNumber` and works with numbers. - - String example: - ```js run - let obj = { - toString() { - return "2"; - } - }; - - alert(obj + 2); // 22 (ToPrimitive returned string => concatenation) - ``` - - Number example: - ```js run - let obj = { - toString() { - return true; - } - }; - - alert(obj + 2); // 3 (ToPrimitive returned boolean, not string => ToNumber) - ``` -======= ```js run let obj = { // toString handles all conversions in the absence of other methods @@ -276,7 +236,6 @@ let obj = { alert(obj + 2); // 22 ("2" + 2), conversion to primitive returned a string => concatenation ``` ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3:1-js/04-object-basics/09-object-toprimitive/article.md ```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 bbe8429a3..0c3a78299 100644 --- a/1-js/05-data-types/01-primitives-methods/article.md +++ b/1-js/05-data-types/01-primitives-methods/article.md @@ -6,15 +6,10 @@ Eles também fornecem métodos para chamar como se fossem objetos. Estudaremos i Vejamos as principais diferenças entre primitivos e objetos. -<<<<<<< HEAD Um primitivo -======= -- Is a value of a primitive type. -- There are 7 primitive types: `string`, `number`, `bigint`, `boolean`, `symbol`, `null` and `undefined`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 - É 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 @@ -57,11 +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. -<<<<<<< HEAD -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. -======= -For instance, there exists a string method [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) that returns a capitalized `str`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 e6c1e0f21..4ffbd8a6f 100644 --- a/1-js/05-data-types/02-number/article.md +++ b/1-js/05-data-types/02-number/article.md @@ -1,10 +1,5 @@ # Numbers -<<<<<<< HEAD -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". - -Let's recap and expand upon what we currently know about them. -======= In modern JavaScript, there are two types of numbers: 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. @@ -12,7 +7,6 @@ In modern JavaScript, there are two types of numbers: 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## More ways to write a number 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 9071a4936..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,68 +1 @@ -<<<<<<< HEAD - - - - 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 - - - - -======= -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 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 7e2147835..be10b01b7 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -142,13 +142,7 @@ for (let char of str) { 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. -<<<<<<< HEAD -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": ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run let str = "Hello"; @@ -233,11 +227,7 @@ The full syntax for `Array.from` also allows us to provide an optional "mapping" Array.from(obj[, mapFn, thisArg]) ``` -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For instance: 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 a3eb015ed..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 @@ -63,13 +63,6 @@ for (let value of Object.values(user)) { } ``` -<<<<<<< HEAD -## 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. -======= ```warn header="Object.keys/values/entries ignore symbolic properties" Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys. @@ -107,4 +100,3 @@ 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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 c27541507..81c8a53a2 100644 --- a/1-js/05-data-types/10-destructuring-assignment/article.md +++ b/1-js/05-data-types/10-destructuring-assignment/article.md @@ -356,13 +356,9 @@ The problem is that JavaScript treats `{...}` in the main code flow (not inside } ``` -<<<<<<< HEAD -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 `(...)`: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run let title, width, height; @@ -408,13 +404,7 @@ alert(item1); // Cake alert(item2); // Donut ``` -<<<<<<< HEAD -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: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ![](destructuring-complex.svg) @@ -445,10 +435,7 @@ In real-life, the problem is how to remember the order of arguments. Usually IDE Like this? ```js -<<<<<<< HEAD -======= // undefined where default values are fine ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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 3342d43a8..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,63 +1 @@ -<<<<<<< HEAD - - - - destructuring-complex.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -======= - ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 + \ No newline at end of file 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 6b2b87258..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,10 +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" -<<<<<<< HEAD -// yesterday's date like 31.12.2016, 20:00 -======= // yesterday's date like 31.12.16 20:00 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 alert( formatDate(new Date(new Date - 86400 * 1000)) ); ``` diff --git a/1-js/05-data-types/12-json/article.md b/1-js/05-data-types/12-json/article.md index 7dd2d7e64..1867ebc92 100644 --- a/1-js/05-data-types/12-json/article.md +++ b/1-js/05-data-types/12-json/article.md @@ -393,11 +393,7 @@ alert( JSON.stringify(meetup) ); */ ``` -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## JSON.parse 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 c9420b87f..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,39 +1 @@ -<<<<<<< HEAD - - - - json-meetup.svg - Created with sketchtool. - - - - - number: 23 - - - - title: "Conference" - - - - ... - - - place - - - - - occupiedBy - - - - participants - - - - - -======= -number: 23title: "Conference"...placeoccupiedByparticipants ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +number: 23title: "Conference"...placeoccupiedByparticipants \ No newline at end of file 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 f7c31447b..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,76 +1 @@ -<<<<<<< HEAD - - - - 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) - - - - -======= -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) ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 4801af984..97bb2bc9c 100644 --- a/1-js/06-advanced-functions/01-recursion/article.md +++ b/1-js/06-advanced-functions/01-recursion/article.md @@ -343,11 +343,7 @@ 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. -<<<<<<< HEAD -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). ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 The algorithm is probably even easier to read from the code: 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 a9f4a62e6..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,75 +1 @@ -<<<<<<< HEAD - - - - 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 - - - - -======= -value1nextvalue"new item"nextvalue2nextvalue3nextvalue4nextnulllist ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 2483d75f9..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,75 +1 @@ -<<<<<<< HEAD - - - - 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 - - - - -======= -value"new item"nextvalue1nextvalue2nextvalue3nextvalue4nextnulllist ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 95ddccbc4..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,70 +1 @@ -<<<<<<< HEAD - - - - linked-list-split.svg - Created with sketchtool. - - - - - value - - - 1 - - - - next - - - - value - - - 2 - - - - next - - - - value - - - 3 - - - - next - - - - value - - - 4 - - - - next - - - null - - - null - - - secondList - - - list - - - - -======= -value1nextvalue2nextvalue3nextvalue4nextnullnullsecondListlist ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 73e9bf10f..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,64 +1 @@ -<<<<<<< HEAD - - - - linked-list.svg - Created with sketchtool. - - - - - value - - - 1 - - - - next - - - - value - - - 2 - - - - next - - - - value - - - 3 - - - - next - - - - value - - - 4 - - - - next - - - null - - - list - - - - -======= -value1nextvalue2nextvalue3nextvalue4nextnulllist ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 a7f026ed5..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,54 +1 @@ -<<<<<<< HEAD - - - - recursion-pow.svg - Created with sketchtool. - - - - - - pow(x,n) - - - - - - - x - - - - - - x * pow(x, n-1) - - - - - - - - n == 1 ? - - - - Yes - - - No - - - - - - recursive call until n==1 - - - - - -======= -pow(x,n)xx * pow(x, n-1)n == 1 ?YesNorecursive call until n==1 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 6f3a93ec5..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,94 +1 @@ -<<<<<<< HEAD - - - - recursive-salaries.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -======= - ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 + \ 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 7f0eba927..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,11 +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 -<<<<<<< HEAD:1-js/06-advanced-functions/02-rest-parameters-spread/article.md -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)? ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3:1-js/06-advanced-functions/02-rest-parameters-spread/article.md It is possible to do the same thing with the spread syntax. 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 index 2512f4251..5cdf7f1a4 100644 --- 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 @@ -1,94 +1 @@ -<<<<<<< HEAD:1-js/06-advanced-functions/03-closure/lexenv-nested-work.svg - - - - lexenv-nested-work.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - makeWorker: function - name: "John" - - - - - - - - - - - - - - - - - - - <empty> - - - - - - outer - - - - - - outer - - - - - - outer - - - - null - - - - - name: "Pete" - - - - - -======= -makeWorker: function name: "John"<empty>outerouterouternullname: "Pete" ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3:1-js/06-advanced-functions/03-closure/2-closure-variable-access/lexenv-nested-work.svg +makeWorker: function name: "John"<empty>outerouterouternullname: "Pete" \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexenv-if.svg b/1-js/06-advanced-functions/03-closure/lexenv-if.svg index bdff5c425..b644fe154 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-if.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-if.svg @@ -1,73 +1 @@ -<<<<<<< HEAD - - - - lexenv-if.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - phrase: "Hello" - - - - - - - - - - - - - - outer - - - - - - outer - - - - null - - - - - user: "John" - - - - - -======= -phrase: "Hello"outerouternulluser: "John" ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +phrase: "Hello"outerouternulluser: "John" \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-1.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-1.svg index b146caaf3..a14df7092 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-1.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-1.svg @@ -1,43 +1 @@ -<<<<<<< HEAD - - - - lexenv-nested-makecounter-1.svg - Created with sketchtool. - - - - - - - - - - - - makeCounter: function - - - - [[Environment]] - - - - - outer - - - - - - - - null - - - - - -======= -makeCounter: function[[Environment]]outernull ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +makeCounter: function[[Environment]]outernull \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg index 0e6382490..66e5200f8 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg @@ -1,73 +1 @@ -<<<<<<< HEAD - - - - lexenv-nested-makecounter-2.svg - Created with sketchtool. - - - - - - - - - - - - - - - - makeCounter: function - - - - - - counter: undefined - - - - - - - - - - - - - - count: 0 - - - - - - outer - - - - - - outer - - - - null - - - - global Lexical Environment - - - Lexical Environment - of makeCounter() call - - - - -======= -makeCounter: functioncounter: undefinedcount: 0outerouternullglobal LexicalEnvironmentLexicalEnvironment of makeCounter() call ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +makeCounter: functioncounter: undefinedcount: 0outerouternullglobal LexicalEnvironmentLexicalEnvironment of makeCounter() call \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg index 8fd6e99a7..28c526c4f 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg @@ -1,75 +1 @@ -<<<<<<< HEAD - - - - lexenv-nested-makecounter-3.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - makeCounter: function - - - - - - counter: undefined - - - - - - - - - - - - - - count: 0 - - - - - - outer - - - - - - outer - - - - null - - - [[Environment]] - - - - - - -======= -makeCounter: functioncounter: undefinedcount: 0outerouternull[[Environment]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +makeCounter: functioncounter: undefinedcount: 0outerouternull[[Environment]] \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg index fc4e9208f..acc1e8fb9 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg @@ -1,90 +1 @@ -<<<<<<< HEAD - - - - lexenv-nested-makecounter-4.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - makeCounter: function - - - - - - counter: - function - - - - - - - - - - - - - - count: 0 - - - - - - outer - - - - - - outer - - - - null - - - [[Environment]] - - - - - - - - - - - - - - - - -======= -makeCounter: functioncounter: functioncount: 0outerouternull[[Environment]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +makeCounter: functioncounter: functioncount: 0outerouternull[[Environment]] \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg index 332de8807..cf91c331d 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg @@ -1,99 +1 @@ -<<<<<<< HEAD - - - - lexenv-nested-makecounter-5.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - makeCounter: function - - - - - - counter: function - - - - - - - - - - - - - - count: 0 - - - - - - - - - - - <empty> - - - - - - outer - - - - - - outer - - - - - - outer - - - - null - - - - [[Environment]] - - - - - - - -======= -makeCounter: functioncounter: functioncount: 0<empty>outerouterouternull[[Environment]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +makeCounter: functioncounter: functioncount: 0<empty>outerouterouternull[[Environment]] \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg index 503b929e3..def542ceb 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg @@ -1,89 +1 @@ -<<<<<<< HEAD - - - - lexenv-nested-makecounter-6.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - makeCounter: function - - - - - - counter: function - - - - - - - - - - - - - - count: 1 - - - - - - outer - - - - - - outer - - - - null - - - [[Environment]] - - - - - modified here - - - - -======= -makeCounter: functioncounter: functioncount: 1outerouternull[[Environment]]modified here ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +makeCounter: functioncounter: functioncount: 1outerouternull[[Environment]]modified here \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-global-2.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-global-2.svg index dd28cdfd3..2e956cbbf 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-global-2.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-global-2.svg @@ -1,68 +1 @@ -<<<<<<< HEAD - - - - lexical-environment-global-2.svg - Created with sketchtool. - - - - - - phrase: "Bye" - - - - - - phrase: "Hello" - - - - - - phrase: undefined - - - - - - <empty> - - - - - - outer - - - - null - - - - - - - - - - - - - - - - execution start - - - - - - - - - -======= -phrase: "Bye"phrase: "Hello"phrase: undefined<empty>outernullexecution start ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +phrase: "Bye"phrase: "Hello"phrase: undefined<empty>outernullexecution start \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-global-3.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-global-3.svg index 191d78f90..d0f4a8e64 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-global-3.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-global-3.svg @@ -1,65 +1 @@ -<<<<<<< HEAD - - - - lexical-environment-global-3.svg - Created with sketchtool. - - - - - - say: function - phrase: "Hello" - - - - - - say: function - - - - - - outer - - - - null - - - - - - - - - - - - - - - - - - - - - - - - - - - execution start - - - - - - -======= -say: function phrase: "Hello"say: functionouternullexecution start ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +say: function phrase: "Hello"say: functionouternullexecution start \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-global.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-global.svg index eddde06ea..9620f0485 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-global.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-global.svg @@ -1,44 +1 @@ -<<<<<<< HEAD - - - - lexical-environment-global.svg - Created with sketchtool. - - - - - - phrase: "Hello" - - - - - - outer - - - - null - - - - - - - - - - - - - - LexicalEnvironment - - - - - -======= -phrase: "Hello"outernullLexical Environment ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +phrase: "Hello"outernullLexical Environment \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg index ea4539cbf..ff0486ede 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg @@ -1,77 +1 @@ -<<<<<<< HEAD - - - - lexical-environment-simple-lookup.svg - Created with sketchtool. - - - - - - - - - - - - - - say: function - phrase: "Hello" - - - - - - name: "John" - - - - - - outer - - - - - - outer - - - - null - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -======= -say: function phrase: "Hello"name: "John"outerouternull ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +say: function phrase: "Hello"name: "John"outerouternull \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg index f11f7c7c5..abd77fff9 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg @@ -1,71 +1 @@ -<<<<<<< HEAD - - - - lexical-environment-simple.svg - Created with sketchtool. - - - - - - - - - - - - - - say: function - phrase: "Hello" - - - - - - name: "John" - - - - - - outer - - - - - - outer - - - - null - - - - - - - - - - - - - - - - - - - - the new function Lexical Environment - - - - - -======= -say: function phrase: "Hello"name: "John"outerouternullLexical Environment of the call ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +say: function phrase: "Hello"name: "John"outerouternullLexical Environment of the call \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/lexical-search-order.svg b/1-js/06-advanced-functions/03-closure/lexical-search-order.svg index 941c17daf..89a9d110a 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-search-order.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-search-order.svg @@ -1,52 +1 @@ -<<<<<<< HEAD - - - - lexical-search-order.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - 2 - - - 3 - - - - -======= -123 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +123 \ No newline at end of file diff --git a/1-js/06-advanced-functions/04-var/article.md b/1-js/06-advanced-functions/04-var/article.md index f5e9efc53..6f05d0a24 100644 --- a/1-js/06-advanced-functions/04-var/article.md +++ b/1-js/06-advanced-functions/04-var/article.md @@ -28,11 +28,7 @@ On the other hand, it's important to understand differences when migrating old s ## "var" has no block scope -<<<<<<< HEAD -`var` variables are either function-wide or global, they are visible through blocks. -======= Variables, declared with `var`, are either function-scoped or global-scoped. They are visible through blocks. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For instance: @@ -96,14 +92,10 @@ var user = "Pete"; var user = "John"; // this "var" does nothing (already declared) // ...it doesn't trigger an error -<<<<<<< HEAD -## "var" are processed at the function start -======= alert(user); // John ``` ## "var" variables can be declared below their use ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 `var` declarations are processed when the function starts (or script starts for globals). @@ -272,13 +264,8 @@ In all the above cases we declare a Function Expression and run it immediately. There are two main differences of `var`: -<<<<<<< HEAD -1. Variables have no block scope, they are visible minimum at the function level. -2. Variable declarations are processed at function start. -======= 1. `var` variables have no block scope; their visibility is scoped to current function, or global, if declared outside function. 2. `var` declarations are processed at function start (script start for globals). ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 There's one more very minor difference related to the global object, that we'll cover in the next chapter. diff --git a/1-js/06-advanced-functions/05-global-object/article.md b/1-js/06-advanced-functions/05-global-object/article.md index 838ba3921..ca92bb2b9 100644 --- a/1-js/06-advanced-functions/05-global-object/article.md +++ b/1-js/06-advanced-functions/05-global-object/article.md @@ -5,11 +5,7 @@ O objeto global fornece variáveis e funções que estão disponíveis em qualqu No navegador ele é chamado de `window`, no Node.js é `global`, em outros ambientes pode ter outro nome. -<<<<<<< HEAD -Recentemente, `globalThis` foi adicionado a linguagem como um nome padrão para o objeto global, que deve ser suportado em todos os ambientes. Em alguns navegadores, como o "non-Chromium Edge", `globalThis` ainda não é suportado, mas pode ser facilmente utilizado através de um polyfill. -======= -Recently, `globalThis` was added to the language, as a standardized name for a global object, that should be supported across all environments. It's supported in all major browsers. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +Recentemente, `globalThis` foi adicionado à linguagem como um nome padrão para o objeto global, e que deve ser suportado em todos os ambientes. Ele é suportado em todos os principais navegadores. Usamos `window` aqui, assumindo que nosso ambiente seja um navegador. Se o seu script puder ser executado em outros ambientes, é melhor utilizar o `globalThis`. @@ -85,14 +81,7 @@ if (!window.Promise) { Isso inclui objetos nativos Javascript, como `Array` e valores específicos do ambiente, como `window.innerHeight` -- a altura da janela no navegador. - O objeto global tem o nome universal `globalThis`. -<<<<<<< HEAD - ...Porém é mais frequentemente referido pelos seu nomes específicos de ambientes "old-school", como `window` (navegador) e `global` (Node.js). Como `globalThis` é uma proposta recente, não é suportado pelo "non-Chromium Edge" (mas pode ser usado com um polyfill). -- Devemos salvar valores no objeto global apenas se eles forem realmente globais em nosso projeto. E manter sua quantidade no mínimo. -- No navegador, ao menos que estejamos usando [modules](info:modules), funções e variáveis globais declaradas com `var` tornam-se uma propriedade do objeto global. + ...Porém é mais frequentemente referido pelos seu nomes específicos de ambientes "old-school", como `window` (navegador) e `global` (Node.js). +- Devemos salvar valores no objeto global apenas se eles forem realmente globais em nosso projeto. E manter a sua quantidade no mínimo. +- No navegador, a menos que estejamos usando [modules](info:modules), funções e variáveis globais declaradas com `var` se tornam numa propriedade do objeto global. - Para tornar nosso código à prova de mudanças no futuro e mais fácil de entender, devemos acessar as propriedades do objeto global diretamente, como `window.x`. -======= - ...But more often is referred by "old-school" environment-specific names, such as `window` (browser) and `global` (Node.js). -- We should store values in the global object only if they're truly global for our project. And keep their number at minimum. -- In-browser, unless we're using [modules](info:modules), global functions and variables declared with `var` become a property of the global object. -- To make our code future-proof and easier to understand, we should access properties of the global object directly, as `window.x`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 diff --git a/1-js/06-advanced-functions/06-function-object/article.md b/1-js/06-advanced-functions/06-function-object/article.md index 773413cb6..3fa5d2a0a 100644 --- a/1-js/06-advanced-functions/06-function-object/article.md +++ b/1-js/06-advanced-functions/06-function-object/article.md @@ -347,11 +347,7 @@ If the function is declared as a Function Expression (not in the main code flow) Also, functions may carry additional properties. Many well-known JavaScript libraries make great use of this feature. -<<<<<<< HEAD -They create a "main" function and attach many other "helper" functions to it. For instance, the [jquery](https://jquery.com) library creates a function named `$`. The [lodash](https://lodash.com) library creates a function `_`. And then adds `_.clone`, `_.keyBy` and other properties to (see the [docs](https://lodash.com/docs) when you want learn more about them). Actually, they do it to lessen their pollution of the global space, so that a single library gives only one global variable. That reduces the possibility of naming conflicts. -======= They create a "main" function and attach many other "helper" functions to it. For instance, the [jQuery](https://jquery.com) library creates a function named `$`. The [lodash](https://lodash.com) library creates a function `_`, and then adds `_.clone`, `_.keyBy` and other properties to it (see the [docs](https://lodash.com/docs) when you want learn more about them). Actually, they do it to lessen their pollution of the global space, so that a single library gives only one global variable. That reduces the possibility of naming conflicts. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 So, a function can do a useful job by itself and also carry a bunch of other functionality in properties. diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md index aa73da873..e69d8dbc9 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md @@ -178,11 +178,7 @@ let timerId = setTimeout(function request() { And if we regularly have CPU-hungry tasks, then we can measure the time taken by the execution and plan the next call sooner or later. -<<<<<<< HEAD -**Recursive `setTimeout` guarantees a delay between the executions, `setInterval` -- does not.** -======= **Nested `setTimeout` allows to set the delay between the executions more precisely than `setInterval`.** ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Let's compare two code fragments. The first one uses `setInterval`: @@ -246,11 +242,7 @@ There's a special use case: `setTimeout(func, 0)`, or just `setTimeout(func)`. This schedules the execution of `func` as soon as possible. But the scheduler will invoke it only after the currently executing script is complete. -<<<<<<< HEAD -So the function is scheduled to run "right after" the current code. In other words, *asynchronously*. -======= So the function is scheduled to run "right after" the current script. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For instance, this outputs "Hello", then immediately "World": @@ -451,22 +443,11 @@ Now the `
` shows increasing values of `i`. ## Summary -<<<<<<< HEAD -- Methods `setInterval(func, delay, ...args)` and `setTimeout(func, delay, ...args)` allow to run the `func` regularly/once after `delay` milliseconds. -- To cancel the execution, we should call `clearInterval/clearTimeout` with the value returned by `setInterval/setTimeout`. -- Nested `setTimeout` calls is a more flexible alternative to `setInterval`. Also they can guarantee the minimal time *between* the executions. -- Zero-timeout scheduling `setTimeout(...,0)` is used to schedule the call "as soon as possible, but after the current code is complete". - -Some use cases of `setTimeout(...,0)`: -- To split CPU-hungry tasks into pieces, so that the script doesn't "hang" -- To let the browser do something else while the process is going on (paint the progress bar). -======= - Methods `setTimeout(func, delay, ...args)` and `setInterval(func, delay, ...args)` allow us to run the `func` once/regularly after `delay` milliseconds. - To cancel the execution, we should call `clearTimeout/clearInterval` with the value returned by `setTimeout/setInterval`. - Nested `setTimeout` calls are a more flexible alternative to `setInterval`, allowing us to set the time *between* executions more precisely. - Zero delay scheduling with `setTimeout(func, 0)` (the same as `setTimeout(func)`) is used to schedule the call "as soon as possible, but after the current script is complete". - The browser limits the minimal delay for five or more nested call of `setTimeout` or for `setInterval` (after 5th call) to 4ms. That's for historical reasons. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Please note that all scheduling methods do not *guarantee* the exact delay. We should not rely on that in the scheduled code. diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/settimeout-interval.svg b/1-js/06-advanced-functions/08-settimeout-setinterval/settimeout-interval.svg index b2a0905ed..a559f6163 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/settimeout-interval.svg +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/settimeout-interval.svg @@ -1,43 +1 @@ -<<<<<<< HEAD - - - - settimeout-interval.svg - Created with sketchtool. - - - - - - func(1) - - - - - - func(2) - - - - - - func(3) - - - - - - - 100 - - - 100 - - - - - - -======= -func(1)func(2)func(3)100100 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +func(1)func(2)func(3)100100 \ No newline at end of file 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 67275c5b6..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 @@ -18,14 +18,8 @@ Let's check the real-life application to better understand that requirement and **For instance, we want to track mouse movements.** -<<<<<<< HEAD -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.** ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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. 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 74bb090ba..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 @@ -241,84 +241,7 @@ There are many solutions possible: For many practical applications, the 3rd variant is good enough, so we'll stick to it. -<<<<<<< HEAD -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)`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Now let's bake it all into the more powerful `cachingDecorator`: @@ -359,19 +282,13 @@ alert( worker.slow(3, 5) ); // works alert( "Again " + worker.slow(3, 5) ); // same (cached) ``` -<<<<<<< HEAD -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). ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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. -<<<<<<< HEAD -======= ## func.apply Instead of `func.call(this, ...arguments)` we could use `func.apply(this, arguments)`. @@ -413,7 +330,6 @@ let wrapper = function() { ``` When an external code calls such `wrapper`, it is indistinguishable from the call of the original function `func`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## Borrowing a method [#method-borrowing] 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 e5bc060ff..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,68 +1 @@ -<<<<<<< HEAD - - - - decorator-makecaching-wrapper.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wrapper - - - around the function - - - - - -======= -wrapperaround the function ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +wrapperaround the function \ No newline at end of file diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index f0d2fc1c9..7bca80ae9 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -205,8 +205,6 @@ for (let key in user) { JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll) in lodash. ```` -<<<<<<< HEAD -======= ## Partial functions Until now we have only been talking about binding `this`. Let's take it a step further. @@ -319,7 +317,6 @@ 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## 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/12-arrow-functions/article.md b/1-js/06-advanced-functions/12-arrow-functions/article.md index c55e5a6f9..c4e8d43fc 100644 --- a/1-js/06-advanced-functions/12-arrow-functions/article.md +++ b/1-js/06-advanced-functions/12-arrow-functions/article.md @@ -4,11 +4,7 @@ Vamos revisitar as *arrow functions*. As *arrow functions* não são somente uma "abreviação" para escrevermos menos código. -<<<<<<< HEAD O *JavaScript* está cheio de situações onde precisamos escrever uma pequena função que será executada em um outro lugar. -======= -JavaScript is full of situations where we need to write a small function that's executed somewhere else. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Por exemplo: @@ -122,18 +118,8 @@ Aqui precisamos criar as variáveis adicionais `args` e `ctx` para que a funçã *Arrow functions* (funções seta): -<<<<<<< HEAD -- 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 ). Isso porque elas são feitas para pequenos trechos de código que não possuem seus próprios "contextos", mas sim utilizam o contexto em que estão inseridas. E elas realmente brilham nesses casos. -======= -- Do not have `this` -- Do not have `arguments` -- Can't be called with `new` -- They also don't have `super`, but we didn't study it yet. We will on the chapter - -That's because they are meant for short pieces of code that do not have their own "context", but rather work in the current one. And they really shine in that use case. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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 c9ab6e655..edf3e260f 100644 --- a/1-js/07-object-properties/01-property-descriptors/article.md +++ b/1-js/07-object-properties/01-property-descriptors/article.md @@ -122,28 +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. -<<<<<<< HEAD -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: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run let user = { }; Object.defineProperty(user, "name", { *!* -<<<<<<< HEAD - 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 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 enumerable: true, configurable: true */!* @@ -273,12 +264,6 @@ delete user.name; Object.defineProperty(user, "name", { value: "Pete" }); ``` -<<<<<<< HEAD -```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. -``` -======= ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## Object.defineProperties 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 66f0a2ddb..047023efe 100644 --- a/1-js/07-object-properties/02-property-accessors/article.md +++ b/1-js/07-object-properties/02-property-accessors/article.md @@ -3,11 +3,7 @@ There are two kinds of object properties. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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. @@ -86,21 +82,7 @@ alert(user.name); // Alice alert(user.surname); // Cooper ``` -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## Accessor descriptors @@ -140,11 +122,7 @@ alert(user.fullName); // John Smith for(let key in user) alert(key); // name, surname ``` -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 If we try to supply both `get` and `value` in the same descriptor, there will be an error: @@ -193,15 +171,9 @@ Technically, the external code may still access the name directly by using `user ## Using for compatibility -<<<<<<< HEAD -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. - -For instance, we started implementing user objects using data properties `name` and `age`: -======= 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. Imagine we started implementing user objects using data properties `name` and `age`: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```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 790541d2f..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,11 +6,7 @@ importance: 5 The task has two parts. -<<<<<<< HEAD -We have an object: -======= Given the following objects: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js let head = { diff --git a/1-js/08-prototypes/01-prototype-inheritance/article.md b/1-js/08-prototypes/01-prototype-inheritance/article.md index 47db72eb2..9c8fbde99 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/article.md +++ b/1-js/08-prototypes/01-prototype-inheritance/article.md @@ -250,12 +250,6 @@ The resulting picture: ![](proto-animal-rabbit-walk-3.svg) -<<<<<<< HEAD -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. - -As a result, methods are shared, but the object state is not. - -======= 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. @@ -328,18 +322,12 @@ Almost all other key/value-getting methods, such as `Object.keys`, `Object.value They only operate on the object itself. Properties from the prototype are *not* taken into account. ``` ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## 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". -<<<<<<< HEAD -- 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 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. -======= - 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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 3156903bb..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,26 +1 @@ -<<<<<<< HEAD - - - - object-prototype-empty.svg - Created with sketchtool. - - - - - prototype object - - - - object - - - - [[Prototype]] - - - - -======= -prototype objectobject[[Prototype]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 9137cdf42..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,44 +1 @@ -<<<<<<< HEAD - - - - proto-animal-rabbit-chain.svg - Created with sketchtool. - - - - - eats: true - walk: function - - - animal - - - - jumps: true - - - rabbit - - - - [[Prototype]] - - - - earLength: 10 - - - longEar - - - - [[Prototype]] - - - - -======= -eats: true walk: functionanimaljumps: truerabbit[[Prototype]]earLength: 10longEar[[Prototype]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 69908d360..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,33 +1 @@ -<<<<<<< HEAD - - - - proto-animal-rabbit-walk-2.svg - Created with sketchtool. - - - - - eats: true - walk: function - - - animal - - - - walk: function - - - rabbit - - - - [[Prototype]] - - - - -======= -eats: true walk: functionanimalwalk: functionrabbit[[Prototype]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 61e338ac3..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,34 +1 @@ -<<<<<<< HEAD - - - - proto-animal-rabbit-walk-3.svg - Created with sketchtool. - - - - - walk: function - sleep: function - - - animal - - - rabbit - - - - [[Prototype]] - - - - name: "White Rabbit" - isSleeping: true - - - - -======= -walk: function sleep: functionanimalrabbit[[Prototype]]name: "White Rabbit" isSleeping: true ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 551a0061d..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,33 +1 @@ -<<<<<<< HEAD - - - - proto-animal-rabbit-walk.svg - Created with sketchtool. - - - - - eats: true - walk: function - - - animal - - - - jumps: true - - - rabbit - - - - [[Prototype]] - - - - -======= -eats: true walk: functionanimaljumps: truerabbit[[Prototype]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 f0de57d74..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,32 +1 @@ -<<<<<<< HEAD - - - - proto-animal-rabbit.svg - Created with sketchtool. - - - - - eats: true - - - animal - - - - jumps: true - - - rabbit - - - - [[Prototype]] - - - - -======= -eats: trueanimaljumps: truerabbit[[Prototype]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 4d1c2d789..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,36 +1 @@ -<<<<<<< HEAD - - - - proto-user-admin.svg - Created with sketchtool. - - - - - name: "John" - surname: "Smith" - set fullName: function - - - - isAdmin: true - name: "Alice" - surname: "Cooper" - - - user - - - admin - - - - [[Prototype]] - - - - -======= -name: "John" surname: "Smith" set fullName: functionisAdmin: true name: "Alice" surname: "Cooper"useradmin[[Prototype]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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/02-function-prototype/article.md b/1-js/08-prototypes/02-function-prototype/article.md index 03b4fe165..b1ef51826 100644 --- a/1-js/08-prototypes/02-function-prototype/article.md +++ b/1-js/08-prototypes/02-function-prototype/article.md @@ -160,15 +160,9 @@ In this chapter we briefly described the way of setting a `[[Prototype]]` for ob Everything is quite simple, just a few notes to make things clear: -<<<<<<< HEAD -- 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`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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 e9dec01a9..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,30 +1 @@ -<<<<<<< HEAD - - - - function-prototype-constructor.svg - Created with sketchtool. - - - - - - Rabbit - - - - - prototype - - - constructor - - - default "prototype" - - - - -======= -Rabbitprototypeconstructordefault "prototype" ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 9b3bc68e1..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,40 +1 @@ -<<<<<<< HEAD - - - - proto-constructor-animal-rabbit.svg - Created with sketchtool. - - - - - eats: true - - - - name: "White Rabbit" - - - animal - - - - Rabbit - - - rabbit - - - - - [[Prototype]] - - - prototype - - - - -======= -eats: truename: "White Rabbit"animalRabbitrabbit[[Prototype]]prototype ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 61db35476..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,43 +1 @@ -<<<<<<< HEAD - - - - rabbit-prototype-constructor.svg - Created with sketchtool. - - - - - - - - - - default "prototype" - - - - - Rabbit - - - rabbit - - - - - - [[Prototype]] - - - prototype - - - constructor - - - - -======= -default "prototype"Rabbitrabbit[[Prototype]]prototypeconstructor ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +default "prototype"Rabbitrabbit[[Prototype]]prototypeconstructor \ No newline at end of file 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 e9dec01a9..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,30 +1 @@ -<<<<<<< HEAD - - - - function-prototype-constructor.svg - Created with sketchtool. - - - - - - Rabbit - - - - - prototype - - - constructor - - - default "prototype" - - - - -======= -Rabbitprototypeconstructordefault "prototype" ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 5b820f0d9..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,43 +1 @@ -<<<<<<< HEAD - - - - native-prototypes-array-tostring.svg - Created with sketchtool. - - - - - toString: function - - ... - - - Array.prototype - - - - toString: function - ... - - - Object.prototype - - - - - [[Prototype]] - - - - [[Prototype]] - - - [1, 2, 3] - - - - -======= -toString: function ...Array.prototypetoString: function ...Object.prototype[[Prototype]][[Prototype]][1, 2, 3] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 5511dcd25..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,91 +1 @@ -<<<<<<< HEAD - - - - 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 - - - - - - - -======= -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 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 ced45930a..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,42 +1 @@ -<<<<<<< HEAD - - - - object-prototype-1.svg - Created with sketchtool. - - - - - constructor: Object - toString: function - ... - - - - Object.prototype - - - - Object - - - obj = new Object() - - - - - [[Prototype]] - - - prototype - - - constructor - - - - -======= -constructor: Object toString: function ...Object.prototypeObjectobj = new Object()[[Prototype]]prototype ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 c3047c2bd..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,25 +1 @@ -<<<<<<< HEAD - - - - object-prototype-null.svg - Created with sketchtool. - - - - - obj - - - - [[Prototype]] - - - null - - - - -======= -obj[[Prototype]]null ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 c96a34451..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,34 +1 @@ -<<<<<<< HEAD - - - - object-prototype.svg - Created with sketchtool. - - - - - constructor: Object - toString: function - ... - - - Object.prototype - - - - Object - - - - prototype - - - constructor - - - - -======= -constructor: Object toString: function ...Object.prototypeObjectprototype ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 9b3bc68e1..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,40 +1 @@ -<<<<<<< HEAD - - - - proto-constructor-animal-rabbit.svg - Created with sketchtool. - - - - - eats: true - - - - name: "White Rabbit" - - - animal - - - - Rabbit - - - rabbit - - - - - [[Prototype]] - - - prototype - - - - -======= -eats: truename: "White Rabbit"animalRabbitrabbit[[Prototype]]prototype ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 61db35476..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,43 +1 @@ -<<<<<<< HEAD - - - - rabbit-prototype-constructor.svg - Created with sketchtool. - - - - - - - - - - default "prototype" - - - - - Rabbit - - - rabbit - - - - - - [[Prototype]] - - - prototype - - - constructor - - - - -======= -default "prototype"Rabbitrabbit[[Prototype]]prototypeconstructor ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 465df7b92..2a46367cc 100644 --- a/1-js/08-prototypes/04-prototype-methods/article.md +++ b/1-js/08-prototypes/04-prototype-methods/article.md @@ -69,27 +69,16 @@ Why? That's for historical reasons. -<<<<<<< HEAD -- The `"prototype"` property of a constructor function works since very ancient times. -- Later in the year 2012: `Object.create` appeared in the standard. It allowed to create objects with the given prototype, but did not allow to get/set it. So browsers implemented non-standard `__proto__` accessor that allowed to get/set a prototype at any time. -- Later in the year 2015: `Object.setPrototypeOf` and `Object.getPrototypeOf` were added to the standard. The `__proto__` was de-facto implemented everywhere, so it made its way to the Annex B of the standard, that is optional for non-browser environments. -======= - The `"prototype"` property of a constructor function has worked since very ancient times. - Later, in the year 2012, `Object.create` appeared in the standard. It gave the ability to create objects with a given prototype, but did not provide the ability to get/set it. So browsers implemented the non-standard `__proto__` accessor that allowed the user to get/set a prototype at any time. - Later, in the year 2015, `Object.setPrototypeOf` and `Object.getPrototypeOf` were added to the standard, to perform the same functionality as `__proto__`. As `__proto__` was de-facto implemented everywhere, it was kind-of deprecated and made its way to the Annex B of the standard, that is: optional for non-browser environments. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 As of now we have all these ways at our disposal. Why was `__proto__` replaced by the functions? That's an interesting question, requiring us to understand why `__proto__` is bad. Read on to get the answer. -<<<<<<< HEAD -```warn header="Don't reset `[[Prototype]]` unless the speed doesn't matter" -Technically, we can get/set `[[Prototype]]` at any time. But usually we only set it once at the object creation time, and then do not modify: `rabbit` inherits from `animal`, and that is not going to change. -======= ```warn header="Don't change `[[Prototype]]` on existing objects if speed matters" Technically, we can get/set `[[Prototype]]` at any time. But usually we only set it once at the object creation time and don't modify it anymore: `rabbit` inherits from `animal`, and that is not going to change. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 And JavaScript engines are highly optimized for this. Changing a prototype "on-the-fly" with `Object.setPrototypeOf` or `obj.__proto__=` is a very slow operation as it breaks internal optimizations for object property access operations. So avoid it unless you know what you're doing, or JavaScript speed totally doesn't matter for you. ``` @@ -117,19 +106,11 @@ That shouldn't surprise us. The `__proto__` property is special: it must be eith But we didn't *intend* to implement such behavior, right? We want to store key/value pairs, and the key named `"__proto__"` was not properly saved. So that's a bug! -<<<<<<< HEAD -Here the consequences are not terrible. But in other cases the prototype may indeed be changed, so the execution may go wrong in totally unexpected ways. -======= Here the consequences are not terrible. But in other cases we may be assigning object values, and then the prototype may indeed be changed. As a result, the execution will go wrong in totally unexpected ways. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 What's worse -- usually developers do not think about such possibility at all. That makes such bugs hard to notice and even turn them into vulnerabilities, especially when JavaScript is used on server-side. -<<<<<<< HEAD -Unexpected things also may happen when accessing `toString` property -- that's a function by default, and other built-in properties. -======= Unexpected things also may happen when assigning to `toString`, which is a function by default, and to other built-in methods. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 How can we avoid this problem? @@ -197,11 +178,7 @@ Modern methods to set up and directly access the prototype are: - [Object.getPrototypeOf(obj)](mdn:js/Object.getPrototypeOf) -- returns the `[[Prototype]]` of `obj` (same as `__proto__` getter). - [Object.setPrototypeOf(obj, proto)](mdn:js/Object.setPrototypeOf) -- sets the `[[Prototype]]` of `obj` to `proto` (same as `__proto__` setter). -<<<<<<< HEAD -The built-in `__proto__` getter/setter is unsafe if we'd want to put user-generated keys in to an object. Just because a user may enter "__proto__" as the key, and there'll be an error with hopefully easy, but generally unpredictable consequences. -======= The built-in `__proto__` getter/setter is unsafe if we'd want to put user-generated keys into an object. Just because a user may enter `"__proto__"` as the key, and there'll be an error, with hopefully light, but generally unpredictable consequences. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 So we can either use `Object.create(null)` to create a "very plain" object without `__proto__`, or stick to `Map` objects for that. @@ -211,10 +188,7 @@ Also, `Object.create` provides an easy way to shallow-copy an object with all de let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); ``` -<<<<<<< HEAD -======= We also made it clear that `__proto__` is a getter/setter for `[[Prototype]]` and resides in `Object.prototype`, just like other methods. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 - [Object.keys(obj)](mdn:js/Object/keys) / [Object.values(obj)](mdn:js/Object/values) / [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of enumerable own string property names/values/key-value pairs. - [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) -- returns an array of all own symbolic property names. @@ -224,14 +198,10 @@ We also made it clear that `__proto__` is a getter/setter for `[[Prototype]]` an We also made it clear that `__proto__` is a getter/setter for `[[Prototype]]` and resides in `Object.prototype`, just as other methods. -<<<<<<< HEAD -We can create an object without a prototype by `Object.create(null)`. Such objects are used as "pure dictionaries", they have no issues with `"__proto__"` as the key. -======= - [Object.keys(obj)](mdn:js/Object/keys) / [Object.values(obj)](mdn:js/Object/values) / [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of enumerable own string property names/values/key-value pairs. - [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) -- returns an array of all own symbolic keys. - [Object.getOwnPropertyNames(obj)](mdn:js/Object/getOwnPropertyNames) -- returns an array of all own string keys. - [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) -- returns an array of all own keys. - [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): returns `true` if `obj` has its own (not inherited) key named `key`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 All methods that return object properties (like `Object.keys` and others) -- return "own" properties. If we want inherited ones, we can use `for..in`. diff --git a/1-js/08-prototypes/04-prototype-methods/object-prototype-2.svg b/1-js/08-prototypes/04-prototype-methods/object-prototype-2.svg index e18af9042..c3717ad50 100644 --- a/1-js/08-prototypes/04-prototype-methods/object-prototype-2.svg +++ b/1-js/08-prototypes/04-prototype-methods/object-prototype-2.svg @@ -1,42 +1 @@ -<<<<<<< HEAD - - - - object-prototype-2.svg - Created with sketchtool. - - - - - ... - get __proto__: function - set __proto__: function - - - - Object.prototype - - - - Object - - - obj - - - - - [[Prototype]] - - - prototype - - - constructor - - - - -======= -... get __proto__: function set __proto__: functionObject.prototypeObjectobj[[Prototype]]prototype ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +... 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 c3047c2bd..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,25 +1 @@ -<<<<<<< HEAD - - - - object-prototype-null.svg - Created with sketchtool. - - - - - obj - - - - [[Prototype]] - - - null - - - - -======= -obj[[Prototype]]null ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +obj[[Prototype]]null \ No newline at end of file diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md index fa525cc7e..a934baf6c 100644 --- a/1-js/09-classes/01-class/article.md +++ b/1-js/09-classes/01-class/article.md @@ -91,13 +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. -<<<<<<< HEAD -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: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ![](class-user.svg) @@ -125,11 +121,7 @@ alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi ## Not just a syntactic sugar -<<<<<<< HEAD -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: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run // rewriting class User in pure functions @@ -157,11 +149,7 @@ 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. -<<<<<<< HEAD - 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`: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run class User { @@ -246,11 +234,7 @@ new User().sayHi(); // Hello ## Getters/setters -<<<<<<< HEAD -Classes also include getters/setters, generators, computed properties etc. -======= Just like literal objects, classes may include getters/setters, computed properties etc. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Here's an example for `user.name` implemented using `get/set`: @@ -286,19 +270,11 @@ alert(user.name); // John user = new User(""); // Name is too short. ``` -<<<<<<< HEAD -Internally, getters and setters are created on `User.prototype`, like this: -======= Technically, such class declaration works by creating getters and setters in `User.prototype`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## Computed names [...] -<<<<<<< HEAD -Here's an example with computed properties: -======= Here's an example with a computed method name using brackets `[...]`: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run function f() { return "sayHi"; } @@ -329,13 +305,9 @@ For instance, let's add `name` property to `class User`: ```js run class User { -<<<<<<< HEAD - name = "Anonymous"; -======= *!* name = "John"; */!* ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 sayHi() { alert(`Hello, ${this.name}!`); @@ -401,10 +373,6 @@ setTimeout(button.click, 1000); // undefined */!* ``` -<<<<<<< HEAD -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 problem is called "losing `this`". There are two approaches to fixing it, as discussed in the chapter : @@ -434,7 +402,6 @@ setTimeout(button.click, 1000); // hello 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## Summary @@ -476,10 +443,6 @@ class MyClass { } ``` -<<<<<<< HEAD -`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`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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 6ff15fc2f..95b58179b 100644 --- a/1-js/09-classes/01-class/class-user.svg +++ b/1-js/09-classes/01-class/class-user.svg @@ -1,33 +1 @@ -<<<<<<< HEAD - - - - class-user.svg - Created with sketchtool. - - - - - sayHi: function - - - - User - - - User.prototype - - - - prototype - - - constructor: User - - - - - -======= -sayHi: functionUserUser.prototypeprototypeconstructor: User ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +sayHi: functionUserUser.prototypeprototypeconstructor: User \ 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 ee3b1443a..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,68 +1 @@ -<<<<<<< HEAD - - - - 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 - - - - -======= -constructor: Animal run: function stop: functionAnimal.prototypeconstructor: Rabbit hide: functionRabbit.prototypeAnimalRabbitnew Rabbit[[Prototype]][[Prototype]]prototypeprototypename: "White Rabbit"constructorconstructorextends ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 1c7264ccf..d9714717f 100644 --- a/1-js/09-classes/02-class-inheritance/article.md +++ b/1-js/09-classes/02-class-inheritance/article.md @@ -36,35 +36,11 @@ Here's how we can represent `animal` object and `Animal` class graphically: 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. -<<<<<<< HEAD -To inherit from another class, we should specify `"extends"` and the parent class before the brackets `{..}`. -======= The syntax to extend another class is: `class Child extends Parent`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Let's create `class Rabbit` that inherits from `Animal`: -<<<<<<< HEAD -```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.`); - } -} - -// Inherit from Animal by specifying "extends Animal" -======= ```js ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 *!* class Rabbit extends Animal { */!* @@ -90,11 +66,7 @@ For instance, to find `rabbit.run` method, the engine checks (bottom-up on the p 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. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ````smart header="Any expression is allowed after `extends`" Class syntax allows to specify not just a class, but any expression after `extends`. @@ -134,12 +106,7 @@ class Rabbit extends Animal { } ``` -<<<<<<< HEAD - -...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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Classes provide `"super"` keyword for that. @@ -275,21 +242,12 @@ In JavaScript, there's a distinction between a constructor function of an inheri That label affects its behavior with `new`. -<<<<<<< HEAD -- 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. - -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. - -For `Rabbit` to work, we need to call `super()` before using `this`, like here: -======= - 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 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 the `Rabbit` constructor to work, it needs to call `super()` before using `this`, like here: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run class Animal { @@ -421,9 +379,6 @@ If it becomes a problem, one can fix it by using methods or getters/setters inst ## Super: internals, [[HomeObject]] -<<<<<<< HEAD -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. @@ -431,7 +386,6 @@ 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 First to say, from all that we've learned till now, it's impossible for `super` to work. @@ -577,9 +531,6 @@ longEar.eat(); // Long Ear eats. Every method remembers its object in the internal `[[HomeObject]]` property. Then `super` uses it to resolve the parent prototype. -<<<<<<< HEAD -`[[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`. @@ -640,7 +591,6 @@ Here's the diagram of what happens: `[[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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 In the example below a non-method syntax is used for comparison. `[[HomeObject]]` property is not set and the inheritance doesn't work: @@ -662,8 +612,6 @@ let rabbit = { rabbit.eat(); // Error calling super (because there's no [[HomeObject]]) */!* ``` -<<<<<<< HEAD -======= ## Summary @@ -679,4 +627,3 @@ rabbit.eat(); // Error calling super (because there's no [[HomeObject]]) Also: - Arrow functions don't have their own `this` or `super`, so they transparently fit into the surrounding context. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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 625b0dc3a..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,45 +1 @@ -<<<<<<< HEAD - - - - class-inheritance-array-object.svg - Created with sketchtool. - - - - - slice: function - ... - - - Array.prototype - - - arr - - - - hasOwnProperty: function - ... - - - Object.prototype - - - - - - [1, 2, 3] - - - [[Prototype]] - - - [[Prototype]] - - - - -======= -slice: function ...Array.prototypearrhasOwnProperty: function ...Object.prototype[1, 2, 3][[Prototype]][[Prototype]] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 b333c1bc5..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,66 +1 @@ -<<<<<<< HEAD - - - - 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 - - - - -======= -jump: functionRabbit.prototyperabbiteat: functionAnimal.prototypename: "White Rabbit"[[Prototype]][[Prototype]]Rabbit.prototype.__proto__ = Animal.prototype sets thistoString: function hasOwnProperty: function ...Object.prototype[[Prototype]][[Prototype]]null ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 468391daf..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,43 +1 @@ -<<<<<<< HEAD - - - - class-inheritance-rabbit-animal.svg - Created with sketchtool. - - - - - methods of Rabbit - - - Rabbit.prototype - - - rabbit - - - - methods of Animal - - - Animal.prototype - - - - - - [[Prototype]] - - - [[Prototype]] - - - properties of rabbit - - - - -======= -methods of RabbitRabbit.prototyperabbitmethods of AnimalAnimal.prototype[[Prototype]][[Prototype]]properties of rabbit ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 efa4d7e9f..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,46 +1 @@ -<<<<<<< HEAD - - - - 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 - - - - -======= - constructor: Animal run: function stop: functionAnimal.prototypeAnimalnew Animal[[Prototype]]prototypename: "My animal" ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 + 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 0f908892e..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,45 +1 @@ -<<<<<<< HEAD - - - - rabbit-animal-independent-rabbit.svg - Created with sketchtool. - - - - - - constructor: Rabbit - hide: function - - - Rabbit.prototype - - - - Rabbit - - - - new Rabbit - - - - - [[Prototype]] - - - prototype - - - name: "My rabbit" - - - constructor - - - - -======= - constructor: Rabbit hide: functionRabbit.prototypeRabbitnew Rabbit[[Prototype]]prototypename: "My rabbit" ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 + 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/this-super-loop.svg b/1-js/09-classes/02-class-inheritance/this-super-loop.svg index 02b39c996..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,76 +1 @@ -<<<<<<< HEAD - - - - this-super-loop.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - rabbit - - - longEar - - - rabbit - - - longEar - - - - - - - - -======= -rabbitlongEarrabbitlongEar ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 index 1356e158c..34d783b4d 100644 --- 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 @@ -1,71 +1 @@ -<<<<<<< HEAD:1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg - - - - 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 - - - - -======= -call: function bind: function ...Function.prototypeconstructorObjectRabbit[[Prototype]][[Prototype]]constructorcall: function bind: function ...Function.prototypeRabbit[[Prototype]]constructorclass Rabbitclass Rabbit extends Object ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3:1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg +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/03-static-properties-methods/animal-rabbit-static.svg b/1-js/09-classes/03-static-properties-methods/animal-rabbit-static.svg index 7d251d81e..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,68 +1 @@ -<<<<<<< HEAD - - - - 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" - - - - -======= -constructor: Animal run: functionAnimal.prototypeconstructor: Rabbit hide: functionRabbit.prototypeAnimalRabbitrabbit[[Prototype]][[Prototype]][[Prototype]]prototypeprototypecomparename: "White Rabbit" ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 494af4baf..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,13 +19,8 @@ User.staticMethod(); // true That actually does the same as assigning it as a function property: -<<<<<<< HEAD -```js -function User() { } -======= ```js run class User { } ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 User.staticMethod = function() { alert(this === User); @@ -130,15 +125,9 @@ That is the same as a direct assignment to `Article`: Article.publisher = "Ilya Kantor"; ``` -<<<<<<< HEAD -## Statics and inheritance - -Statics are inherited, we can access `Parent.method` as `Child.method`. -======= ## Inheritance of static properties and methods Static properties and methods are inherited. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For instance, `Animal.compare` and `Animal.planet` in the code below are inherited and accessible as `Rabbit.compare` and `Rabbit.planet`: @@ -185,22 +174,14 @@ rabbits[0].run(); // Black Rabbit runs with speed 5. alert(Rabbit.planet); // Earth ``` -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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) -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Here, let's check that: @@ -211,16 +192,6 @@ class Rabbit extends Animal {} // for static properties and methods alert(Rabbit.__proto__ === Animal); // true -<<<<<<< HEAD -// 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); -``` - -This way `Rabbit` has access to all static methods of `Animal`. -======= // for regular methods alert(Rabbit.prototype.__proto__ === Animal.prototype); // true ``` @@ -228,7 +199,6 @@ alert(Rabbit.prototype.__proto__ === Animal.prototype); // true ## 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## 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 8a4fbf4d9..b2340f06c 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 @@ -262,11 +262,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 -<<<<<<< HEAD -class CoffeeMachine extends CoffeeMachine() { -======= class MegaCoffeeMachine extends CoffeeMachine { ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 method() { *!* alert( this.#waterAmount ); // Error: can only access from CoffeeMachine @@ -275,11 +271,7 @@ class MegaCoffeeMachine extends CoffeeMachine { } ``` -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ````warn Private fields are special. @@ -330,11 +322,7 @@ Hiding complexity **It's always convenient when implementation details are hidden, and a simple, well-documented external interface is available.** -<<<<<<< HEAD -To hide internal interface we use either protected or public properties: -======= To hide an internal interface we use either protected or private properties: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 - 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 can only access those from inside the class. diff --git a/1-js/09-classes/05-extend-natives/article.md b/1-js/09-classes/05-extend-natives/article.md index fddc816bb..36c97b0cf 100644 --- a/1-js/09-classes/05-extend-natives/article.md +++ b/1-js/09-classes/05-extend-natives/article.md @@ -21,11 +21,7 @@ alert(filteredArr); // 10, 50 alert(filteredArr.isEmpty()); // false ``` -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 In the example above, ```js @@ -37,11 +33,7 @@ That's actually very cool, because we can keep using `PowerArray` methods furthe Even more, we can customize that behavior. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 If we'd like built-in methods like `map`, `filter` will return regular arrays, we can return `Array` in `Symbol.species`, like here: @@ -79,17 +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`. -<<<<<<< HEAD -But statics are an exception. Built-in classes don't inherit static properties from each other. - -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. -======= 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). 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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 99c8cf085..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,75 +1 @@ -<<<<<<< HEAD - - - - 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 - - - - -======= -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 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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/article.md b/1-js/09-classes/06-instanceof/article.md index 4621a6842..b9d652211 100644 --- a/1-js/09-classes/06-instanceof/article.md +++ b/1-js/09-classes/06-instanceof/article.md @@ -46,11 +46,7 @@ alert( arr instanceof Object ); // true Please note that `arr` also belongs to the `Object` class. That's because `Array` prototypically inherits from `Object`. -<<<<<<< HEAD -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`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 The algorithm of `obj instanceof Class` works roughly as follows: @@ -68,11 +64,7 @@ The algorithm of `obj instanceof Class` works roughly as follows: alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) is called ``` -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 In other words, compare: ```js @@ -106,11 +98,7 @@ By the way, there's also a method [objA.isPrototypeOf(objB)](mdn:js/object/isPro It's funny, but the `Class` constructor itself does not participate in the check! Only the chain of prototypes and `Class.prototype` matters. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Like here: @@ -194,13 +182,8 @@ alert( {}.toString.call(user) ); // [object User] For most environment-specific objects, there is such a property. Here are some browser specific examples: ```js run -<<<<<<< HEAD -// 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 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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 1b527ee2b..78bff9f12 100644 --- a/1-js/09-classes/06-instanceof/instanceof.svg +++ b/1-js/09-classes/06-instanceof/instanceof.svg @@ -1,55 +1 @@ -<<<<<<< HEAD - - - - instanceof.svg - Created with sketchtool. - - - - - Animal.prototype - - - - Object.prototype - - - - - Rabbit.prototype - - - - [[Prototype]] - - - - rabbit - - - - [[Prototype]] - - - [[Prototype]] - - - - null - - - [[Prototype]] - - - = Animal.prototype? - - - - - - - -======= -Animal.prototypeObject.prototypeRabbit.prototype[[Prototype]]rabbit[[Prototype]][[Prototype]]null[[Prototype]]= Animal.prototype? ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 3d68ae2c9..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,25 +100,14 @@ Please note that the call to the parent method `super.say()` from `sayHiMixin` l ![](mixin-inheritance.svg) -<<<<<<< HEAD -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]]`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## EventMixin Now let's make a mixin for real life. -<<<<<<< HEAD -The important feature of many objects is working with events. - -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. - -An event must have a name and, optionally, bundle some additional data. -======= 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. - 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. @@ -129,7 +115,6 @@ An important feature of many browser objects (for instance) is that they can gen - ...And the method `.off(name, handler)` that removes the `handler` listener. 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 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. @@ -186,12 +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. -<<<<<<< HEAD -======= - `.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`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Usage: @@ -216,11 +198,7 @@ menu.on("select", value => alert(`Value selected: ${value}`)); menu.choose("123"); // value selected ``` -<<<<<<< HEAD -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(...)`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 And the `eventMixin` can add such behavior to as many classes as we'd like, without interfering with the inheritance chain. @@ -228,16 +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. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 We can use mixins as a way to augment a class by adding multiple behaviors, like event-handling as we have seen above. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 diff --git a/1-js/09-classes/07-mixins/mixin-inheritance.svg b/1-js/09-classes/07-mixins/mixin-inheritance.svg index 1cda5b8b9..aaa8cb7d0 100644 --- a/1-js/09-classes/07-mixins/mixin-inheritance.svg +++ b/1-js/09-classes/07-mixins/mixin-inheritance.svg @@ -1,58 +1 @@ -<<<<<<< HEAD - - - - 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] - - - - -======= -sayHi: function sayBye: functionsayHiMixinsay: functionsayMixin[[Prototype]]constructor: User sayHi: function sayBye: functionUser.prototype[[Prototype]]name: ...user[[HomeObject] ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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 9bc47f9ef..9f200bab6 100644 --- a/1-js/10-error-handling/1-try-catch/article.md +++ b/1-js/10-error-handling/1-try-catch/article.md @@ -25,23 +25,14 @@ try { It works like this: 1. First, the code in `try {...}` is executed. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ![](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`. -<<<<<<< HEAD -Let's see more examples. -======= Let's look at some examples. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 - An errorless example: shows `alert` `(1)` and `(2)`: @@ -347,11 +338,7 @@ Now `catch` became a single place for all error handling: both for `JSON.parse` ## Rethrowing -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For example: @@ -607,11 +594,7 @@ Let's imagine we've got a fatal error outside of `try..catch`, and the script di 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. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 The syntax: 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 c2aec14c6..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,62 +1 @@ -<<<<<<< HEAD - - - - 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... - - - - -======= -BeginNo ErrorsAn error occured in the codeIgnore catch blockIgnore the rest of tryExecute catch blocktry { }// code... ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +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/article.md b/1-js/10-error-handling/2-custom-errors/article.md index 4762a7794..8c89e30ef 100644 --- a/1-js/10-error-handling/2-custom-errors/article.md +++ b/1-js/10-error-handling/2-custom-errors/article.md @@ -6,11 +6,7 @@ Our errors should support basic error properties like `message`, `name` and, pre 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. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## Extending Error @@ -29,13 +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. -<<<<<<< HEAD -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: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js // The "pseudocode" for the built-in Error class defined by JavaScript itself @@ -193,11 +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. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Let's call it `MyError`. @@ -232,11 +218,7 @@ 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. -<<<<<<< HEAD -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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 The scheme is like this: @@ -346,12 +328,6 @@ The approach is called "wrapping exceptions", because we take "low level" except ## Summary -<<<<<<< HEAD -- 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. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 diff --git a/1-js/11-async/01-callbacks/article.md b/1-js/11-async/01-callbacks/article.md index 66fedf981..ce29c3152 100644 --- a/1-js/11-async/01-callbacks/article.md +++ b/1-js/11-async/01-callbacks/article.md @@ -39,11 +39,7 @@ loadScript('/my/script.js'); The script is executed "asynchronously", as it starts loading now, but runs later, when the function has already finished. -<<<<<<< HEAD -The call initiates the script loading, then the execution continues. While the script is loading, the code below may finish executing, and if the loading takes time, other scripts may run meanwhile too. -======= If there's any code below `loadScript(…)`, it doesn't wait until the script loading finishes. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js loadScript('/my/script.js'); @@ -51,11 +47,7 @@ loadScript('/my/script.js'); // ... ``` -<<<<<<< HEAD -Now let's say we want to use the new script when it loads. It probably declares new functions, so we'd like to run them. -======= Let's say we need to use the new script as soon as it loads. It declares new functions, and we want to run them. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 But if we do that immediately after the `loadScript(…)` call, that wouldn't work: diff --git a/1-js/11-async/01-callbacks/callback-hell.svg b/1-js/11-async/01-callbacks/callback-hell.svg index b13d3cd7a..907f62c2a 100644 --- a/1-js/11-async/01-callbacks/callback-hell.svg +++ b/1-js/11-async/01-callbacks/callback-hell.svg @@ -1,354 +1 @@ -<<<<<<< HEAD - - - - callback-hell.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - loadScript - - - ( - - - '1.js' - - - , - - - - function - - - ( - - - error - - - , - - - - script - - - ) - - - - { - - - - - - - if - - - - ( - - - error - - - ) - - - - { - - - - - - handleError - - - ( - - - error - - - ); - - - - - - } - - - - else - - - - { - - - - - - // ... - - - - - - loadScript - - - ( - - - '2.js' - - - , - - - - function - - - ( - - - error - - - , - - - - script - - - ) - - - - { - - - - - - if - - - - ( - - - error - - - ) - - - - { - - - - - - handleError - - - ( - - - error - - - ); - - - - - - } - - - - else - - - - { - - - - - - // ... - - - - - - loadScript - - - ( - - - '3.js' - - - , - - - - function - - - ( - - - error - - - , - - - - script - - - ) - - - - { - - - - - - if - - - - ( - - - error - - - ) - - - - { - - - - - - handleError - - - ( - - - error - - - ); - - - - - - } - - - - else - - - - { - - - - - - // ...continue after all scripts are loaded (*) - - - - - - } - - - - - - }); - - - - - - } - - - - - - }) - - - - - - } - - - - - }); - - - - - - - - - - - - - - - - -======= - ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 + \ No newline at end of file diff --git a/1-js/11-async/02-promise-basics/promise-reject-1.svg b/1-js/11-async/02-promise-basics/promise-reject-1.svg index 5c5742334..809bc2430 100644 --- a/1-js/11-async/02-promise-basics/promise-reject-1.svg +++ b/1-js/11-async/02-promise-basics/promise-reject-1.svg @@ -1,31 +1 @@ -<<<<<<< HEAD - - - - promise-reject-1.svg - Created with sketchtool. - - - - - new Promise(executor) - - - state: "pending" - result: undefined - - - - reject(error) - - - - state: "rejected" - result: error - - - - -======= -new Promise(executor)state: "pending" result: undefinedreject(error)state: "rejected" result: error ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +new Promise(executor)state: "pending" result: undefinedreject(error)state: "rejected" result: error \ No newline at end of file diff --git a/1-js/11-async/02-promise-basics/promise-resolve-1.svg b/1-js/11-async/02-promise-basics/promise-resolve-1.svg index 0f5825370..07a2a95f6 100644 --- a/1-js/11-async/02-promise-basics/promise-resolve-1.svg +++ b/1-js/11-async/02-promise-basics/promise-resolve-1.svg @@ -1,31 +1 @@ -<<<<<<< HEAD - - - - promise-resolve-1.svg - Created with sketchtool. - - - - - new Promise(executor) - - - state: "pending" - result: undefined - - - - resolve("done") - - - - state: "fulfilled" - result: "done" - - - - -======= -new Promise(executor)state: "pending" result: undefinedresolve("done")state: "fulfilled" result: "done" ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +new Promise(executor)state: "pending" result: undefinedresolve("done")state: "fulfilled" result: "done" \ No newline at end of file diff --git a/1-js/11-async/02-promise-basics/promise-resolve-reject.svg b/1-js/11-async/02-promise-basics/promise-resolve-reject.svg index ef3d46761..428dfd845 100644 --- a/1-js/11-async/02-promise-basics/promise-resolve-reject.svg +++ b/1-js/11-async/02-promise-basics/promise-resolve-reject.svg @@ -1,40 +1 @@ -<<<<<<< HEAD - - - - promise-resolve-reject.svg - Created with sketchtool. - - - - - new Promise(executor) - - - state: "pending" - result: undefined - - - - - resolve(value) - - - reject(error) - - - - state: "fulfilled" - result: value - - - - state: "rejected" - result: error - - - - -======= -new Promise(executor)state: "pending" result: undefinedresolve(value)reject(error)state: "fulfilled" result: valuestate: "rejected" result: error ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +new Promise(executor)state: "pending" result: undefinedresolve(value)reject(error)state: "fulfilled" result: valuestate: "rejected" result: error \ No newline at end of file diff --git a/1-js/11-async/03-promise-chaining/01-then-vs-catch/solution.md b/1-js/11-async/03-promise-chaining/01-then-vs-catch/solution.md index bf1be9117..694165e69 100644 --- a/1-js/11-async/03-promise-chaining/01-then-vs-catch/solution.md +++ b/1-js/11-async/03-promise-chaining/01-then-vs-catch/solution.md @@ -1,8 +1,4 @@ -<<<<<<< HEAD A resposta breve é: **não, eles não são iguais**: -======= -The short answer is: **no, they are not equal**: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 A diferença é que se um erro ocorrer em `f1` ele será tratado pelo `.catch` neste caso: @@ -21,8 +17,4 @@ promise Isso é devido ao erro ser propagado pela cadeia, e no segundo código não há cadeia após `f1`. -<<<<<<< HEAD -Em outras palavras, `.then` passa resultados/erros para o próximo `.then/catch`. Então, no primeiro exemplo, há um `catch` em seguida, e no segundo exemplo não há, então o erro não é tratado. -======= -In other words, `.then` passes results/errors to the next `.then/catch`. So in the first example, there's a `catch` below, and in the second one there isn't, so the error is unhandled. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +Por outras palavras, `.then` passa resultados/erros para o próximo `.then/catch`. Então, no primeiro exemplo, há um `catch` embaixo, e no segundo exemplo não há, então o erro não é tratado. diff --git a/1-js/11-async/04-promise-error-handling/article.md b/1-js/11-async/04-promise-error-handling/article.md index 376044761..9f7159af9 100644 --- a/1-js/11-async/04-promise-error-handling/article.md +++ b/1-js/11-async/04-promise-error-handling/article.md @@ -1,11 +1,9 @@ # Error handling with promises -Asynchronous actions may sometimes fail: in case of an error the corresponding promise becomes rejected. For instance, `fetch` fails if the remote server is not available. We can use `.catch` to handle errors (rejections). +Promise chains are great at error handling. When a promise rejects, the control jumps to the closest rejection handler. That's very convenient in practice. -Promise chaining is great at that aspect. When a promise rejects, the control jumps to the closest rejection handler down the chain. That's very convenient in practice. - -For instance, in the code below the URL is wrong (no such server) and `.catch` handles the error: +For instance, in the code below the URL to `fetch` is wrong (no such site) and `.catch` handles the error: ```js run *!* @@ -15,17 +13,9 @@ fetch('https://no-such-server.blabla') // rejects .catch(err => alert(err)) // TypeError: failed to fetch (the text may vary) ``` -Or, maybe, everything is all right with the server, but the response is not valid JSON: +As you can see, the `.catch` doesn't have to be immediate. It may appear after one or maybe several `.then`. -```js run -fetch('/') // fetch works fine now, the server responds successfully -*!* - .then(response => response.json()) // rejects: the page is HTML, not a valid json -*/!* - .catch(err => alert(err)) // SyntaxError: Unexpected token < in JSON at position 0 -``` - -The easiest way to catch all errors is to append `.catch` to the end of chain: +Or, maybe, everything is all right with the site, but the response is not valid JSON. The easiest way to catch all errors is to append `.catch` to the end of chain: ```js run fetch('/article/promise-chaining/user.json') @@ -48,11 +38,11 @@ fetch('/article/promise-chaining/user.json') */!* ``` -Normally, `.catch` doesn't trigger at all, because there are no errors. But if any of the promises above rejects (a network problem or invalid json or whatever), then it would catch it. +Normally, such `.catch` doesn't trigger at all. But if any of the promises above rejects (a network problem or invalid json or whatever), then it would catch it. ## Implicit try..catch -The code of a promise executor and promise handlers has an "invisible `try..catch`" around it. If an error happens, it gets caught and treated as a rejection. +The code of a promise executor and promise handlers has an "invisible `try..catch`" around it. If an exception happens, it gets caught and treated as a rejection. For instance, this code: @@ -74,9 +64,9 @@ new Promise((resolve, reject) => { }).catch(alert); // Error: Whoops! ``` -The "invisible `try..catch`" around the executor automatically catches the error and treats it as a rejection. +The "invisible `try..catch`" around the executor automatically catches the error and turns it into rejected promise. -This happens not only in the executor, but in its handlers as well. If we `throw` inside a `.then` handler, that means a rejected promise, so the control jumps to the nearest error handler. +This happens not only in the executor function, but in its handlers as well. If we `throw` inside a `.then` handler, that means a rejected promise, so the control jumps to the nearest error handler. Here's an example: @@ -106,7 +96,7 @@ The final `.catch` not only catches explicit rejections, but also accidental err ## Rethrowing -As we already noticed, `.catch` behaves like `try..catch`. We may have as many `.then` handlers as we want, and then use a single `.catch` at the end to handle errors in all of them. +As we already noticed, `.catch` at the end of the chain is similar to `try..catch`. We may have as many `.then` handlers as we want, and then use a single `.catch` at the end to handle errors in all of them. In a regular `try..catch` we can analyze the error and maybe rethrow it if it can't be handled. The same thing is possible for promises. @@ -120,7 +110,7 @@ new Promise((resolve, reject) => { throw new Error("Whoops!"); -}).catch(function(error) { +}).catch(function(error) { alert("The error is handled, continue normally"); @@ -150,11 +140,7 @@ new Promise((resolve, reject) => { } }).then(function() { -<<<<<<< HEAD - /* never runs here */ -======= /* doesn't run here */ ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 }).catch(error => { // (**) alert(`The unknown error has occurred: ${error}`); @@ -163,128 +149,28 @@ new Promise((resolve, reject) => { }); ``` -Then the execution jumps from the first `.catch` `(*)` to the next one `(**)` down the chain. - -In the section below we'll see a practical example of rethrowing. - -## Fetch error handling example - -Let's improve error handling for the user-loading example. - -The promise returned by [fetch](mdn:api/WindowOrWorkerGlobalScope/fetch) rejects when it's impossible to make a request. For instance, a remote server is not available, or the URL is malformed. But if the remote server responds with error 404, or even error 500, then it's considered a valid response. - -What if the server returns a non-JSON page with error 500 in the line `(*)`? What if there's no such user, and github returns a page with error 404 at `(**)`? - -```js run -fetch('no-such-user.json') // (*) - .then(response => response.json()) - .then(user => fetch(`https://api.github.com/users/${user.name}`)) // (**) - .then(response => response.json()) - .catch(alert); // SyntaxError: Unexpected token < in JSON at position 0 - // ... -``` - - -As of now, the code tries to load the response as JSON no matter what and dies with a syntax error. You can see that by running the example above, as the file `no-such-user.json` doesn't exist. - -That's not good, because the error just falls through the chain, without details: what failed and where. - -So let's add one more step: we should check the `response.status` property that has HTTP status, and if it's not 200, then throw an error. - -```js run -class HttpError extends Error { // (1) - constructor(response) { - super(`${response.status} for ${response.url}`); - this.name = 'HttpError'; - this.response = response; - } -} - -function loadJson(url) { // (2) - return fetch(url) - .then(response => { - if (response.status == 200) { - return response.json(); - } else { - throw new HttpError(response); - } - }) -} - -loadJson('no-such-user.json') // (3) - .catch(alert); // HttpError: 404 for .../no-such-user.json -``` - -1. We make a custom class for HTTP Errors to distinguish them from other types of errors. Besides, the new class has a constructor that accepts `response` object and saves it in the error. So error-handling code will be able to access it. -2. Then we put together the requesting and error-handling code into a function that fetches the `url` *and* treats any non-200 status as an error. That's convenient, because we often need such logic. -3. Now `alert` shows a more helpful descriptive message. - -The great thing about having our own class for errors is that we can easily check for it in error-handling code. - -For instance, we can make a request, and then if we get 404 -- ask the user to modify the information. - -The code below loads a user with the given name from github. If there's no such user, then it asks for the correct name: - -```js run -function demoGithubUser() { - let name = prompt("Enter a name?", "iliakan"); - - return loadJson(`https://api.github.com/users/${name}`) - .then(user => { - alert(`Full name: ${user.name}.`); - return user; - }) - .catch(err => { -*!* - if (err instanceof HttpError && err.response.status == 404) { -*/!* - alert("No such user, please reenter."); - return demoGithubUser(); - } else { - throw err; // (*) - } - }); -} - -demoGithubUser(); -``` - -Please note: `.catch` here catches all errors, but it "knows how to handle" only `HttpError 404`. In that particular case it means that there's no such user, and `.catch` just retries in that case. - -For other errors, it has no idea what could go wrong. Maybe a programming error or something. So it just rethrows it in the line `(*)`. +The execution jumps from the first `.catch` `(*)` to the next one `(**)` down the chain. ## Unhandled rejections -What happens when an error is not handled? For instance, after the rethrow `(*)` in the example above. - -Or we could just forget to append an error handler to the end of the chain, like here: +What happens when an error is not handled? For instance, we forgot to append `.catch` to the end of the chain, like here: ```js untrusted run refresh new Promise(function() { noSuchFunction(); // Error here (no such function) }) .then(() => { - // zero or many promise handlers + // successful promise handlers, one or more }); // without .catch at the end! ``` -In case of an error, the promise state becomes "rejected", and the execution should jump to the closest rejection handler. But there is no such handler in the examples above. So the error gets "stuck". +In case of an error, the promise becomes rejected, and the execution should jump to the closest rejection handler. But there is none. So the error gets "stuck". There's no code to handle it. -<<<<<<< HEAD -<<<<<<< HEAD -In practice, just like with a regular unhandled errors, it means that something has terribly gone wrong, the script probably died. -======= -In practice, just like with regular unhandled errors in code, it means that something has terribly gone wrong. ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 - -Most JavaScript engines track such situations and generate a global error in that case. We can see it in the console. -======= In practice, just like with regular unhandled errors in code, it means that something has gone terribly wrong. What happens when a regular error occurs and is not caught by `try..catch`? The script dies with a message in the console. A similar thing happens with unhandled promise rejections. The JavaScript engine tracks such rejections and generates a global error in that case. You can see it in the console if you run the example above. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 In the browser we can catch such errors using the event `unhandledrejection`: @@ -308,59 +194,11 @@ If an error occurs, and there's no `.catch`, the `unhandledrejection` handler tr Usually such errors are unrecoverable, so our best way out is to inform the user about the problem and probably report the incident to the server. -In non-browser environments like Node.js there are other similar ways to track unhandled errors. - +In non-browser environments like Node.js there are other ways to track unhandled errors. ## Summary -<<<<<<< HEAD -- `.catch` handles promise rejections of all kinds: be it a `reject()` call, or an error thrown in a handler. -- We should place `.catch` exactly in places where we want to handle errors and know how to handle them. The handler should analyze errors (custom error classes help) and rethrow unknown ones. -- It's normal not to use `.catch` if we don't know how to handle errors (all errors are unrecoverable). -- In any case we should have the `unhandledrejection` event handler (for browsers, and analogs for other environments), to track unhandled errors and inform the user (and probably our server) about the them, so that our app never "just dies". - -And finally, if we have load-indication, then `.finally` is a great handler to stop it when the fetch is complete: - -```js run -function demoGithubUser() { - let name = prompt("Enter a name?", "iliakan"); - -*!* - document.body.style.opacity = 0.3; // (1) start the indication -*/!* - - return loadJson(`https://api.github.com/users/${name}`) -*!* - .finally(() => { // (2) stop the indication - document.body.style.opacity = ''; - return new Promise(resolve => setTimeout(resolve, 0)); // (*) - }) -*/!* - .then(user => { - alert(`Full name: ${user.name}.`); - return user; - }) - .catch(err => { - if (err instanceof HttpError && err.response.status == 404) { - alert("No such user, please reenter."); - return demoGithubUser(); - } else { - throw err; - } - }); -} - -demoGithubUser(); -``` - -Here on the line `(1)` we indicate loading by dimming the document. The method doesn't matter, could use any type of indication instead. - -When the promise is settled, be it a successful fetch or an error, `finally` triggers at the line `(2)` and stops the indication. - -There's a little browser trick `(*)` with returning a zero-timeout promise from `finally`. That's because some browsers (like Chrome) need "a bit time" outside promise handlers to paint document changes. So it ensures that the indication is visually stopped before going further on the chain. -======= - `.catch` handles errors in promises of all kinds: be it a `reject()` call, or an error thrown in a handler. - We should place `.catch` exactly in places where we want to handle errors and know how to handle them. The handler should analyze errors (custom error classes help) and rethrow unknown ones (maybe they are programming mistakes). - It's ok not to use `.catch` at all, if there's no way to recover from an error. - In any case we should have the `unhandledrejection` event handler (for browsers, and analogs for other environments) to track unhandled errors and inform the user (and probably our server) about them, so that our app never "just dies". ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 diff --git a/1-js/11-async/04-promise-error-handling/promise-then-chain.svg b/1-js/11-async/04-promise-error-handling/promise-then-chain.svg index a0f1522ab..0a3ea6d37 100644 --- a/1-js/11-async/04-promise-error-handling/promise-then-chain.svg +++ b/1-js/11-async/04-promise-error-handling/promise-then-chain.svg @@ -1,42 +1 @@ -<<<<<<< HEAD - - - - promise-then-chain.svg - Created with sketchtool. - - - - - .then - - - - new Promise - - - resolve(1) - - - return 2 - - - - - .then - - - return 4 - - - - - .then - - - - - -======= -.thennew Promiseresolve(1)return 2.thenreturn 4.then ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +.thennew Promiseresolve(1)return 2.thenreturn 4.then \ No newline at end of file diff --git a/1-js/11-async/04-promise-error-handling/promise-then-many.svg b/1-js/11-async/04-promise-error-handling/promise-then-many.svg index 119a5a209..ce8dc1c0c 100644 --- a/1-js/11-async/04-promise-error-handling/promise-then-many.svg +++ b/1-js/11-async/04-promise-error-handling/promise-then-many.svg @@ -1,36 +1 @@ -<<<<<<< HEAD - - - - promise-then-many.svg - Created with sketchtool. - - - - - .then - - - - new Promise - - - resolve(1) - - - - - .then - - - - - .then - - - - - -======= -.thennew Promiseresolve(1).then.then ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +.thennew Promiseresolve(1).then.then \ No newline at end of file diff --git a/1-js/11-async/05-promise-api/article.md b/1-js/11-async/05-promise-api/article.md index cd7423a79..7338c7af0 100644 --- a/1-js/11-async/05-promise-api/article.md +++ b/1-js/11-async/05-promise-api/article.md @@ -75,15 +75,9 @@ The syntax is: let promise = Promise.all([...promises...]); ``` -<<<<<<< HEAD -It takes an array of promises (technically can be any iterable, but usually an array) and returns a new promise. - -The new promise resolves when all listed promises are settled and has an array of their results. -======= `Promise.all` takes an array of promises (it technically can be any iterable, but is usually an array) and returns a new promise. The new promise resolves when all listed promises are settled, and the array of their results becomes its result. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For instance, the `Promise.all` below settles after 3 seconds, and then its result is an array `[1, 2, 3]`: @@ -95,11 +89,7 @@ Promise.all([ ]).then(alert); // 1,2,3 when promises are ready: each promise contributes an array member ``` -<<<<<<< HEAD -Please note that the relative order is the same. Even though the first promise takes the longest time to resolve, it is still first in the array of results. -======= Please note that the order of the resulting array members is the same as in its source promises. Even though the first promise takes the longest time to resolve, it's still first in the array of results. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 A common trick is to map an array of job data into an array of promises, and then wrap that into `Promise.all`. @@ -122,11 +112,7 @@ Promise.all(requests) )); ``` -<<<<<<< HEAD -A more real-life example with fetching user information for an array of github users by their names (or we could fetch an array of goods by their ids, the logic is same): -======= A bigger example with fetching user information for an array of GitHub users by their names (we could fetch an array of goods by their ids, the logic is identical): ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run let names = ['iliakan', 'remy', 'jeresig']; @@ -166,11 +152,7 @@ Here the second promise rejects in two seconds. That leads to an immediate rejec The important detail is that promises provide no way to "cancel" or "abort" their execution. So other promises continue to execute, and then eventually settle, but all their results are ignored. -<<<<<<< HEAD -There are ways to avoid this: we can either write additional code to `clearTimeout` (or otherwise cancel) the promises in case of an error, or we can make errors show up as members in the resulting array (see the task below this chapter about it). -======= For example, if there are multiple `fetch` calls, like in the example above, and one fails, the others will still continue to execute, but `Promise.all` won't watch them anymore. They will probably settle, but their results will be ignored. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ````smart header="`Promise.all(...)` allows non-promise items in `iterable`" Normally, `Promise.all(...)` accepts an iterable (in most cases an array) of promises. But if any of those objects is not a promise, it's wrapped in `Promise.resolve`. @@ -182,25 +164,13 @@ Promise.all([ new Promise((resolve, reject) => { setTimeout(() => resolve(1), 1000) }), -<<<<<<< HEAD - 2, // treated as Promise.resolve(2) - 3 // treated as Promise.resolve(3) -======= 2, 3 ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ]).then(alert); // 1, 2, 3 ``` So we are able to pass non-promise values to `Promise.all` where convenient. -<<<<<<< HEAD -```` - -## Promise.race - -Similar to `Promise.all`, it takes an iterable of promises, but instead of waiting for all of them to finish, it waits for the first result (or error), and goes on with it. -======= `Promise.all` rejects as a whole if any promise rejects. That's good for "all or nothing" cases, when we need *all* results successful to proceed: ```js @@ -278,7 +248,6 @@ Now we can use `Promise.allSettled` to get the results of *all* given promises, ## Promise.race Similar to `Promise.all`, but waits only for the first settled promise and gets its result (or error). ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 The syntax is: @@ -296,9 +265,6 @@ Promise.race([ ]).then(alert); // 1 ``` -<<<<<<< HEAD -So, the first result/error becomes the result of the whole `Promise.race`. After the first settled promise "wins the race", all further results/errors are ignored. -======= The first promise here was fastest, so it became the result. After the first settled promise "wins the race", all further results/errors are ignored. @@ -354,18 +320,11 @@ let promise = new Promise((resolve, reject) => reject(error)); ``` In practice, this method is almost never used. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ## Summary There are 4 static methods of `Promise` class: -<<<<<<< HEAD -1. `Promise.resolve(value)` -- makes a resolved promise with the given value. -2. `Promise.reject(error)` -- makes a rejected promise with the given error. -3. `Promise.all(promises)` -- waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, then it becomes the error of `Promise.all`, and all other results are ignored. -4. `Promise.race(promises)` -- waits for the first promise to settle, and its result/error becomes the outcome. -======= 1. `Promise.all(promises)` -- waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, it becomes the error of `Promise.all`, and all other results are ignored. 2. `Promise.allSettled(promises)` (recently added method) -- waits for all promises to settle and returns their results as an array of objects with: - `status`: `"fulfilled"` or `"rejected"` @@ -373,6 +332,5 @@ There are 4 static methods of `Promise` class: 3. `Promise.race(promises)` -- waits for the first promise to settle, and its result/error becomes the outcome. 4. `Promise.resolve(value)` -- makes a resolved promise with the given value. 5. `Promise.reject(error)` -- makes a rejected promise with the given error. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Of these four, `Promise.all` is the most common in practice. diff --git a/1-js/11-async/06-promisify/article.md b/1-js/11-async/06-promisify/article.md index 8ffe1a055..75969463a 100644 --- a/1-js/11-async/06-promisify/article.md +++ b/1-js/11-async/06-promisify/article.md @@ -2,13 +2,7 @@ "Promisification" is a long word for a simple transformation. It's the conversion of a function that accepts a callback into a function that returns a promise. -<<<<<<< HEAD -In other words, we create a wrapper-function that does the same, internally calling the original one, but returns a promise. - -Such transforms are often needed in real-life, as many functions and libraries are callback-based. But promises are more convenient. So it makes sense to promisify those. -======= Such transformations are often required in real-life, as many functions and libraries are callback-based. But promises are more convenient, so it makes sense to promisify them. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For instance, we have `loadScript(src, callback)` from the chapter . @@ -27,11 +21,7 @@ function loadScript(src, callback) { // loadScript('path/script.js', (err, script) => {...}) ``` -<<<<<<< HEAD -Let's promisify it. The new `loadScriptPromise(src)` function will do the same, but accept only `src` (no callback) and return a promise. -======= Let's promisify it. The new `loadScriptPromise(src)` function achieves the same result, but it accepts only `src` (no `callback`) and returns a promise. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js let loadScriptPromise = function(src) { @@ -51,13 +41,7 @@ Now `loadScriptPromise` fits well in our promise-based code. As we can see, it delegates all the work to the original `loadScript`, providing its own callback that translates to promise `resolve/reject`. -<<<<<<< HEAD -As we may need to promisify many functions, it makes sense to use a helper. - -That's actually very simple -- `promisify(f)` below takes a to-promisify function `f` and returns a wrapper function. -======= In practice we'll probably need to promisify many functions, so it makes sense to use a helper. We'll call it `promisify(f)`: it accepts a to-promisify function `f` and returns a wrapper function. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 That wrapper does the same as in the code above: returns a promise and passes the call to the original `f`, tracking the result in a custom callback: @@ -117,11 +101,7 @@ f = promisify(f, true); f(...).then(arrayOfResults => ..., err => ...) ``` -<<<<<<< HEAD -In some cases, `err` may be absent at all: `callback(result)`, or there's something exotic in the callback format, then we can promisify such functions manually. -======= For more exotic callback formats, like those without `err` at all: `callback(result)`, we can promisify such functions manually without using the helper. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 There are also modules with a bit more flexible promisification functions, e.g. [es6-promisify](https://github.com/digitaldesignlabs/es6-promisify). In Node.js, there's a built-in `util.promisify` function for that. diff --git a/1-js/11-async/07-microtask-queue/article.md b/1-js/11-async/07-microtask-queue/article.md index 156f05453..7d14acf72 100644 --- a/1-js/11-async/07-microtask-queue/article.md +++ b/1-js/11-async/07-microtask-queue/article.md @@ -3,15 +3,9 @@ Promise handlers `.then`/`.catch`/`.finally` are always asynchronous. -<<<<<<< HEAD -Even when a Promise is immediately resolved, the code on the lines *below* your `.then`/`.catch`/`.finally` will still execute first. - -Here's the code that demonstrates it: -======= Even when a Promise is immediately resolved, the code on the lines *below* `.then`/`.catch`/`.finally` will still execute before these handlers. Here's a demo: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run let promise = Promise.resolve(); @@ -131,19 +125,11 @@ As a logical consequence, macrotasks are handled only when promises give the eng ## Unhandled rejection -<<<<<<< HEAD -Remember "unhandled rejection" event from the chapter ? - -Now, with the understanding of microtasks, we can formalize it. - -**"Unhandled rejection" is when a promise error is not handled at the end of the microtask queue.** -======= Remember the `unhandledrejection` event from the article ? Now we can see exactly how JavaScript finds out that there was an unhandled rejection. **An "unhandled rejection" occurs when a promise error is not handled at the end of the microtask queue.** ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For instance, consider this code: @@ -155,13 +141,7 @@ window.addEventListener('unhandledrejection', event => { }); ``` -<<<<<<< HEAD -We create a rejected `promise` and do not handle the error. So we have the "unhandled rejection" event (printed in browser console too). - -We wouldn't have it if we added `.catch`, like this: -======= But if we forget to add `.catch`, then, after the microtask queue is empty, the engine triggers the event: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run let promise = Promise.reject(new Error("Promise Failed!")); @@ -185,15 +165,6 @@ setTimeout(() => promise.catch(err => alert('caught'))); window.addEventListener('unhandledrejection', event => alert(event.reason)); ``` -<<<<<<< HEAD -Now the unhandled rejction appears again. Why? Because `unhandledrejection` triggers when the microtask queue is complete. The engine examines promises and, if any of them is in "rejected" state, then the event is generated. - -In the example, the `.catch` added by `setTimeout` triggers too, of course it does, but later, after `unhandledrejection` has already occurred. - -## Summary - -- Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (v8 term). -======= Now, if we run it, we'll see `Promise Failed!` first and then `caught`. If we didn't know about the microtasks queue, we could wonder: "Why did `unhandledrejection` handler run? We did catch and handle the error!" @@ -201,7 +172,6 @@ If we didn't know about the microtasks queue, we could wonder: "Why did `unhandl But now we understand that `unhandledrejection` is generated when the microtask queue is complete: the engine examines promises and, if any of them is in the "rejected" state, then the event triggers. In the example above, `.catch` added by `setTimeout` also triggers. But it does so later, after `unhandledrejection` has already occurred, so it doesn't change anything. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 **So, `.then/catch/finally` are called after the current code is finished.** @@ -209,20 +179,10 @@ In the example above, `.catch` added by `setTimeout` also triggers. But it does - There's also a "macrotask queue" that keeps various events, network operation results, `setTimeout`-scheduled calls, and so on. These are also called "macrotasks" (v8 term). -<<<<<<< HEAD - The engine uses the macrotask queue to handle them in the appearance order. - - **Macrotasks run after the code is finished *and* after the microtask queue is empty.** -======= Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (ES8 term). So `.then/catch/finally` handlers are always called after the current code is finished. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 In other words, they have lower priority. -<<<<<<< HEAD -So the order is: regular code, then promise handling, then everything else, like events etc. -======= In most Javascript engines, including browsers and Node.js, the concept of microtasks is closely tied with the "event loop" and "macrotasks". As these have no direct relation to promises, they are covered in another part of the tutorial, in the article . ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 diff --git a/1-js/11-async/07-microtask-queue/promiseQueue.svg b/1-js/11-async/07-microtask-queue/promiseQueue.svg index dc353e0dd..7f2189849 100644 --- a/1-js/11-async/07-microtask-queue/promiseQueue.svg +++ b/1-js/11-async/07-microtask-queue/promiseQueue.svg @@ -1,47 +1 @@ -<<<<<<< HEAD - - - - promiseQueue.svg - Created with sketchtool. - - - - promise - . - then - ( - handler - ); - - - ... - - - alert - ( - "code finished" - ); - - - - handler enqueued - - - queued handler runs - - - - - - - - script execution finished - - - - - -======= -promise . then ( handler ); ... alert ( "code finished" );handler enqueuedqueued handler runsscript execution finished ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +promise . then ( handler ); ... alert ( "code finished" );handler enqueuedqueued handler runsscript execution finished \ No newline at end of file diff --git a/1-js/11-async/08-async-await/article.md b/1-js/11-async/08-async-await/article.md index af1608a66..23acc477e 100644 --- a/1-js/11-async/08-async-await/article.md +++ b/1-js/11-async/08-async-await/article.md @@ -14,11 +14,7 @@ async function f() { The word "async" before a function means one simple thing: a function always returns a promise. Even If a function actually returns a non-promise value, prepending the function definition with the "async" keyword directs JavaScript to automatically wrap that value in a resolved promise. -<<<<<<< HEAD -For instance, the code above returns a resolved promise with the result of `1`, let's test it: -======= For instance, this function returns a resolved promise with the result of `1`; let's test it: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run async function f() { @@ -28,11 +24,7 @@ async function f() { f().then(alert); // 1 ``` -<<<<<<< HEAD -...We could explicitly return a promise, that would be the same as: -======= ...We could explicitly return a promise, which would be the same: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run async function f() { @@ -332,13 +324,8 @@ The `async` keyword before a function has two effects: The `await` keyword before a promise makes JavaScript wait until that promise settles, and then: -<<<<<<< HEAD -1. If it's an error, the exception is generated, same as if `throw error` were called at that very place. -2. Otherwise, it returns the result, so we can assign it to a value. -======= 1. If it's an error, the exception is generated — same as if `throw error` were called at that very place. 2. Otherwise, it returns the result. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Together they provide a great framework to write asynchronous code that is easy to both read and write. diff --git a/1-js/12-generators-iterators/1-generators/01-pseudo-random-generator/solution.md b/1-js/12-generators-iterators/1-generators/01-pseudo-random-generator/solution.md index 2110b53ad..af2ad0eed 100644 --- a/1-js/12-generators-iterators/1-generators/01-pseudo-random-generator/solution.md +++ b/1-js/12-generators-iterators/1-generators/01-pseudo-random-generator/solution.md @@ -35,8 +35,4 @@ alert(generator()); // 282475249 alert(generator()); // 1622650073 ``` -<<<<<<< HEAD -That's fine for this context. But then we loose ability to iterate with `for..of` and to use generator composition, that may be useful elsewhere. -======= That also works. But then we lose ability to iterate with `for..of` and to use generator composition, that may be useful elsewhere. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 diff --git a/1-js/12-generators-iterators/1-generators/article.md b/1-js/12-generators-iterators/1-generators/article.md index 3b05d8725..e77ceb66d 100644 --- a/1-js/12-generators-iterators/1-generators/article.md +++ b/1-js/12-generators-iterators/1-generators/article.md @@ -1,9 +1,8 @@ - # Generators Regular functions return only one, single value (or nothing). -Generators can return ("yield") multiple values, possibly an infinite number of values, one after another, on-demand. They work great with [iterables](info:iterable), allowing to create data streams with ease. +Generators can return ("yield") multiple values, one after another, on-demand. They work great with [iterables](info:iterable), allowing to create data streams with ease. ## Generator functions @@ -19,24 +18,33 @@ function* generateSequence() { } ``` -When `generateSequence()` is called, it does not execute the code. Instead, it returns a special object, called "generator". +Generator functions behave differently from regular ones. When such function is called, it doesn't run its code. Instead it returns a special object, called "generator object", to manage the execution. + +Here, take a look: + +```js run +function* generateSequence() { + yield 1; + yield 2; + return 3; +} -```js // "generator function" creates "generator object" let generator = generateSequence(); +*!* +alert(generator); // [object Generator] +*/!* ``` -The `generator` object can be perceived as a "frozen function call": +The function code execution hasn't started yet: ![](generateSequence-1.svg) -<<<<<<< HEAD -Upon creation, the code execution is paused at the very beginning. -======= The main method of a generator is `next()`. When called, it runs the execution until the nearest `yield ` statement (`value` can be omitted, then it's `undefined`). Then the function execution pauses, and the yielded `value` is returned to the outer code. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 -The main method of a generator is `next()`. When called, it resumes execution till the nearest `yield ` statement. Then the execution pauses, and the value is returned to the outer code. +The result of `next()` is always an object with two properties: +- `value`: the yielded value. +- `done`: `true` if the function code has finished, otherwise `false`. For instance, here we create the generator and get its first yielded value: @@ -56,15 +64,11 @@ let one = generator.next(); alert(JSON.stringify(one)); // {value: 1, done: false} ``` -The result of `next()` is always an object: -- `value`: the yielded value. -- `done`: `false` if the code is not finished yet, otherwise `true`. - -As of now, we got the first value only: +As of now, we got the first value only, and the function execution is on the second line: ![](generateSequence-2.svg) -Let's call `generator.next()` again. It resumes the execution and returns the next `yield`: +Let's call `generator.next()` again. It resumes the code execution and returns the next `yield`: ```js let two = generator.next(); @@ -86,18 +90,10 @@ alert(JSON.stringify(three)); // {value: 3, *!*done: true*/!*} Now the generator is done. We should see it from `done:true` and process `value:3` as the final result. -<<<<<<< HEAD -New calls `generator.next()` don't make sense any more. If we make them, they return the same object: `{done: true}`. - -There's no way to "roll back" a generator. But we can create another one by calling `generateSequence()`. - -So far, the most important thing to understand is that generator functions, unlike regular function, do not run the code. They serve as "generator factories". Running `function*` returns a generator, and then we ask it for values. -======= New calls to `generator.next()` don't make sense any more. If we do them, they return the same object: `{done: true}`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```smart header="`function* f(…)` or `function *f(…)`?" -That's a minor religious question, both syntaxes are correct. +Both syntaxes are correct. But usually the first syntax is preferred, as the star `*` denotes that it's a generator function, it describes the kind, not the name, so it should stick with the `function` keyword. ``` @@ -122,11 +118,11 @@ for(let value of generator) { } ``` -That's a much better-looking way to work with generators than calling `.next().value`, right? +Looks a lot nicer than calling `.next().value`, right? ...But please note: the example above shows `1`, then `2`, and that's all. It doesn't show `3`! -It's because for-of iteration ignores the last `value`, when `done: true`. So, if we want all results to be shown by `for..of`, we must return them with `yield`: +It's because `for..of` iteration ignores the last `value`, when `done: true`. So, if we want all results to be shown by `for..of`, we must return them with `yield`: ```js run function* generateSequence() { @@ -144,11 +140,7 @@ for(let value of generator) { } ``` -<<<<<<< HEAD -Naturally, as generators are iterable, we can call all related functionality, e.g. the spread operator `...`: -======= As generators are iterable, we can call all related functionality, e.g. the spread syntax `...`: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js run function* generateSequence() { @@ -162,13 +154,9 @@ let sequence = [0, ...generateSequence()]; alert(sequence); // 0, 1, 2, 3 ``` -<<<<<<< HEAD -In the code above, `...generateSequence()` turns the iterable into array of items (read more about the spread operator in the chapter [](info:rest-parameters-spread-operator#spread-operator)) -======= In the code above, `...generateSequence()` turns the iterable generator object into an array of items (read more about the spread syntax in the chapter [](info:rest-parameters-spread#spread-syntax)) ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 -## Using generators instead of iterables +## Using generators for iterables Some time ago, in the chapter [](info:iterable) we created an iterable `range` object that returns values `from..to`. @@ -179,7 +167,7 @@ let range = { from: 1, to: 5, - // for..of calls this method once in the very beginning + // for..of range calls this method once in the very beginning [Symbol.iterator]() { // ...it returns the iterator object: // onward, for..of works only with that object, asking it for next values @@ -200,28 +188,13 @@ let range = { } }; +// iteration over range returns numbers from range.from to range.to alert([...range]); // 1,2,3,4,5 ``` -Using a generator to make iterable sequences is so much more elegant: - -```js run -function* generateSequence(start, end) { - for (let i = start; i <= end; i++) { - yield i; - } -} - -let sequence = [...generateSequence(1,5)]; - -alert(sequence); // 1, 2, 3, 4, 5 -``` - -...But what if we'd like to keep a custom `range` object? - -## Converting Symbol.iterator to generator +We can use a generator function for iteration by providing it as `Symbol.iterator`. -We can get the best from both worlds by providing a generator as `Symbol.iterator`: +Here's the same `range`, but much more compact: ```js run let range = { @@ -238,45 +211,24 @@ let range = { alert( [...range] ); // 1,2,3,4,5 ``` -<<<<<<< HEAD -The `range` object is now iterable. - -That works pretty well, because when `range[Symbol.iterator]` is called: -- it returns an object (now a generator) -- that has `.next()` method (yep, a generator has it) -- that returns values in the form `{value: ..., done: true/false}` (check, exactly what generator does). -======= That works, because `range[Symbol.iterator]()` now returns a generator, and generator methods are exactly what `for..of` expects: - it has a `.next()` method - that returns values in the form `{value: ..., done: true/false}` That's not a coincidence, of course. Generators were added to JavaScript language with iterators in mind, to implement them easily. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 - -That's not a coincidence, of course. Generators aim to make iterables easier, so we can see that. -The last variant with a generator is much more concise than the original iterable code, and keeps the same functionality. +The variant with a generator is much more concise than the original iterable code of `range`, and keeps the same functionality. -```smart header="Generators may continue forever" +```smart header="Generators may generate values forever" In the examples above we generated finite sequences, but we can also make a generator that yields values forever. For instance, an unending sequence of pseudo-random numbers. -<<<<<<< HEAD -That surely would require a `break` in `for..of`, otherwise the loop would repeat forever and hang. -======= That surely would require a `break` (or `return`) in `for..of` over such generator. Otherwise, the loop would repeat forever and hang. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ``` ## Generator composition Generator composition is a special feature of generators that allows to transparently "embed" generators in each other. -<<<<<<< HEAD -For instance, we'd like to generate a sequence of: -- digits `0..9` (character codes 48..57), -- followed by alphabet letters `a..z` (character codes 65..90) -- followed by uppercased letters `A..Z` (character codes 97..122) -======= For instance, we have a function that generates a sequence of numbers: ```js @@ -287,22 +239,16 @@ function* generateSequence(start, end) { Now we'd like to reuse it to generate a more complex sequence: - first, digits `0..9` (with character codes 48..57), -<<<<<<< HEAD -- followed by alphabet letters `A..Z` (character codes 65..90) -- followed by uppercased letters `a..z` (character codes 97..122) ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 -======= - followed by uppercase alphabet letters `A..Z` (character codes 65..90) - followed by lowercase alphabet letters `a..z` (character codes 97..122) ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 - -Then we plan to create passwords by selecting characters from it (could add syntax characters as well), but need to generate the sequence first. -We already have `function* generateSequence(start, end)`. Let's reuse it to deliver 3 sequences one after another, together they are exactly what we need. +We can use this sequence e.g. to create passwords by selecting characters from it (could add syntax characters as well), but let's generate it first. In a regular function, to combine results from multiple other functions, we call them, store the results, and then join at the end. -For generators, we can do better, like this: +For generators, there's a special `yield*` syntax to "embed" (compose) one generator into another. + +The composed generator: ```js run function* generateSequence(start, end) { @@ -333,7 +279,7 @@ for(let code of generatePasswordCodes()) { alert(str); // 0..9A..Za..z ``` -The special `yield*` directive in the example is responsible for the composition. It *delegates* the execution to another generator. Or, to say it simple, it runs generators and transparently forwards their yields outside, as if they were done by the calling generator itself. +The `yield*` directive *delegates* the execution to another generator. This term means that `yield* gen` iterates over the generator `gen` and transparently forwards its yields outside. As if the values were yielded by the outer generator. The result is the same as if we inlined the code from nested generators: @@ -366,19 +312,11 @@ for(let code of generateAlphaNum()) { alert(str); // 0..9A..Za..z ``` -A generator composition is a natural way to insert a flow of one generator into another. - -It works even if the flow of values from the nested generator is infinite. It's simple and doesn't use extra memory to store intermediate results. +A generator composition is a natural way to insert a flow of one generator into another. It doesn't use extra memory to store intermediate results. ## "yield" is a two-way street -<<<<<<< HEAD -Till this moment, generators were like "iterators on steroids". And that's how they are often used. - -But in fact they are much more powerful and flexible. -======= Until this moment, generators were similar to iterable objects, with a special syntax to generate values. But in fact they are much more powerful and flexible. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 That's because `yield` is a two-way street: it not only returns the result to the outside, but also can pass the value inside the generator. @@ -390,7 +328,7 @@ Let's see an example: function* gen() { *!* // Pass a question to the outer code and wait for an answer - let result = yield "2 + 2?"; // (*) + let result = yield "2 + 2 = ?"; // (*) */!* alert(result); @@ -405,13 +343,6 @@ generator.next(4); // --> pass the result into the generator ![](genYield2.svg) -<<<<<<< HEAD -1. The first call `generator.next()` is always without an argument. It starts the execution and returns the result of the first `yield` ("2+2?"). At this point the generator pauses the execution (still on that line). -2. Then, as shown at the picture above, the result of `yield` gets into the `question` variable in the calling code. -3. On `generator.next(4)`, the generator resumes, and `4` gets in as the result: `let result = 4`. - -Please note, the outer code does not have to immediately call`next(4)`. It may take time to calculate the value. This is also a valid code: -======= 1. The first call `generator.next()` should be always made without an argument (the argument is ignored if passed). It starts the execution and returns the result of the first `yield "2+2=?"`. At this point the generator pauses the execution, while staying on the line `(*)`. 2. Then, as shown at the picture above, the result of `yield` gets into the `question` variable in the calling code. 3. On `generator.next(4)`, the generator resumes, and `4` gets in as the result: `let result = 4`. @@ -419,33 +350,32 @@ Please note, the outer code does not have to immediately call`next(4)`. It may t Please note, the outer code does not have to immediately call `next(4)`. It may take time. That's not a problem: the generator will wait. For instance: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```js // resume the generator after some time setTimeout(() => generator.next(4), 1000); ``` -The syntax may seem a bit odd. It's quite uncommon for a function and the calling code to pass values around to each other. But that's exactly what's going on. +As we can see, unlike regular functions, a generator and the calling code can exchange results by passing values in `next/yield`. To make things more obvious, here's another example, with more calls: ```js run function* gen() { - let ask1 = yield "2 + 2?"; + let ask1 = yield "2 + 2 = ?"; alert(ask1); // 4 - let ask2 = yield "3 * 3?" + let ask2 = yield "3 * 3 = ?" alert(ask2); // 9 } let generator = gen(); -alert( generator.next().value ); // "2 + 2?" +alert( generator.next().value ); // "2 + 2 = ?" -alert( generator.next(4).value ); // "3 * 3?" +alert( generator.next(4).value ); // "3 * 3 = ?" alert( generator.next(9).done ); // true ``` @@ -470,12 +400,12 @@ As we observed in the examples above, the outer code may pass a value into the g To pass an error into a `yield`, we should call `generator.throw(err)`. In that case, the `err` is thrown in the line with that `yield`. -For instance, here the yield of `"2 + 2?"` leads to an error: +For instance, here the yield of `"2 + 2 = ?"` leads to an error: ```js run function* gen() { try { - let result = yield "2 + 2?"; // (1) + let result = yield "2 + 2 = ?"; // (1) alert("The execution does not reach here, because the exception is thrown above"); } catch(e) { @@ -500,7 +430,7 @@ The current line of the calling code is the line with `generator.throw`, labelle ```js run function* generate() { - let result = yield "2 + 2?"; // Error in this line + let result = yield "2 + 2 = ?"; // Error in this line } let generator = generate(); @@ -520,16 +450,12 @@ If we don't catch the error there, then, as usual, it falls through to the outer ## Summary -- Generators are created by generator functions `function*(…) {…}`. +- Generators are created by generator functions `function* f(…) {…}`. - Inside generators (only) there exists a `yield` operator. - The outer code and the generator may exchange results via `next/yield` calls. -In modern JavaScript, generators are rarely used. But sometimes they come in handy, because the ability of a function to exchange data with the calling code during the execution is quite unique. +In modern JavaScript, generators are rarely used. But sometimes they come in handy, because the ability of a function to exchange data with the calling code during the execution is quite unique. And, surely, they are great for making iterable objects. -<<<<<<< HEAD -Also, in the next chapter we'll learn async generators, which are used to read streams of asynchronously generated data in `for` loop. -======= Also, in the next chapter we'll learn async generators, which are used to read streams of asynchronously generated data (e.g paginated fetches over a network) in `for await ... of` loops. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 -In web-programming we often work with streamed data, e.g. need to fetch paginated results, so that's a very important use case. +In web-programming we often work with streamed data, so that's another very important use case. diff --git a/1-js/12-generators-iterators/1-generators/genYield2-2.svg b/1-js/12-generators-iterators/1-generators/genYield2-2.svg index 2ffc06674..41f163364 100644 --- a/1-js/12-generators-iterators/1-generators/genYield2-2.svg +++ b/1-js/12-generators-iterators/1-generators/genYield2-2.svg @@ -1,73 +1 @@ -<<<<<<< HEAD - - - - genYield2-2.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "2 + 2?" - - - - - "3 * 3?" - - - . - next - ( - 4 - ) - - - - - . - next - ( - 9 - ) - - - Generator - - - Calling code - - - - -======= -"2 + 2 = ?""3 * 3 = ?". next ( 4 ). next ( 9 )GeneratorCalling code ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +"2 + 2 = ?""3 * 3 = ?". next ( 4 ). next ( 9 )GeneratorCalling code \ No newline at end of file diff --git a/1-js/12-generators-iterators/1-generators/genYield2.svg b/1-js/12-generators-iterators/1-generators/genYield2.svg index 0cf42d0b5..611328755 100644 --- a/1-js/12-generators-iterators/1-generators/genYield2.svg +++ b/1-js/12-generators-iterators/1-generators/genYield2.svg @@ -1,45 +1 @@ -<<<<<<< HEAD - - - - genYield2.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - question = "2 + 2?" - - - - - Generator - - - Calling code - - - .next(4) - - - - -======= -question = "2 + 2 = ?"GeneratorCalling code.next(4) ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +question = "2 + 2 = ?"GeneratorCalling code.next(4) \ No newline at end of file diff --git a/1-js/12-generators-iterators/1-generators/generateSequence-1.svg b/1-js/12-generators-iterators/1-generators/generateSequence-1.svg index 6f7b433c4..0a00c4712 100644 --- a/1-js/12-generators-iterators/1-generators/generateSequence-1.svg +++ b/1-js/12-generators-iterators/1-generators/generateSequence-1.svg @@ -1,31 +1 @@ -<<<<<<< HEAD - - - - generateSequence-1.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - -======= - ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 + \ No newline at end of file diff --git a/1-js/12-generators-iterators/1-generators/generateSequence-2.svg b/1-js/12-generators-iterators/1-generators/generateSequence-2.svg index dc8cd4c36..dc2225d8a 100644 --- a/1-js/12-generators-iterators/1-generators/generateSequence-2.svg +++ b/1-js/12-generators-iterators/1-generators/generateSequence-2.svg @@ -1,34 +1 @@ -<<<<<<< HEAD - - - - generateSequence-2.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - {value: 1, done: false} - - - - -======= -{value: 1, done: false} ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +{value: 1, done: false} \ No newline at end of file diff --git a/1-js/12-generators-iterators/1-generators/generateSequence-3.svg b/1-js/12-generators-iterators/1-generators/generateSequence-3.svg index 39d1ddab2..68bf8d268 100644 --- a/1-js/12-generators-iterators/1-generators/generateSequence-3.svg +++ b/1-js/12-generators-iterators/1-generators/generateSequence-3.svg @@ -1,34 +1 @@ -<<<<<<< HEAD - - - - generateSequence-3.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - {value: 2, done: false} - - - - -======= -{value: 2, done: false} ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +{value: 2, done: false} \ No newline at end of file diff --git a/1-js/12-generators-iterators/1-generators/generateSequence-4.svg b/1-js/12-generators-iterators/1-generators/generateSequence-4.svg index 5df2437f1..e590c59a5 100644 --- a/1-js/12-generators-iterators/1-generators/generateSequence-4.svg +++ b/1-js/12-generators-iterators/1-generators/generateSequence-4.svg @@ -1,34 +1 @@ -<<<<<<< HEAD - - - - generateSequence-4.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - {value: 3, done: true} - - - - -======= -{value: 3, done: true} ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +{value: 3, done: true} \ No newline at end of file diff --git a/1-js/13-modules/01-modules-intro/article.md b/1-js/13-modules/01-modules-intro/article.md index b07ceffb8..072e33c22 100644 --- a/1-js/13-modules/01-modules-intro/article.md +++ b/1-js/13-modules/01-modules-intro/article.md @@ -1,12 +1,7 @@ # Modules, introduction -<<<<<<< HEAD -As our application grows bigger, we want to split it into multiple files, so called 'modules'. -A module usually contains a class or a library of useful functions. -======= As our application grows bigger, we want to split it into multiple files, so called "modules". A module may contain a class or a library of functions for a specific purpose. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For a long time, JavaScript existed without a language-level module syntax. That wasn't a problem, because initially scripts were small and simple. So there was no need. @@ -18,13 +13,6 @@ To name some (for historical reasons): - [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) -- the module system created for Node.js server. - [UMD](https://github.com/umdjs/umd) -- one more module system, suggested as a universal one, compatible with AMD and CommonJS. -<<<<<<< HEAD -Now all these slowly become a part of history, but we still can find them in old scripts. The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js. - -## What is a module? - -A module is just a file, a single script, as simple as that. -======= Now all these slowly become a part of history, but we still can find them in old scripts. The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js. So we'll study the modern JavaScript modules from now on. @@ -32,17 +20,11 @@ The language-level module system appeared in the standard in 2015, gradually evo ## What is a module? A module is just a file. One script is one module. As simple as that. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Directives `export` and `import` allow to interchange functionality between modules: -<<<<<<< HEAD -- `export` keyword labels variables and functions that should be accessible from outside the file. -- `import` allows to import functionality from other modules. -======= - `export` keyword labels variables and functions that should be accessible from outside the current module. - `import` allows the import of functionality from other modules. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For instance, if we have a file `sayHi.js` exporting a function: @@ -63,15 +45,11 @@ alert(sayHi); // function... sayHi('John'); // Hello, John! ``` -<<<<<<< HEAD -In this tutorial we concentrate on the language itself, but we use browser as the demo environment, so let's see how modules work in the browser. -======= The `import` directive loads the module by path `./sayHi.js` relative to the current file, and assigns exported function `sayHi` to the corresponding variable. Let's run the example in-browser. As modules support special keywords and features, we must tell the browser that a script should be treated as a module, by using the attribute ` ``` -<<<<<<< HEAD -Here's a brief list of methods to insert a node into a parent element (`parentElem` for short): - -`parentElem.appendChild(node)` -: Appends `node` as the last child of `parentElem`. - - The following example adds a new `
  • ` to the end of `
      `: - - ```html run height=100 -
        -
      1. 0
      2. -
      3. 1
      4. -
      5. 2
      6. -
      - - - ``` - -`parentElem.insertBefore(node, nextSibling)` -: Inserts `node` before `nextSibling` into `parentElem`. - - The following code inserts a new list item before the second `
    1. `: - - ```html run height=100 -
        -
      1. 0
      2. -
      3. 1
      4. -
      5. 2
      6. -
      - - ``` - To insert `newLi` as the first element, we can do it like this: - - ```js - list.insertBefore(newLi, list.firstChild); - ``` - -`parentElem.replaceChild(node, oldChild)` -: Replaces `oldChild` with `node` among children of `parentElem`. - -All these methods return the inserted node. In other words, `parentElem.appendChild(node)` returns `node`. But usually the returned value is not used, we just run the method. - -These methods are "old school": they exist from the ancient times and we can meet them in many old scripts. Unfortunately, there are some tasks that are hard to solve with them. - -For instance, how to insert *html* if we have it as a string? Or, given a node, how to insert another node *before* it? Of course, all that is doable, but not in an elegant way. - -So there exist two other sets of insertion methods to handle all cases easily. - -### prepend/append/before/after - -This set of methods provides more flexible insertions: -======= Here we called `append` on `document.body`, but we can call `append` method on any other element, to put another element into it. For instance, we can append something to `
      ` by calling `div.append(anotherElement)`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Here are more insertion methods, they specify different places where to insert: @@ -195,15 +110,11 @@ Here are more insertion methods, they specify different places where to insert: - `node.after(...nodes or strings)` –- insert nodes or strings *after* `node`, - `node.replaceWith(...nodes or strings)` –- replaces `node` with the given nodes or strings. -<<<<<<< HEAD -Here's an example of using these methods to add more items to a list and the text before/after it: -======= Arguments of these methods are an arbitrary list of DOM nodes to insert, or text strings (that become text nodes automatically). Let's see them in action. Here's an example of using these methods to add items to a list and the text before/after it: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```html autorun
        @@ -226,11 +137,7 @@ Here's an example of using these methods to add items to a list and the text bef ``` -<<<<<<< HEAD -Here's a small picture what methods do: -======= Here's a visual picture of what the methods do: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ![](before-prepend-append-after.svg) @@ -308,11 +215,7 @@ For instance:

        Bye

        ``` -<<<<<<< HEAD -That's how we can append an arbitrary HTML to our page. -======= That's how we can append arbitrary HTML to the page. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Here's the picture of insertion variants: @@ -585,15 +488,6 @@ Insertion and removal of nodes: Text strings are inserted "as text". -<<<<<<< HEAD -- Given a piece of HTML: `elem.insertAdjacentHTML(where, html)`, inserts depending on where: - - `"beforebegin"` -- insert `html` right before `elem`, - - `"afterbegin"` -- insert `html` into `elem`, at the beginning, - - `"beforeend"` -- insert `html` into `elem`, at the end, - - `"afterend"` -- insert `html` right after `elem`. - - Also there are similar methods `elem.insertAdjacentText` and `elem.insertAdjacentElement`, they insert text strings and elements, but they are rarely used. -======= - Given some HTML in `html`, `elem.insertAdjacentHTML(where, html)` inserts it depending on the value of `where`: - `"beforebegin"` -- insert `html` right before `elem`, - `"afterbegin"` -- insert `html` into `elem`, at the beginning, @@ -601,7 +495,6 @@ Insertion and removal of nodes: - `"afterend"` -- insert `html` right after `elem`. Also there are similar methods, `elem.insertAdjacentText` and `elem.insertAdjacentElement`, that insert text strings and elements, but they are rarely used. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 - To append HTML to the page before it has finished loading: - `document.write(html)` diff --git a/2-ui/1-document/07-modifying-document/before-prepend-append-after.svg b/2-ui/1-document/07-modifying-document/before-prepend-append-after.svg index 25b958412..6e1fb4874 100644 --- a/2-ui/1-document/07-modifying-document/before-prepend-append-after.svg +++ b/2-ui/1-document/07-modifying-document/before-prepend-append-after.svg @@ -1,74 +1 @@ -<<<<<<< HEAD - - - - before-prepend-append-after.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ol.after - - - ol.append - - - ol.prepend - - - - - - ol.before - - - ol.*(…nodes or strings) - - - - -======= -ol.afterol.appendol.prependol.before(…nodes or strings) ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +ol.afterol.appendol.prependol.before(…nodes or strings) \ No newline at end of file diff --git a/2-ui/1-document/07-modifying-document/insert-adjacent.svg b/2-ui/1-document/07-modifying-document/insert-adjacent.svg index 7fe480726..64beee037 100644 --- a/2-ui/1-document/07-modifying-document/insert-adjacent.svg +++ b/2-ui/1-document/07-modifying-document/insert-adjacent.svg @@ -1,74 +1 @@ -<<<<<<< HEAD - - - - insert-adjacent.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ol.insertAdjacentHTML(*, html) - - - - - - - - - - - - - - - - - - - - afterend - - - beforeend - - - afterbegin - - - - - - beforebegin - - - - -======= -ol.insertAdjacentHTML(*, html)afterendbeforeendafterbeginbeforebegin ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +ol.insertAdjacentHTML(*, html)afterendbeforeendafterbeginbeforebegin \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/1-get-scroll-height-bottom/task.md b/2-ui/1-document/09-size-and-scroll/1-get-scroll-height-bottom/task.md index 2a6830b76..796039c2a 100644 --- a/2-ui/1-document/09-size-and-scroll/1-get-scroll-height-bottom/task.md +++ b/2-ui/1-document/09-size-and-scroll/1-get-scroll-height-bottom/task.md @@ -4,11 +4,7 @@ importance: 5 # What's the scroll from the bottom? -<<<<<<< HEAD -The `elem.scrollTop` property is the size of the scrolled out part from the top. How to get "`scrollBottom`" -- the size from the bottom? -======= The `elem.scrollTop` property is the size of the scrolled out part from the top. How to get the size of the bottom scroll (let's call it `scrollBottom`)? ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Write the code that works for an arbitrary `elem`. diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg index 302008f91..ca8bbc3bd 100644 --- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg +++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg @@ -1,24 +1 @@ -<<<<<<< HEAD - - - - field.svg - Created with sketchtool. - - - - - (0,0) - - - - clientWidth - - - - - - -======= -(0,0)clientWidth ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +(0,0)clientWidth \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md index 3383d6c33..afa1d8f50 100644 --- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md +++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md @@ -37,15 +37,9 @@ The code won't work reliably while `` has no width/height: When the browser does not know the width/height of an image (from tag attributes or CSS), then it assumes them to equal `0` until the image finishes loading. -<<<<<<< HEAD -In real life after the first load browser usually caches the image, and on next loads it will have the size immediately. - -But on the first load the value of `ball.offsetWidth` is `0`. That leads to wrong coordinates. -======= So the value of `ball.offsetWidth` will be `0` until the image loads. That leads to wrong coordinates in the code above. After the first load, the browser usually caches the image, and on reloads it will have the size immediately. But on the first load the value of `ball.offsetWidth` is `0`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 We should fix that by adding `width/height` to ``: diff --git a/2-ui/1-document/09-size-and-scroll/article.md b/2-ui/1-document/09-size-and-scroll/article.md index 3461260e8..5a4c8ba52 100644 --- a/2-ui/1-document/09-size-and-scroll/article.md +++ b/2-ui/1-document/09-size-and-scroll/article.md @@ -58,13 +58,9 @@ Let's start exploring them from the outside of the element. These properties are rarely needed, but still they are the "most outer" geometry properties, so we'll start with them. -<<<<<<< HEAD -The `offsetParent` is the nearest ancestor that is: -======= The `offsetParent` is the nearest ancestor that the browser uses for calculating coordinates during rendering. That's the nearest ancestor that is one of the following: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 1. CSS-positioned (`position` is `absolute`, `relative`, `fixed` or `sticky`), or 2. ``, ``, or ``, or @@ -112,11 +108,7 @@ For our sample element: ````smart header="Geometry properties for not shown elements are zero/null" Geometry properties are calculated only for shown elements. -<<<<<<< HEAD -If an element (or any of its ancestors) has `display:none` or is not in the document, then all geometry properties are zero or `null` depending on what it is. -======= If an element (or any of its ancestors) has `display:none` or is not in the document, then all geometry properties are zero (or `null` for `offsetParent`). ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 For example, `offsetParent` is `null`, and `offsetWidth`, `offsetHeight` are `0`. @@ -277,11 +269,7 @@ Elements have the following geometry properties: - `offsetParent` -- is the nearest positioned ancestor or `td`, `th`, `table`, `body`. - `offsetLeft/offsetTop` -- coordinates relative to the upper-left edge of `offsetParent`. - `offsetWidth/offsetHeight` -- "outer" width/height of an element including borders. -<<<<<<< HEAD -- `clientLeft/clientTop` -- the distance from the upper-left outer corner to its upper-left inner corner. For left-to-right OS they are always the widths of left/top borders. For right-to-left OS the vertical scrollbar is on the left so `clientLeft` includes its width too. -======= - `clientLeft/clientTop` -- the distances from the upper-left outer corner to the upper-left inner (content + padding) corner. For left-to-right OS they are always the widths of left/top borders. For right-to-left OS the vertical scrollbar is on the left so `clientLeft` includes its width too. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 - `clientWidth/clientHeight` -- the width/height of the content including paddings, but without the scrollbar. - `scrollWidth/scrollHeight` -- the width/height of the content including the scrolled out parts. Also includes paddings, but not the scrollbar. - `scrollLeft/scrollTop` -- width/height of the scrolled out part of the element, starting from its upper-left corner. diff --git a/2-ui/1-document/09-size-and-scroll/metric-all.svg b/2-ui/1-document/09-size-and-scroll/metric-all.svg index 69bc9ae09..3c77f09ac 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-all.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-all.svg @@ -1,140 +1 @@ -<<<<<<< HEAD - - - - metric-all.svg - Created with sketchtool. - - - - - - - - - - - - - - Introduction - - This Ecma Standard is based on several - originating technologies, the most well - known being JavaScript (Netscape) and - JScript (Microsoft). The language was - invented by Brendan Eich at Netscape and - first appeared in that company’s Navigator - 2.0 browser. It has appeared in all - subsequent browsers from Netscape and - in all browsers from Microsoft starting with - Internet Explorer 3.0. - The development of this Standard started - in November 1996. The first edition of this - Ecma Standard was adopted by the Ecma - General Assembly of June 1997. - That Ecma Standard was submitted to ISO/ - IEC JTC 1 for adoption under the fast-track - procedure, and approved as international - standard ISO/IEC 16262, in April 1998. The - Ecma General Assembly of June 1998 - approved the second edition of ECMA-262 - to keep it fully aligned with ISO/IEC 16262. - Changes between the first and the second - edition are editorial in nature. - - - - - scrollHeight - - - offsetHeight - - - scrollTop - - - - - - - - - - - clientHeight - - - - offsetTop - - - clientLeft - - - - - - - - - - clientWidth - - - - clientTop - - - offsetLeft - - - - - - offsetWidth - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -======= -Introduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997. That Ecma Standard was submitted to ISO/ IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262, in April 1998. The Ecma General Assembly of June 1998 approved the second edition of ECMA-262 to keep it fully aligned with ISO/IEC 16262. Changes between the first and the second edition are editorial in nature.scrollHeightoffsetHeightscrollTopclientHeightoffsetTopclientLeftclientWidthclientTopoffsetLeftoffsetWidth ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +Introduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997. That Ecma Standard was submitted to ISO/ IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262, in April 1998. The Ecma General Assembly of June 1998 approved the second edition of ECMA-262 to keep it fully aligned with ISO/IEC 16262. Changes between the first and the second edition are editorial in nature.scrollHeightoffsetHeightscrollTopclientHeightoffsetTopclientLeftclientWidthclientTopoffsetLeftoffsetWidth \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg b/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg index f6329c3fd..12bc456a6 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg @@ -1,74 +1 @@ -<<<<<<< HEAD - - - - metric-client-left-top-rtl.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - clientTop: - 25px - = border - - - clientLeft: - 41px - - - - - - - - -======= -clientTop: 25px = borderclientLeft: 41px ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +clientTop: 25px = borderclientLeft: 41px \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg b/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg index e9926bccf..5708047d4 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg @@ -1,63 +1 @@ -<<<<<<< HEAD - - - - metric-client-left-top.svg - Created with sketchtool. - - - - - - - - - - - - - Introduction - - This Ecma Standard is based on - several originating technologies, - the most well known being - JavaScript (Netscape) and JScript - (Microsoft). The language was - invented by Brendan Eich at - Netscape and first appeared in - that company’s Navigator 2.0 - browser. It has appeared in all - subsequent browsers from - Netscape and in all browsers - from Microsoft starting with - Internet Explorer 3.0. - The development of this - Standard started in November - 1996. The first edition of this - Ecma Standard was adopted by - the Ecma General Assembly of - June 1997. - - - - - - - clientTop: - 25px - = border - - - clientLeft: - 25px - - - - - - - - -======= -Introduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997.clientTop: 25px = borderclientLeft: 25px ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +Introduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997.clientTop: 25px = borderclientLeft: 25px \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg b/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg index 0753509da..fe4b3c69d 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg @@ -1,116 +1 @@ -<<<<<<< HEAD - - - - metric-client-width-height.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - border - 25px - - - padding - 20px - - - content width: - 284px - - - - - - border - 25px - - - padding - 20px - - - scrollbar - 16px - - - - - - - - clientWidth = - 20+284+20 - = - 324px - - - - - - clientHeight: - 240px - - - - - - height: - 200px - - - - - - Introduction - - This Ecma Standard is based on several - originating technologies, the most well - known being JavaScript (Netscape) and - JScript (Microsoft). The language was - invented by Brendan Eich at Netscape and - first appeared in that company’s Navigator - 2.0 browser. It has appeared in all - subsequent browsers from Netscape and - in all browsers from Microsoft starting with - - - - -======= -border 25pxpadding 20pxcontent width: 284pxborder 25pxpadding 20pxscrollbar 16pxclientWidth = 20+284+20 = 324pxclientHeight: 240pxheight: 200pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +border 25pxpadding 20pxcontent width: 284pxborder 25pxpadding 20pxscrollbar 16pxclientWidth = 20+284+20 = 324pxclientHeight: 240pxheight: 200pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-width-nopadding.svg b/2-ui/1-document/09-size-and-scroll/metric-client-width-nopadding.svg index 659317615..62de5f572 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-width-nopadding.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-width-nopadding.svg @@ -1,81 +1 @@ -<<<<<<< HEAD - - - - metric-client-width-nopadding.svg - Created with sketchtool. - - - - - - - - - - - - - - - - clientWidth: - 284px - = content width - - - - CSS width: - 300px - - - - Introduction - - This Ecma Standard is based on several - originating technologies, the most well - known being JavaScript (Netscape) and - JScript (Microsoft). The language was - invented by Brendan Eich at Netscape and - first appeared in that company’s Navigator - 2.0 browser. It has appeared in all - subsequent browsers from Netscape and - in all browsers from Microsoft starting with - - - - - padding: 0; - width: 300px; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -======= -clientWidth: 284px = content widthCSS width: 300pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with padding: 0; width: 300px; ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +clientWidth: 284px = content widthCSS width: 300pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with padding: 0; width: 300px; \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-css.svg b/2-ui/1-document/09-size-and-scroll/metric-css.svg index 7e19e3e92..e910a9c87 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-css.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-css.svg @@ -1,113 +1 @@ -<<<<<<< HEAD - - - - metric-css.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - padding: - 20px - - - height: - 200px - - - - - - - - padding: - 20px - - - - - border - 25px - - - padding - 20px - - - content width: - 284px - - - - - - border - 25px - - - padding - 20px - - - scrollbar - 16px - - - Introduction - - This Ecma Standard is based on several - originating technologies, the most well - known being JavaScript (Netscape) and - JScript (Microsoft). The language was - invented by Brendan Eich at Netscape and - first appeared in that company’s Navigator - 2.0 browser. It has appeared in all - subsequent browsers from Netscape and in - all browsers from Microsoft starting with - - - - - - - - - - -======= -padding: 20pxheight: 200pxpadding: 20pxborder 25pxpadding 20pxcontent width: 284pxborder 25pxpadding 20pxscrollbar 16pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +padding: 20pxheight: 200pxpadding: 20pxborder 25pxpadding 20pxcontent width: 284pxborder 25pxpadding 20pxscrollbar 16pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg b/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg index f5419e56c..d72a20138 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg @@ -1,92 +1 @@ -<<<<<<< HEAD - - - - metric-offset-parent.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - offsetTop: - 180px - - - offsetLeft: - 180px - - - Introduction - - This Ecma Standard is based on several - originating technologies, the most well - known being JavaScript (Netscape) and - JScript (Microsoft). The language was - invented by Brendan Eich at Netscape - and first appeared in that company’s - Navigator 2.0 browser. It has appeared - in all subsequent browsers from - Netscape and in all browsers from - Microsoft - - - - - - - - - position: absolute; - left: 180px; - top: 180px; - - - offsetParent <MAIN> - - - <DIV> - - - - - - - - - - - - - - - - - - - - - - - - - - -======= -offsetTop: 180pxoffsetLeft: 180pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoftposition: absolute; left: 180px; top: 180px;offsetParent <MAIN> <DIV> ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +offsetTop: 180pxoffsetLeft: 180pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoftposition: absolute; left: 180px; top: 180px;offsetParent <MAIN> <DIV> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg b/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg index 24494cea0..76e20b1bc 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg @@ -1,116 +1 @@ -<<<<<<< HEAD - - - - metric-offset-width-height.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - border - 25px - - - padding - 20px - - - content width: - 284px - - - height: - 200px - - - - - - - - - border - 25px - - - padding - 20px - - - scrollbar - 16px - - - - - - - - offsetWidth = - 25+20+284+20+16+25 - = - 390px - - - - - - offsetHeight: - 290px - - - - - - Introduction - - This Ecma Standard is based on several - originating technologies, the most well - known being JavaScript (Netscape) and - JScript (Microsoft). The language was - invented by Brendan Eich at Netscape and - first appeared in that company’s Navigator - 2.0 browser. It has appeared in all - subsequent browsers from Netscape and - in all browsers from Microsoft starting with - - - - -======= -border 25pxpadding 20pxcontent width: 284pxheight: 200pxborder 25pxpadding 20pxscrollbar 16pxoffsetWidth = 25+20+284+20+16+25 = 390pxoffsetHeight: 290pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +border 25pxpadding 20pxcontent width: 284pxheight: 200pxborder 25pxpadding 20pxscrollbar 16pxoffsetWidth = 25+20+284+20+16+25 = 390pxoffsetHeight: 290pxIntroduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg b/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg index fec6eb1db..3c00bed00 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg @@ -1,91 +1 @@ -<<<<<<< HEAD - - - - metric-scroll-top.svg - Created with sketchtool. - - - - - - - - - - - - - - - Introduction - - This Ecma Standard is based on several - originating technologies, the most well - known being JavaScript (Netscape) and - JScript (Microsoft). The language was - invented by Brendan Eich at Netscape and - first appeared in that company’s Navigator - 2.0 browser. It has appeared in all - subsequent browsers from Netscape and - in all browsers from Microsoft starting with - Internet Explorer 3.0. - The development of this Standard started - in November 1996. The first edition of this - Ecma Standard was adopted by the Ecma - General Assembly of June 1997. - That Ecma Standard was submitted to ISO/ - IEC JTC 1 for adoption under the fast-track - procedure, and approved as international - standard ISO/IEC 16262, in April 1998. The - Ecma General Assembly of June 1998 - approved the second edition of ECMA-262 - to keep it fully aligned with ISO/IEC 16262. - Changes between the first and the second - edition are editorial in nature. - - - - - scrollTop - - - - - - - - scrollHeight: - 723px - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -======= -Introduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997. That Ecma Standard was submitted to ISO/ IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262, in April 1998. The Ecma General Assembly of June 1998 approved the second edition of ECMA-262 to keep it fully aligned with ISO/IEC 16262. Changes between the first and the second edition are editorial in nature.scrollTopscrollHeight: 723px ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +Introduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997. That Ecma Standard was submitted to ISO/ IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262, in April 1998. The Ecma General Assembly of June 1998 approved the second edition of ECMA-262 to keep it fully aligned with ISO/IEC 16262. Changes between the first and the second edition are editorial in nature.scrollTopscrollHeight: 723px \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg b/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg index cdd15fe7c..29e25eb6f 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg @@ -1,95 +1 @@ -<<<<<<< HEAD - - - - metric-scroll-width-height.svg - Created with sketchtool. - - - - - - - - - - - - - - - Introduction - - This Ecma Standard is based on several - originating technologies, the most well - known being JavaScript (Netscape) and - JScript (Microsoft). The language was - invented by Brendan Eich at Netscape - and first appeared in that company’s - Navigator 2.0 browser. It has appeared - in all subsequent browsers from - Netscape and in all browsers from - Microsoft starting with Internet Explorer - 3.0. - The development of this Standard - started in November 1996. The first - edition of this Ecma Standard was - adopted by the Ecma General Assembly - of June 1997. - That Ecma Standard was submitted to - ISO/IEC JTC 1 for adoption under the - fast-track procedure, and approved as - international standard ISO/IEC 16262, in - April 1998. The Ecma General Assembly - of June 1998 approved the second - edition of ECMA-262 to keep it fully - aligned with ISO/IEC 16262. Changes - between the first and the second - edition are editorial in nature. - - - - - - - scrollHeight: - 723px - - - - - - - - - scrollWidth = - 324px - - - - - - - - - - - - - - - - - - - - - - - - - - -======= -Introduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997. That Ecma Standard was submitted to ISO/IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262, in April 1998. The Ecma General Assembly of June 1998 approved the second edition of ECMA-262 to keep it fully aligned with ISO/IEC 16262. Changes between the first and the second edition are editorial in nature.scrollHeight: 723pxscrollWidth = 324px ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +Introduction This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997. That Ecma Standard was submitted to ISO/IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262, in April 1998. The Ecma General Assembly of June 1998 approved the second edition of ECMA-262 to keep it fully aligned with ISO/IEC 16262. Changes between the first and the second edition are editorial in nature.scrollHeight: 723pxscrollWidth = 324px \ No newline at end of file diff --git a/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg b/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg index a57cd6a7b..b0dff4d4e 100644 --- a/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg +++ b/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg @@ -1,32 +1 @@ -<<<<<<< HEAD - - - - document-client-width-height.svg - Created with sketchtool. - - - - - - - - - - - - - - documentElement.clientHeight - - - documentElement.clientWidth - - - - - - -======= -documentElement.clientHeightdocumentElement.clientWidth ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +documentElement.clientHeightdocumentElement.clientWidth \ No newline at end of file diff --git a/2-ui/1-document/11-coordinates/article.md b/2-ui/1-document/11-coordinates/article.md index 9f189b13d..b45a152a1 100644 --- a/2-ui/1-document/11-coordinates/article.md +++ b/2-ui/1-document/11-coordinates/article.md @@ -55,9 +55,6 @@ If we compare window coordinates versus CSS positioning, then there are obvious But in CSS, the `right` property means the distance from the right edge, and the `bottom` property means the distance from the bottom edge. -<<<<<<< HEAD -If we just look at the picture above, we can see that in JavaScript it is not so. All window coordinates are counted from the upper-left corner, including these ones. -======= Please note: - Coordinates may be decimal fractions, such as `10.5`. That's normal, internally browser uses fractions in calculations. We don't have to round them when setting to `style.left/top`. @@ -91,7 +88,6 @@ There are obvious similarities between window-relative coordinates and CSS `posi But in CSS positioning, `right` property means the distance from the right edge, and `bottom` property means the distance from the bottom edge. If we just look at the picture above, we can see that in JavaScript it is not so. All window coordinates are counted from the top-left corner, including these ones. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ``` ## elementFromPoint(x, y) [#elementFromPoint] diff --git a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/move-ball-coords.svg b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/move-ball-coords.svg index 2f62e77aa..73dcee5f2 100644 --- a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/move-ball-coords.svg +++ b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/move-ball-coords.svg @@ -1,55 +1 @@ -<<<<<<< HEAD - - - - move-ball-coords.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - ball.style.position.left - - - ? - - - fieldCoords.left - - - event.clientX - - - - - - - - - - - - - - - -======= -ball.style.left?fieldCoords.leftevent.clientX ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +ball.style.left?fieldCoords.leftevent.clientX \ No newline at end of file diff --git a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/solution.md b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/solution.md index b38cf60aa..b04cb8231 100644 --- a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/solution.md +++ b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/solution.md @@ -36,11 +36,7 @@ To get field-relative `left` coordinate of the click, we can substract the field let left = event.clientX - fieldCoords.left - field.clientLeft; ``` -<<<<<<< HEAD -Normally, `ball.style.position.left` means the "left edge of the element" (the ball). So if we assign that `left`, then the ball edge would be under the mouse cursor. -======= Normally, `ball.style.left` means the "left edge of the element" (the ball). So if we assign that `left`, then the ball edge, not center, would be under the mouse cursor. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 We need to move the ball half-width left and half-height up to make it center. diff --git a/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel1.svg b/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel1.svg index c926cf1fa..2c92df87d 100644 --- a/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel1.svg +++ b/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel1.svg @@ -1,35 +1 @@ -<<<<<<< HEAD - - - - carousel1.svg - Created with sketchtool. - - - - - - - - - - - - - - - div (container) - - - 130x130 - - - ul (width: 9999px) - - - - - -======= -div (container)130x130ul (width: 9999px) ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +div (container)130x130ul (width: 9999px) \ No newline at end of file diff --git a/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel2.svg b/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel2.svg index bcf73a09c..3f53a7691 100644 --- a/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel2.svg +++ b/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel2.svg @@ -1,37 +1 @@ -<<<<<<< HEAD - - - - carousel2.svg - Created with sketchtool. - - - - - - - - - - - - - - - - - div (container) - - - 130x130 - - - ul (margin-left: -350px) - - - - - -======= -div (container)130x130ul (margin-left: -350px) ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +div (container)130x130ul (margin-left: -350px) \ No newline at end of file diff --git a/2-ui/2-events/01-introduction-browser-events/article.md b/2-ui/2-events/01-introduction-browser-events/article.md index 17131c6f0..70c6edb54 100644 --- a/2-ui/2-events/01-introduction-browser-events/article.md +++ b/2-ui/2-events/01-introduction-browser-events/article.md @@ -160,11 +160,7 @@ button.onclick = sayThanks; button.onclick = sayThanks(); ``` -<<<<<<< HEAD -If we add brackets, then `sayThanks()` -- will be the *result* of the function execution, so `onclick` in the last code becomes `undefined` (the function returns nothing). That won't work. -======= If we add parentheses, then `sayThanks()` becomes is a function call. So the last line actually takes the *result* of the function execution, that is `undefined` (as the function returns nothing), and assigns it to `onclick`. That doesn't work. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ...But in the markup we do need the brackets: @@ -172,11 +168,7 @@ If we add parentheses, then `sayThanks()` becomes is a function call. So the las ``` -<<<<<<< HEAD -The difference is easy to explain. When the browser reads the attribute, it creates a handler function with the body from its content. -======= The difference is easy to explain. When the browser reads the attribute, it creates a handler function with body from the attribute content. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 So the last example is the same as: ```js @@ -232,14 +224,8 @@ element.addEventListener(event, handler, [options]); `options` : An additional optional object with properties: - `once`: if `true`, then the listener is automatically removed after it triggers. -<<<<<<< HEAD - - `capture`: the phrase where to handle the event, to be covered later in the chapter . For historical reasons, `options` can also be `false/true`, that's the same as `{capture: false/true}`. - - `passive`: if `true`, then the handler will not `preventDefault()`, we'll cover that later in . - -======= - `capture`: the phase where to handle the event, to be covered later in the chapter . For historical reasons, `options` can also be `false/true`, that's the same as `{capture: false/true}`. - `passive`: if `true`, then the handler will not call `preventDefault()`, we'll explain that later in . ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 To remove the handler, use `removeEventListener`: @@ -385,11 +371,7 @@ For instance: ``` -<<<<<<< HEAD -In other words, when `addEventListener` receives an object as the handler, it calls `object.handleEvent(event)` in case of an event. -======= As we can see, when `addEventListener` receives an object as the handler, it calls `obj.handleEvent(event)` in case of an event. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 We could also use a class for that: diff --git a/2-ui/2-events/02-bubbling-and-capturing/article.md b/2-ui/2-events/02-bubbling-and-capturing/article.md index 801a9615b..a0de1efb7 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/article.md +++ b/2-ui/2-events/02-bubbling-and-capturing/article.md @@ -68,13 +68,8 @@ For instance, if we have a single handler `form.onclick`, then it can "catch" al In `form.onclick` handler: -<<<<<<< HEAD -- `this` (`=event.currentTarget`) is the `
        ` element, because the handler runs on it. -- `event.target` is the concrete element inside the form that actually was clicked. -======= - `this` (=`event.currentTarget`) is the `` element, because the handler runs on it. - `event.target` is the actual element inside the form that was clicked. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Check it out: @@ -186,16 +181,9 @@ The code sets click handlers on *every* element in the document to see which one If you click on `

        `, then the sequence is: -<<<<<<< HEAD -1. `HTML` -> `BODY` -> `FORM` -> `DIV` -> `P` (capturing phase, the first listener), and then: -2. `P` -> `DIV` -> `FORM` -> `BODY` -> `HTML` (bubbling phase, the second listener). - -Please note that `P` shows up two times: at the end of capturing and at the start of bubbling. -======= 1. `HTML` -> `BODY` -> `FORM` -> `DIV` (capturing phase, the first listener): 2. `P` (target phase, triggers two times, as we've set two listeners: capturing and bubbling) 3. `DIV` -> `FORM` -> `BODY` -> `HTML` (bubbling phase, the second listener). ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 There's a property `event.eventPhase` that tells us the number of the phase on which the event was caught. But it's rarely used, because we usually know it in the handler. @@ -207,15 +195,9 @@ If we `addEventListener(..., true)`, then we should mention the same phase in `r The event handling process: -<<<<<<< HEAD -- When an event happens -- the most nested element where it happens gets labeled as the "target element" (`event.target`). -- Then the event first moves from the document root down to the `event.target`, calling handlers assigned with `addEventListener(...., true)` on the way (`true` is a shorthand for `{capture: true}`). -- Then the event moves from `event.target` up to the root, calling handlers assigned using `on` and `addEventListener` without the 3rd argument or with the 3rd argument `false`. -======= - Then the event moves down from the document root to `event.target`, calling handlers assigned with `addEventListener(..., true)` on the way (`true` is a shorthand for `{capture: true}`). - Then handlers are called on the target element itself. - Then the event bubbles up from `event.target` to the root, calling handlers assigned using `on` and `addEventListener` without the 3rd argument or with the 3rd argument `false/{capture:false}`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 Each handler can access `event` object properties: diff --git a/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg b/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg index 55e5084ec..e3d749898 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg +++ b/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg @@ -1,32 +1 @@ -<<<<<<< HEAD - - - - event-order-bubbling.svg - Created with sketchtool. - - - - - - - - 1 - - - 2 - - - 3 - - - Most deeply - nested element - - - - - -======= -123Most deeply nested element ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +123Most deeply nested element \ No newline at end of file diff --git a/2-ui/2-events/03-event-delegation/bagua-bubble.svg b/2-ui/2-events/03-event-delegation/bagua-bubble.svg index 6f8f20995..bb9989b45 100644 --- a/2-ui/2-events/03-event-delegation/bagua-bubble.svg +++ b/2-ui/2-events/03-event-delegation/bagua-bubble.svg @@ -1,31 +1 @@ -<<<<<<< HEAD - - - - bagua-bubble.svg - Created with sketchtool. - - - - - - - - <table> - - - <td> - - - <strong> - - - event.target - - - - - -======= -<table><td><strong>event.target ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +<table><td><strong>event.target \ No newline at end of file diff --git a/2-ui/2-events/04-default-browser-action/article.md b/2-ui/2-events/04-default-browser-action/article.md index 8f8f5e05c..9cfd46534 100644 --- a/2-ui/2-events/04-default-browser-action/article.md +++ b/2-ui/2-events/04-default-browser-action/article.md @@ -15,11 +15,7 @@ If we handle an event in JavaScript, we may not want the corresponding browser a There are two ways to tell the browser we don't want it to act: - The main way is to use the `event` object. There's a method `event.preventDefault()`. -<<<<<<< HEAD -- If the handler is assigned using `on` (not by `addEventListener`), then we can just return `false` from it. -======= - If the handler is assigned using `on` (not by `addEventListener`), then returning `false` also works the same. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 In this HTML a click on a link doesn't lead to navigation, browser doesn't do anything: @@ -36,11 +32,7 @@ The value returned by an event handler is usually ignored. The only exception is `return false` from a handler assigned using `on`. -<<<<<<< HEAD -In all other cases, the return is not needed and it's not processed anyhow. -======= In all other cases, `return` value is ignored. In particular, there's no sense in returning `true`. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ``` ### Example: the menu @@ -216,11 +208,7 @@ As we can clearly see, `event.stopPropagation()` and `event.preventDefault()` (a ``` ```smart header="Nested context menus architecture" -<<<<<<< HEAD -There are also alternative ways to implement nested context menus. One of them is to have a special global object with a method that handles `document.oncontextmenu`, and also methods that allow to store various "lower-level" handlers in it. -======= There are also alternative ways to implement nested context menus. One of them is to have a single global object with a handler for `document.oncontextmenu`, and also methods that allow us to store other handlers in it. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 The object will catch any right-click, look through stored handlers and run the appropriate one. diff --git a/2-ui/2-events/05-dispatch-events/article.md b/2-ui/2-events/05-dispatch-events/article.md index b036892c9..fa6a0308b 100644 --- a/2-ui/2-events/05-dispatch-events/article.md +++ b/2-ui/2-events/05-dispatch-events/article.md @@ -8,17 +8,17 @@ We can generate not only completely new events, that we invent for our own purpo ## Event constructor -Events form a hierarchy, just like DOM element classes. The root is the built-in [Event](http://www.w3.org/TR/dom/#event) class. +Build-in event classes form a hierarchy, similar to DOM element classes. The root is the built-in [Event](http://www.w3.org/TR/dom/#event) class. We can create `Event` objects like this: ```js -let event = new Event(event type[, options]); +let event = new Event(type[, options]); ``` Arguments: -- *event type* -- may be any string, like `"click"` or our own like `"hey-ho!"`. +- *type* -- event type, a string like `"click"` or our own like `"my-event"`. - *options* -- the object with two optional properties: - `bubbles: true/false` -- if `true`, then the event bubbles. - `cancelable: true/false` -- if `true`, then the "default action" may be prevented. Later we'll see what it means for custom events. @@ -66,9 +66,13 @@ All we need is to set `bubbles` to `true`: // ...dispatch on elem! let event = new Event("hello", {bubbles: true}); // (2) elem.dispatchEvent(event); + + // the handler on document will activate and display the message. + ``` + Notes: 1. We should use `addEventListener` for our custom events, because `on` only exists for built-in events, `document.onhello` doesn't work. @@ -160,17 +164,9 @@ Besides, the event class describes "what kind of event" it is, and if the event Many browser events have a "default action", such as navigating to a link, starting a selection, and so on. -<<<<<<< HEAD -Of course, if the event has a non-standard name, then it's not known to the browser, and there's no "default browser action" for it. - -But the event-generating code may plan some actions after `dispatchEvent`. - -The call of `event.preventDefault()` is a way for the handler to send a signal that those actions shouldn't be performed. -======= For new, custom events, there are definitely no default browser actions, but a code that dispatches such event may have its own plans what to do after triggering the event. By calling `event.preventDefault()`, an event handler may send a signal that those actions should be canceled. ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 In that case the call to `elem.dispatchEvent(event)` returns `false`. And the code that dispatched it knows that it shouldn't continue. @@ -237,12 +233,8 @@ It's processed immediately, without waiting for `onclick` handler to end: alert(2); }; -<<<<<<< HEAD - document.addEventListener('menu-open', () => alert('nested')) -======= // triggers between 1 and 2 document.addEventListener('menu-open', () => alert('nested')); ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ``` @@ -252,50 +244,35 @@ Please note that the nested event `menu-open` is caught on the `document`. The p That's not only about `dispatchEvent`, there are other cases. If an event handler calls methods that trigger other events -- they are processed synchronously too, in a nested fashion. -<<<<<<< HEAD -<<<<<<< HEAD -If we don't like it, we can either put the `dispatchEvent` (or other event-triggering call) at the end of `onclick` or, if inconvenient, wrap it in `setTimeout(...,0)`: -======= -If we don't like it, we can either put the `dispatchEvent` (or other event-triggering call) at the end of `onclick` or, maybe better, wrap it in zero-delay `setTimeout`: ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 -======= Let's say we don't like it. We'd want `onclick` to be fully processed first, independently from `menu-open` or any other nested events. Then we can either put the `dispatchEvent` (or another event-triggering call) at the end of `onclick` or, maybe better, wrap it in the zero-delay `setTimeout`: ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 ```html run ``` -<<<<<<< HEAD -======= Now `dispatchEvent` runs asynchronously after the current code execution is finished, including `mouse.onclick`, so event handlers are totally separate. The output order becomes: 1 -> 2 -> nested. ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 ## Summary -To generate an event, we first need to create an event object. +To generate an event from code, we first need to create an event object. The generic `Event(name, options)` constructor accepts an arbitrary event name and the `options` object with two properties: - `bubbles: true` if the event should bubble. diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md index e0ac375fc..72e615bdd 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md @@ -14,11 +14,7 @@ Make a universal object `new HoverIntent(options)` for it. Its `options`: - `elem` -- element to track. -<<<<<<< HEAD -- `over` -- a function to call if the mouse is slowly moving the element. -======= - `over` -- a function to call if the mouse came to the element: that is, it moves slowly or stopped over it. ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 - `out` -- a function to call when the mouse leaves the element (if `over` was called). An example of using such object for the tooltip: diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md index 63cbfbab6..652ff3cbf 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md @@ -8,11 +8,7 @@ The `mouseover` event occurs when a mouse pointer comes over an element, and `mo ![](mouseover-mouseout.svg) -<<<<<<< HEAD -These events are special, because they have a `relatedTarget`. -======= These events are special, because they have property `relatedTarget`. This property complements `target`. When a mouse leaves one element for another, one of them becomes `target`, and the other one - `relatedTarget`. ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 For `mouseover`: @@ -21,13 +17,8 @@ For `mouseover`: For `mouseout` the reverse: -<<<<<<< HEAD -- `event.target` -- is the element that mouse left. -- `event.relatedTarget` -- is the new under-the-pointer element (that mouse left for). -======= - `event.target` -- is the element that the mouse left. - `event.relatedTarget` -- is the new under-the-pointer element, that mouse left for (`target` -> `relatedTarget`). ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 ```online In the example below each face and its features are separate elements. When you move the mouse, you can see mouse events in the text area. diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg index 74baa6787..b38d76fbe 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg @@ -1,33 +1 @@ -<<<<<<< HEAD -<<<<<<< HEAD - - - - mouseover-to-child.svg - Created with sketchtool. - - - - - #FROM - - - - #TO - - - - mouseover - - - mouseout - - - - -======= -mouseoutmouseover#parent#child ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 -======= -mouseoutmouseover#parent#child ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +mouseoutmouseover#parent#child \ No newline at end of file diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg index 302008f91..ca8bbc3bd 100644 --- a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg +++ b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg @@ -1,24 +1 @@ -<<<<<<< HEAD - - - - field.svg - Created with sketchtool. - - - - - (0,0) - - - - clientWidth - - - - - - -======= -(0,0)clientWidth ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 +(0,0)clientWidth \ No newline at end of file diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md index 268b4f9be..6cb1152c1 100644 --- a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md +++ b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md @@ -2,23 +2,11 @@ Drag'n'Drop is a great interface solution. Taking something and dragging and dropping it is a clear and simple way to do many things, from copying and moving documents (as in file managers) to ordering (dropping items into a cart). -<<<<<<< HEAD -In the modern HTML standard there's a [section about Drag Events](https://html.spec.whatwg.org/multipage/interaction.html#dnd). - -They are interesting, because they allow to solve simple tasks easily, and also allow to handle drag'n'drop of "external" files into the browser. So we can take a file in the OS file-manager and drop it into the browser window. Then JavaScript gains access to its contents. - -<<<<<<< HEAD -But native Drag Events also have limitations. For instance, we can limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. There are other drag'n'drop tasks that can't be implemented using that API. -======= -But native Drag Events also have limitations. For instance, we can't limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. There are other drag'n'drop tasks that can't be done using that API. ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 -======= In the modern HTML standard there's a [section about Drag and Drop](https://html.spec.whatwg.org/multipage/interaction.html#dnd) with special events such as `dragstart`, `dragend`, and so on. These events allow us to support special kinds of drag'n'drop, such as handling dragging a file from OS file-manager and dropping it into the browser window. Then JavaScript can access the contents of such files. But native Drag Events also have limitations. For instance, we can't prevent dragging from a certain area. Also we can't make the dragging "horizontal" or "vertical" only. And there are many other drag'n'drop tasks that can't be done using them. Also, mobile device support for such events is very weak. ->>>>>>> e074a5f825a3d10b0c1e5e82561162f75516d7e3 So here we'll see how to implement Drag'n'Drop using mouse events. @@ -105,18 +93,14 @@ So we should listen on `document` to catch it. ## Correct positioning -In the examples above the ball is always centered under the pointer: +In the examples above the ball is always moved so, that it's center is under the pointer: ```js ball.style.left = pageX - ball.offsetWidth / 2 + 'px'; ball.style.top = pageY - ball.offsetHeight / 2 + 'px'; ``` -<<<<<<< HEAD -Not bad, but there's a side-effect. To initiate the drag'n'drop can we `mousedown` anywhere on the ball. If do it at the edge, then the ball suddenly "jumps" to become centered. -======= Not bad, but there's a side-effect. To initiate the drag'n'drop, we can `mousedown` anywhere on the ball. But if "take" it from its edge, then the ball suddenly "jumps" to become centered under the mouse pointer. ->>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923 It would be better if we keep the initial shift of the element relative to the pointer. @@ -136,8 +120,6 @@ Let's update our algorithm: let shiftY = event.clientY - ball.getBoundingClientRect().top; ``` - Please note that there's no method to get document-relative coordinates in JavaScript, so we use window-relative coordinates here. - 2. Then while dragging we position the ball on the same shift relative to the pointer, like this: ```js @@ -163,7 +145,8 @@ ball.onmousedown = function(event) { moveAt(event.pageX, event.pageY); - // centers the ball at (pageX, pageY) coordinates + // moves the ball at (pageX, pageY) coordinates + // taking initial shifts into account function moveAt(pageX, pageY) { ball.style.left = pageX - *!*shiftX*/!* + 'px'; ball.style.top = pageY - *!*shiftY*/!* + 'px'; @@ -173,10 +156,10 @@ ball.onmousedown = function(event) { moveAt(event.pageX, event.pageY); } - // (3) move the ball on mousemove + // move the ball on mousemove document.addEventListener('mousemove', onMouseMove); - // (4) drop the ball, remove unneeded handlers + // drop the ball, remove unneeded handlers ball.onmouseup = function() { document.removeEventListener('mousemove', onMouseMove); ball.onmouseup = null; @@ -197,19 +180,10 @@ In action (inside `