Ad

Exercício:

A função "a" deve retornar uma promise sem usar a classe Promise.

Modifique a função "b" de forma que execute a promise de "a" sem usar then/catch.

function a() {
  return new Promise(function (resolve, reject) {
    resolve('ok');
  });
}

function b() {
  a().then(function(res) {
    console.log(res);
  }).catch(function(err) {
    console.log(err);
  })
}

Exercício:

Reescreva os códigos utilizando os novos recursos do ES6

// 1 - Encontre  um número maior que 6
var arr = [1, 4, 6, 8, 10];
var resp = null;
for (var i = 0; i < arr.length; ++i) {
	if (arr[i] > 6) {
		resp = arr[i];
		break;
	}
}


// 2 - Encontre o índice de um número maior que 6
var arr = [1, 4, 6, 8, 10];
var resp = null;
for (var i = 0; i < arr.length; ++i) {
	if (arr[i] > 6) {
		resp = i;
		break;
	}
}


// 3 - Encontre os numeros maiores que 6
var arr = [1, 4, 6, 8, 10];
var resp = arr.reduce((carry, item) => {
  if (item > 6)
    carry.push(item);
  return carry;
}, []);


// 4 - O array contém o número 6?
var arr = [1, 4, 6, 8, 10];
var resp = arr.indexOf(6) > -1;


// 5 - Todos os números do array são números pares?
var arr = [2, 4, 6, 8, 9];
var resp = true;
for (var i = 0; i < arr.length; ++i) {
  if (arr[i] % 2 !== 0) {
    resp = false;
    break;
  }
}

// 6 - Algum número no array é impar?
var arr = [2, 4, 0, -2];
var resp = arr.reduce(function (carry, item) {
  return carry || (item % 2 !== 0);
}, false);

Exercício:

Crie um construtor para classe Collection onde receba 2 parâmetros. Não esqueça de iniciar o construtor da classe base.

new Collection('#body', true);
class Component {
  constructor(dom) {
    console.log('Parent class constructor executed!');
    this.dom = dom;
  }
  
  onCreate() {
    return true;
  }
}

class Collection {
  // 
}

Exercício:

Crie a classe Title, herde Component e sobrescreva o método onCreate para retornar a string "super!", mas que também execute o método onCreate da classe base.

class Component {
  constructor(dom) {
      this.dom = dom;
  }
  
  onCreate() {
    console.log('onCreate from parent class');
    return 'missing';
  }
  
  static on(event, callback) {
    callback();
  }
  
  async emit(event, data) {}
}

Exercício:

Use os novos recursos do ES6 para resolver os problemas do dia a dia.

// 1 - Criar um separador de 20 hífens

var separador = '';

for (var i = 20; i--;)
  separador += '-';


// 2 - Completar com espaços à esquerda para formar uma string de 20 caracteres

var titulo = 'UOL';

titulo = new Array(20 - titulo.length + 1).fill('').join(' ') + titulo;


// 3 - Completar com espaços à direita para formar uma string de 20 caracteres

var titulo = 'UOL';

for (var i = 20 - titulo.length; i--; titulo += ' ');


// 4 - Verificar se a string contém outra string em boolean

var titulo = 'UOL - O melhor conteúdo';

var resp = titulo.indexOf('melhor') !== -1;


// 5 - Verificar se a string começa com outra string em boolean

var titulo = 'UOL - O melhor conteúdo';

var resp = titulo.indexOf('UOL') == 0;


// 6 - Verificar se a string termina com outra string em boolean

var titulo = 'UOL - O melhor conteúdo';

var resp = new RegExp('melhor$').test(titulo);

Com destructuring e deep matching conseguimos navegar por um objeto até chegar no valor da propriedade.

Exercício:

Navague até o título nos array resultados e imprima no console o valor. Assuma "Brasil" como valor padrão quando "titulo" não existir.

let results = [
  {materia: {conteudo: {titulo: 'São Paulo'}}, tags: [1, 2, 3]},
  {materia: {conteudo: {}}, tags: [3, 2]},
  {materia: {conteudo: {titulo: 'Rio de Janeiro'}}, tags: [3, 2]},
];

for (const result of results) {
  let titulo = result.materia.conteudo.titulo || 'Brasil';
  console.log(titulo);
}

Exercício:

Troque os valores de A por B e B por A sem criar uma nova variável.

let a = 5, b = 10;

// reescreva
// resolva sem precisar de uma nova variável
let c = a;
a = b;
b = c;

Quando estamos criando uma lib em JS é comum colocarmos tudo dentro de uma função anônima. Mas porquê? Um dos motivos é garantir que as variáveis externas não vão conflitar com suas variáveis e que as variáveis que você está criando não vão conflitar com o resto do programa. Existem outros motivos, mas voltando a raiz esse é o principal.

Exercício:

ES6 trouxe um novo recurso que veio para substituir funções anônimas quando queremos criar um escopo/contexto. Substitua a função anônima por esse recurso.

function todo() {
  return 'Walk';
}

// reescrever em ES6
(function() {

  function todo() {
    return 'Run';
  }

})();

Para definir variáveis no JS, opcionalmente, mas altamente recomendado usamos a keyword var. Var possui algumas particularidades, como içamento, que a princípio veio para otimizar nosso código mas causou alguns efeitos colaterais.

ES6 trouxe duas novas palavras-chaves para auxiliar na declaração de variáveis: let e const.

Exercício:

Substitua var por let ou const quando necessário.

// Exercício 1
var titulo = "UOL - O melhor conteúdo";


// Exercício 2
var tags = []

tags.push(...['A', 'B']);


// Exercício 3
var descricao = "Em 1999";

descricao += " em São Paulo";


// Exercício 4
var materia = {titulo: "Barão de Limeira"};

materia.titulo = "Alameda " + materia.titulo;


// Exercício 5
for (var i = 10; i--;) {
  console.log(i);
}


// Exercício 6
for (var tag of ['A', 'B']) {
  console.log(tag);
}


// Exercício 7
for (var j = [].length; j--;) {}

if (j === -1) {
  console.log('Não encontrei');
}


// Exercício 8
var a = 123;

{
  a *= 2;
}

console.log(a);


// Exercício 9
var state = 'active';

function stop() {
  state = 'paused';
}

stop();


// Exercício 10
var TRUE = !0;

Exercício:

Capture o reject da Promise em ES6.

function monteCarlo() {
  return new Promise(function (resolve, reject) {
    reject({server: 'down'});
  });
}

async function main() {

  // converter para ES6
  const results = await monteCarlo();
  
  return true;
}

Não há limite para a quantidade de parâmetros que você pode enviar para uma função JS. A assinatura é um meio mais fácil de acessar alguns desses parâmetros. Em alguns casos pode ser muito útil definir assumir um valor padrão quando o parâmetro é opcional. Uma forma de verificar se o parâmetro foi ou não definido é validar com undefined. Só que com ES6 existe uma forma mais simples e elegante de tornar parâmetros opcionais.

Exercício:

Reescreva o código em ES6.

// reescreva em ES6
function main(a, b, c) {
    if (typeof b == 'undefined')
        b = 2;
    
    if (typeof c == 'undefined')
        c = 3
    
    return a * b * c;
}

Além de trazer novidades na escrita da linguagem, ES6 também trouxe novas classes.

Exercício:

Remover os itens duplicados do array sem percorrer o array

const main = () => {
  
  let links = [
    'https://www.uol',
    'https://www.bol.com.br',
    'https://www.uol',
    'https://noticias.uol.com.br',
    'https://www.bol.com.br',
  ];
  
  // converter para ES6
  var uniqueLinks = links.reduce(function (carry, item) {
    if (carry.indexOf(item) === -1) {
      carry.push(item);
    }
    return carry;
  }, []);
  
  
  return uniqueLinks.length;
};

Async / await vieram para facilitar a execução de código assíncrono, muitas vezes encapsulado em Promises e dar maior controle sobre o fluxo de execução, dando a possibilidade de transformar trechos assíncronos em síncronos evitando callbacks excessivos (callback from hell).

Exercício:

Converta a execução da Promise para async/await.

function monteCarlo() {
  return new Promise(function (resolve, reject) {
    resolve([{
      titulo: 'UOL - O Melhor conteúdo'
    }]);
  });
}

async function main() {

  // converter para ES6
  monteCarlo().then(function(response) {
    console.log(response)
  });
  
  return true;
}

LazyRange cria um range de um número até outro com generators. O benefício do generator é que o range só será criado quando necessário.

E se pudermos alinhar generators de forma que várias instruções sejam executadas porém somente quando necessário, evitando percorrer o mesmo array diversas vezes?

Estamos falando de pura performance.

Exercício:

Implementar a função plusOne que some 1 em cada item de doubleRangeValue e retorne os valores sob demanda (generator).

function* lazyRange(start, stop) {
  while (start <= stop) {
    console.log(`Interando ${start}`);
    yield start;
    ++start;
  }
}

function* doubleRangeValue(...args) {
  for (let value of lazyRange(...args)) {
    value *= 2;
    console.log(`Dobro ${value}`);
    yield value;
  }
}

function* plusOne() {
  // implemente
}

async function main() {
  let resp = [...plusOne(1, 5)];
  return resp.join(',');
}

"Você precisa disso para agora?"

Ou então apenas repasse.

Generator é uma instrução que fica na espera, somente é executada quando necessário.

Exercício:

Percorrer o generator na função main e para cada item imprimir no console seu valor.

function* lazyRange(start, stop) {
  while (start <= stop) {
    console.log(`Interando ${start}`);
    yield start;
    ++start;
  }
}

function createRange() {
  console.log("Criando um range");
  return lazyRange(1, 10);
}

function getData() {
  let theRange = createRange();
  console.log("Repassando o range");
  return {theRange};
}

function main() {
  let resp = getData();
  
  // percorra o generator executando o trecho comentado abaixo
  // console.log(`Valor ${item}`);
  
  return 1;
}
Loading more items...