Curso básico de Javascript – (parte 1)

Eu preparei este material de estudo com intuito de ensinar o básico do básico de javascript, pois é um artigo bem longo no qual eu dividi em três partes totalizando 70 questões com exemplos práticos sobre javascript que são de extrema importância para você se dar bem como Web developer, então preste muita atenção.

1. Qual é a diferença entre undefinede null?

  • Antes de entender as diferenças entre undefinede nulldevemos entender as semelhanças entre elas.

Eles pertencem aos 7 tipos primitivos do JavaScript.

let primitiveTypes = ['string','number','null','undefined','boolean','symbol', 'bigint'];

Eles são valores falsos . Valores avaliados como false ao convertê-lo em booleano usando Boolean(value)or !!value.

   console.log(!!null); //logs false
   console.log(!!undefined); //logs false

   console.log(Boolean(null)); //logs false
   console.log(Boolean(undefined)); //logs false

Ok, vamos falar sobre as diferenças.

  • undefined é o valor padrão de uma variável que não recebeu um valor específico. Ou uma função que não tem valor de retorno explícito ex. console.log. Ou uma propriedade que não existe em um objeto. O motor de JavaScript faz isso para nós a atribuição de undefinedvalor.
let _thisIsUndefined;
  const doNothing = () => {};
  const someObj = {
    a : "ay",
    b : "bee",
    c : "si"
  };

  console.log(_thisIsUndefined); //logs undefined
  console.log(doNothing()); //logs undefined
  console.log(someObj["d"]); //logs undefined
  • null é "um valor que não representa valor" . null é um valor que foi definido explicitamente para uma variável. Neste exemplo, obtemos um valor de null quando o fs.read Filemétodo não gera um erro.
fs.readFile('path/to/file', (e,data) => {
     console.log(e); //it logs null when no error occurred
     if(e){
       console.log(e);
     }
     console.log(data);
   });

Ao comparar null e undefined chegamos true usar == e false usar ===.

console.log(null == undefined); // logs true
console.log(null === undefined); // logs false

2. O que o operador && faz?

O operador && ou Logical AND encontra a primeira expressão falsa em seus operandos e a retorna e, se não encontrar nenhuma expressão falsa , retorna a última expressão. Emprega curto-circuito para evitar trabalho desnecessário. Eu usei isso no catch para fechar a conexão com o banco de dados em um dos meus projetos.

console.log(false && 1 && []); //logs false
 console.log(" " && true && 5); //logs 5

Usando instruções if .

const router: Router = Router();

  router.get('/endpoint', (req: Request, res: Response) => {
     let conMobile: PoolConnection;
     try {
        //do some db operations
     } catch (e) {
     if (conMobile) {
      conMobile.release();
     }
  }
});

Usando o operador && .

const router: Router = Router();

router.get('/endpoint', (req: Request, res: Response) => {
  let conMobile: PoolConnection;
  try {
     //do some db operations
  } catch (e) {
    conMobile && conMobile.release()
  }
});

3. O que o operador || faz?

O operador `||`ou Logical `OR` encontra a primeira expressão de verdade em seus operandos e a retorna. Isso também emprega curto-circuito para evitar trabalho desnecessário. Ele foi usado antes para inicializar os valores dos parâmetros padrão nas funções IN antes que o *ES6 (EcmaScript 6) fosse suportado.

console.log(null || 1 || undefined); //logs 1

function logName(name) {
  var n = name || "Mark";
  console.log(n);
}

logName(); //logs "Mark"

4. O uso do operador + ou unary plus é a maneira mais rápida de converter uma string em um número?

De acordo com a documentação da MDN, é a maneira mais rápida de converter uma string em um número porque ela não executa nenhuma operação no valor se já for um número.

5. O que é o DOM ?

DOM significa Document Object Model é uma interface ( API ) para documentos HTML e XML. Quando o navegador lê ( analisa ) nosso documento HTML pela primeira vez, ele cria um objeto grande, um objeto realmente grande com base no documento HTML que é o DOM . É uma estrutura de árvore que é modelada a partir do documento HTML. O DOM é usado para interagir e modificar a estrutura do DOM ou elementos ou nós específicos.

Imagine uma estrutura HTML como esta.

O equivalente DOM seria assim.

O `document` objeto em JavaScript representa o DOM . Ele nos fornece muitos métodos que podemos usar para selecionar elementos para atualizar o conteúdo dos elementos e muito mais.

6. O que é Propagação de Eventos ?

Quando um evento ocorre em um elemento DOM , esse evento não ocorre totalmente naquele apenas um elemento. Na fase borbulhante , o evento borbulha ou vai para o pai, para os avós, para o pai até que chegue até o `window` momento da fase de captura, o evento começa da parte windowinferior ao elemento que desencadeou o evento ou o `event.target`.

A Propagação de Eventos possui três fases.

  1. Fase de captura - o evento começa a partir de windowentão desce para todos os elementos até atingir o elemento de destino.
  2. Fase de destino - o evento atingiu o elemento de destino.
  3. Fase de Bubbling - o evento borbulha do elemento alvo e depois sobe todos os elementos até atingir o window.

7. O que é o evento Bubbling ?

Quando um evento ocorre em um elemento DOM, esse evento não ocorre totalmente naquele apenas um elemento.

E o nosso código js.

function addEvent(el, event, callback, isCapture = false) {
  if (!el || !event || !callback || typeof callback !== 'function') return;
  if (typeof el === 'string') {
    el = document.querySelector(el);
  };
  el.addEventListener(event, callback, isCapture);
}

addEvent(document, 'DOMContentLoaded', () => {
  const child = document.querySelector('.child');
  const parent = document.querySelector('.parent');
  const grandparent = document.querySelector('.grandparent');

  addEvent(child, 'click', function (e) {
    console.log('child');
  });

  addEvent(parent, 'click', function (e) {
    console.log('parent');
  });

  addEvent(grandparent, 'click', function (e) {
    console.log('grandparent');
  });

  addEvent(document, 'click', function (e) {
    console.log('document');
  });

  addEvent('html', 'click', function (e) {
    console.log('html');
  })

  addEvent(window, 'click', function (e) {
    console.log('window');
  })

});

O `addEventListener` método possui um terceiro parâmetro opcional use `Capture` com um valor padrão `false` evento que ocorrerá na fase Bubbling se `true` evento ocorrer na fase de captura. Se clicar sobre o `child` elemento ele registra `child`, `parent`, `grandparent`, html, documente window, respectivamente, na consola . Isso é evento borbulhante.

8. O que é captura de eventos ?

Quando um evento ocorre em um elemento DOM, esse evento não ocorre totalmente naquele apenas um elemento. Na Fase de Captura , o evento inicia de `window` todo o caminho até o elemento que acionou o evento.

Se tivermos um exemplo de marcação como esta.

Em nosso código js.

function addEvent(el, event, callback, isCapture = false) {
  if (!el || !event || !callback || typeof callback !== 'function') return;
  if (typeof el === 'string') {
    el = document.querySelector(el);
  };
  el.addEventListener(event, callback, isCapture);
}

addEvent(document, 'DOMContentLoaded', () => {
  const child = document.querySelector('.child');
  const parent = document.querySelector('.parent');
  const grandparent = document.querySelector('.grandparent');

  addEvent(child, 'click', function (e) {
    console.log('child');
  }, true);

  addEvent(parent, 'click', function (e) {
    console.log('parent');
  }, true);

  addEvent(grandparent, 'click', function (e) {
    console.log('grandparent');
  }, true);

  addEvent(document, 'click', function (e) {
    console.log('document');
  }, true);

  addEvent('html', 'click', function (e) {
    console.log('html');
  }, true)

  addEvent(window, 'click', function (e) {
    console.log('window');
  }, true)

});

O `addEventListener` método possui um terceiro parâmetro opcional use `Capture` com um valor padrão `false` evento que ocorrerá na fase Bubbling se `true` ocorrer na fase de captura. Se clicar sobre o `child` elemento ele registra `window`, `document, html, grandparente parente child,` respectivamente, no console. Isso é captura de eventos .

9. Qual é a diferença entre event.preventDefault()e event.stopPropagation()métodos?

O `event.preventDefault()` método evita o comportamento padrão de um elemento. Se usado em um `form`, ele impede o envio. Se usado em um `anchor` no qual impede a navegação. Se usado em um `contextmenu`, impede a exibição ou exibição. Enquanto o `event.stopPropagation()` interrompe a propagação de um evento ou impede a ocorrência do evento na fase de bolhas ou captura.

10. Como saber se o `event.preventDefault()` método foi usado em um elemento?

Podemos utilizar a `event.defaultPrevented` propriedade no objeto de evento. Para retorna `boolean` indicando se o `event.preventDefault()` foi chamado em um elemento específico.

11. Por que esse código `obj.someprop.x` gera um erro?

const obj = {};
console.log(obj.someprop.x);

Obviamente, isso gera um erro devido ao motivo pelo qual estamos tentando acessar um
`x` propriedade na `someprop` que possui um valor `undefined`. Lembre-se de propriedades em um objeto que não existe por si só e seu protótipo tem um valor padrão `undefined` e não possui propriedades `x`.

12. O que é `event.target` ?

Em termos mais simples, o `event.target` é o elemento no qual o evento ocorreu ou o elemento que acionou o proprio evento.

Exemplo de marcação HTML.

Exemplo de JavaScript.

function clickFunc(event) {
  console.log(event.target);
}

Se você clicar no botão, ele registrará a marcação do botão, mesmo que anexemos o evento na parte externa da `div` ele sempre registrará o botão para que possamos concluir que o `event.target` é o elemento que acionou o evento.

13. O que é `event.currentTarget` ?

O `event.currentTarget` é o elemento no qual anexamos explicitamente o manipulador de eventos.

Copiando a marcação na pergunta 12 .
Exemplo de marcação HTML.

Nosso JS ficaria assim.

function clickFunc(event) {
  console.log(event.currentTarget);
}

Se você clicar no botão, ele registrará a marcação `div` mais externa, apesar de clicarmos no botão. Neste exemplo, podemos concluir que o `event.currentTarget` é o elemento no qual anexamos o manipulador de eventos.

14. Qual a diferença entre `==` e `===` ?

A diferença entre `==` (igualdade abstrata) e `===` (igualdade estrita) é que ela `==` compara por valor após coerção e `===` por valor e tipo sem coerção.

Vamos nos aprofundar na `==`(igualdade abstrata). Então, primeiro vamos falar sobre coerção .

coerção é o processo de converter um valor para outro tipo. Como neste caso, o `==` faz coerção implícita . Ele `==` tem algumas condições para executar antes de comparar os dois valores.

Suponha que tenhamos que comparar `x` `==` `y` valores.

  1. Se x e y tiver o mesmo tipo. Em seguida, compare-os com o `===` operador.
  2. Se x é `null` e y é `undefined` então retorne `true`.
  3. Se x é undefined e y é, null então retorne true.
  4. Se x é do tipo `number` e y é do tipo string retorne x `==` `toNumber(y)`.
  5. Se x é do tipo string e y é do tipo, `number` retorne `toNumber(x)` `==` y.
  6. Se x for do tipo, `boolean` retorne `toNumber(x)` `==` y.
  7. Se y for do tipo, `boolean` retorne x `==``toNumber(y)`.
  8. Se x é um ou string, symbolou number e y é o tipo object Então retorne x `==` `toPrimitive(y)`.
  9. Se x for um objecte x for um string, symbol Então retorne `toPrimitive(x)` `==` y.
  10. Retorno `false`.

Nota: `toPrimitive` usa primeiro o método `valueOf` e depois o método `toString` nos objetos para obter o valor primitivo desse objeto.

Vamos dar exemplos.

x y x == y
5 5 true
1 '1' true
null undefined true
0 false true
'1,2' 1,2 true
'[object Obeject]' {} true

Todos esses exemplos retornam `true`.

  1. O primeiro exemplo vai para a condição um porque x e y tem o mesmo tipo e valor.

  2. O segundo exemplo vai para a condição quatro y é convertida em number antes de comparar.

  3. O terceiro exemplo vai para a condição dois .

  4. O quarto exemplo vai para a condição sete porque y é boolean.

  5. O quinto exemplo vai para a condição oito . A matriz é convertida em string usando o método `toString()` que retorna 1,2.

  6. O último exemplo vai para a condição dez. O objeto é convertido em uma string usando o método `toString()` que retorna `[object Object]`.

x y x === y
5 5 true
1 '1' false
null undefined false
0 false false
'1,2' [1,2] false
'[object, Object]' {} false

Se utilizar o operador `===`, todas as comparações, com exceção do primeiro exemplo, retornarão false porque não têm o mesmo tipo, enquanto o primeiro exemplo retornará `true` porque os dois têm o mesmo tipo e valor.

15. Por que ele retorna falso ao comparar dois objetos semelhantes em JavaScript?

De acordo com o exemplo abaixo.

let a = { a: 1 };
let b = { a: 1 };
let c = a;

console.log(a === b); // logs false even though they have the same property
console.log(a === c); // logs true hmm

O javaScript compara objetos e primitivos de maneira diferente. Nas primitivas, as compara por valor, enquanto nos objetos, por referência ou pelo endereço na memória em que a variável está armazenada . É por isso que o primeira instrução `console.log` retorna `false` e a segunda instrução `console.log` retorna `true`. `a` e `c` tem a mesma referência e `a` e `b` não.

16. O que faz o `!!` operador faz?

O operador NÃO `double` ou `!!` força o valor no lado direito em um booleano, basicamente é uma maneira elegante de converter um valor em um booleano.

console.log(!!null); //logs false
console.log(!!undefined); //logs false
console.log(!!''); //logs false
console.log(!!0); //logs false
console.log(!!NaN); //logs false
console.log(!!' '); //logs true
console.log(!!{}); //logs true
console.log(!![]); //logs true
console.log(!!1); //logs true
console.log(!![].length); //logs false

17. Como avaliar várias expressões em uma linha?

Podemos usar o operador `,` para avaliar várias expressões em uma linha. Ele avalia da esquerda para a direita e retorna o valor do último item à direita ou do último operando.

let x = 5;

x = (x++ , x = addFive(x), x *= 2, x -= 5, x += 10);

function addFive(num) {
  return num + 5;
}

Se você registrar o valor x seria 27. Primeiro, incrementar o valor de x seria 6, isso irá invocar a função `addFive(6)` que 6 passou como um parâmetro e atribuiu o resultado para x o novo valor x seria 11. Depois disso, irá multiplicar o valor atual do x que é 2 e atribuí-lo para o valor x atualizado x seria 22. Em seguida, subtraímos o valor atual de x5 e atribuímos o resultado ao valor x atualizado que seria 17. Por fim, incrementamos o valor de x10 e atribuímos o valor atualizado x agora ao valor x que seria 27.

18. O que é `Hoisting`?

Elevação é o termo usado para descrever a movimentação de variáveis e funções para o topo de seu escopo (global ou função), onde definimos essa variável ou função.

Ok para entender `Hoisting` , eu tenho que explicar o contexto de execução .
O contexto de execução é o "ambiente de código" atualmente em execução. O contexto de execução possui duas fases de compilação e execução .

Compilação - nesta fase torna-se todas as declarações de função que vai até o topo do seu alcance, para que possamos referenciá-los mais tarde recebe toda variáveis de declaração (declarar com a palavra chave var).

Execução - nesta fase, atribui valores às variáveis içadas anteriormente e executa ou invoca funções (métodos em objetos) .

Nota: apenas declarações de função e variáveis declaradas como `var` são Hoisting nem expressões de função ou arrow, let e const são palavras-chave.

No código abaixo temos um exemplo.

console.log(y);
y = 1;
console.log(y);
console.log(greet("Mark"));

function greet(name){
  return 'Hello ' + name + '!';
}

var y;

Este código registra `undefined`, `1`, `Hello Palamar!` respectivamente.
Portanto, a fase de compilação ficaria assim.

function greet(name) {
  return 'Hello ' + name + '!';
}

var y; //implicit "undefined" assignment

//waiting for "compilation" phase to finish

//then start "execution" phase
/*
console.log(y);
y = 1;
console.log(y);
console.log(greet("Palamar"));
*/

por exemplo, comentei sobre a atribuição de chamada de variável e função .

Após o término da fase de compilação , ela inicia a fase de execução , invocando métodos e atribuindo valores às variáveis.

function greet(name) {
  return 'Hello ' + name + '!';
}

var y;

//start "execution" phase

console.log(y);
y = 1;
console.log(y);
console.log(greet("Palamar"));

19. O que é escopo ?

O escopo em JavaScript é a área em que temos acesso válido a variáveis ou funções. JavaScript tem três tipos de escopos. Escopo Global , Escopo da Função e Escopo do Bloco (ES6) .

  • Escopo Global - variáveis ou funções declaradas no espaço de nomes global estão no escopo global e, portanto, estão acessíveis em qualquer lugar em nosso código.
//global namespace
   var g = "global";

   function globalFunc(){
     function innerFunc(){
          console.log(g); // can access "g" because "g" is a global variable
     }
     innerFunc();
   }  
  • Escopo da Função - variáveis, funções e parâmetros declarados em uma função que são acessíveis dentro dessa função, mas não fora dela.
function myFavoriteFunc(a) {
       if (true) {
          var b = "Hello " + a;
       }
       return b;
   }
   myFavoriteFunc("World");

   console.log(a); // Throws a ReferenceError "a" is not defined
   console.log(b); // does not continue here 

Escopo do bloco - variáveis ( `let, const`) declaradas em um bloco { } só podem ter acesso dentro dele.

function testBlock(){
   if(true){
     let z = 5;
   }
   return z; 
 }

 testBlock(); // Throws a ReferenceError "z" is not defined

Escopo também é um conjunto de regras para encontrar variáveis. Ele procura a variável mais próxima e para de procurar quando encontra. Isso é chamado de cadeia de escopo .

/* Scope Chain
   Inside inner function perspective

   inner's scope -> outer's scope -> global's scope
  */

  //Global Scope
  var variable1 = "Comrades";   
  var variable2 = "Sayonara";

  function outer(){
  //outer's scope
    var variable1 = "World";
    function inner(){
    //inner's scope
      var variable2 = "Hello";
      console.log(variable2 + " " + variable1);
    }
    inner();
  }  
  outer(); 
// logs Hello World 
// because (variable2 = "Hello") and (variable1 = "World") are the nearest 
// variables inside inner's scope.

20. O que são `Closures`?

Essa é provavelmente a pergunta mais difícil de todas essas perguntas, porque Closures é um tópico controverso. Então eu vou explicar pelo que eu entendo.

Closures é simplesmente a capacidade de uma função, no momento da declaração, lembrar as referências de variáveis e parâmetros em seu escopo atual, no escopo da função pai, no escopo da função pai do pai até atingir o escopo global com a ajuda da Cadeia de Escopo . Basicamente, é o escopo criado quando a função foi declarada.

No exemplo abaixo irei explicar o funcionamento Closures.

//Global's Scope
   var globalVar = "abc";

   function a(){
   //testClosures's Scope
     console.log(globalVar);
   }

   a(); //logs "abc" 
   /* Scope Chain
      Inside a function perspective

      a's scope -> global's scope  
   */ 

Neste exemplo, quando declaramos a afunção, o escopo global faz parte do a's Closure.

O motivo da variável `globalVar` que não possui um valor na imagem devido ao motivo pelo qual o valor dessa variável pode mudar com base em onde e quando invocamos a afunção.
Mas no nosso exemplo acima, a variável `globalVar` terá o valor de abc .

Ok, vamos ter um exemplo complexo.

var globalVar = "global";
var outerVar = "outer"

function outerFunc(outerParam) {
  function innerFunc(innerParam) {
    console.log(globalVar, outerParam, innerParam);
  }
  return innerFunc;
}

const x = outerFunc(outerVar);
outerVar = "outer-2";
globalVar = "guess"
x("inner");

A explicação para isso é que, quando invocamos a função `outerFunc` e atribuído o valor retornado da função `innerFunc` para a variável x, o `outerParam` terá um valor de exterior mesmo que atribuir um novo valor outer-2 para a variável `outerVar` porque a reatribuição aconteceu após a invocação de a outerfunção e, quando invocamos a função `outerFunc`, ela procura o valor de `outerVar` na cadeia de escopo , o valor `outerVar` de "outer" será "externo".

Agora, quando invocamos a variável x que tem uma referência a `innerFunc`, a `innerParam` terá um valor de inner porque esse é o valor que passamos na invocação e a `globalVar` variável terá um valor de palpite, porque antes de invocar a variável x atribuímos um novo valor para `globalVare`, no momento da invocação, valor x `globalVarna` Cadeia de escopo é
palpite .

Temos um exemplo que demonstra um problema de não entender o closures corretamente.

const arrFuncs = [];
for(var i = 0; i < 5; i++){
  arrFuncs.push(function (){
    return i;
  });
}
console.log(i); // i is 5

for (let i = 0; i < arrFuncs.length; i++) {
  console.log(arrFuncs[i]()); // all logs "5"
}

Este código não está funcionando como esperávamos devido aos closures.

O `var` cria uma variável global e, quando pressionamos uma função, retornamos a variável global `i`. Então, quando chamamos uma dessas funções nessa matriz após o loop, ele registra `5`porque obtemos o valor atual de iqual é `5` e podemos acessá-lo porque é uma variável global. Porque Closures mantém as referências dessa variável e não seus valores no momento de sua criação. Podemos resolver isso usando o `IIFES` ou alterando o `var` para `let` escopo do bloco.

21. Quais são os valores falsos no JavaScript ?

const falsyValues = ['', 0, null, undefined, NaN, false];

Os valores `falsy` são valores que quando convertidos em booleanos se tornam falsos .

22. Como verificar se um valor é falso ?

Use a função booleana ou o operador Double NOT !!

23. O que "use strict" faz?

"use strict" é um recurso do ES5 no JavaScript que transforma nosso código no Modo Estrito em funções ou scripts inteiros. O Modo Estrito nos ajuda a evitar erros no início de nosso código e adiciona restrições a ele.

Restrições que o Modo Estrito nos fornece.

Atribuindo ou acessando uma variável que não é declarada.

function returnY(){
    "use strict";
    y = 123;
    return y;
 }

Atribuir um valor a uma variável global somente leitura ou não gravável;

"use strict";
   var NaN = NaN;
   var undefined = undefined;
   var Infinity = "and beyond";

Excluindo uma propriedade não excluída.

"use strict";
   const obj = {};

   Object.defineProperty(obj, 'x', {
      value : '1'
   });  

   delete obj.x;
Nomes de parâmetros duplicados.

"use strict";

   function someFunc(a, b, b, c){

   }

Criando variáveis com o uso da função `eval` .

"use strict";

 eval("var x = 1;");

 console.log(x); //Throws a Reference Error x is not defined

O valor padrão disso será `undefined`.

"use strict";

  function showMeThis(){
    return this;
  }

  showMeThis(); //returns undefined

Existem muito mais restrições no modo estrito que essas.

Segunda Parte do curso.

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like