O Javascript é uma linguagem muito diferente do que costumava ser há apenas alguns anos.
O Javascript, que é a especificação oficial do ECMAScript melhorou muito nos ultimos anos. Ele possui um comite conhecido como Ecma TC39, que faz lançamentos anuais de Javascript e mecanismo como V8, seguindo implementação de novos recursos.
Isso começou com o Javascript 2015, ou comumente conhecido com 6.0.
Segue as versões
Ver | Nome Oficial | Descrição |
---|---|---|
ES1 | ECMAScript 1 (1997) | First edition |
ES2 | ECMAScript 2 (1998) | Editorial changes |
ES3 | ECMAScript 3 (1999) | Added regular expressions |
Added try/catch | ||
Added switch | ||
Added do-while | ||
ES4 | ECMAScript 4 | Never released |
ES5 | ECMAScript 5 (2009) | Added "strict mode" |
Added JSON support | ||
Read More | Added String.trim() | |
Added Array.isArray() | ||
Added Array iteration methods | ||
Allows trailing commas for object literals | ||
ES6 | ECMAScript 2015 | Added let and const |
Added default parameter values | ||
Read More | Added Array.find() | |
Added Array.findIndex() | ||
ECMAScript 2016 | Added exponential operator (**) | |
Added Array.includes() | ||
Read More | ||
ECMAScript 2017 | Added string padding | |
Added Object.entries() | ||
Read More | Added Object.values() | |
Added async functions | ||
Added shared memory | ||
ECMAScript 2018 | Added rest / spread properties | |
Added asynchronous iteration | ||
Read More | Added Promise.finally() | |
Additions to RegExp |
Desde então temos lançamentos anuais chamado ES + ano.
Mas hoje a linguagem possui lançamentos constantes ao longo dos anos.
Podemos usar o compilador Babel para escrever recursos em andamento em Javascript.
Vamos ver algumas mudanças que já forma implementada na linguagem.
console.count(`contagem do log`); // contagem do log: 1
console.count(`contagem do log`); // contagem do log: 2
console.count(`contagem do log`); // contagem do log: 3
Um bloco em javascript
{
// Block Scope
}
if (true) {
// Block Scope
}
for (var i = 1; i <= 10; i++) {
// Block Scope
}
function sum(a, b) {
// Function Scope
var result = a + b;
}
sum(4 + 3);
Somente dentro de uma function que o Javascript respeita o escopo, ou seja a variavel result usando a palavra reservada var só existe no escopo da function.
Para resolver isso foram criada as palavras reservadas let
e const
, assim os escopo são respeitado:
for (var i = 1; i <= 10; i++) {
// Block Scope
}
i // Erro pois essa variavel só existe dentro do for
Trabalhar com imutabilidade.
// Scalar values
const answer = 42;
const greeting = 'Hello';
// Arrays and Objects
const numbers = [2, 4, 6];
const person = {
firstName: 'John',
lastName: 'Doe',
};
Os valores escalar não pode ser mudado. O apontamento dos Objetos e Arrays também não pode ser alterado, mas o conteúdo deles podem sem modificados.
Object.freeze()
Dê preferencia ao const ao invés do let.
A especificação introduzio uma nova maneira de funções.
As formas que tinhamos para declarar uma function:
function square(a) {
return a * a;
}
// Com função anonima
const square = function (a) {
return a * a;
};
Agora com arrow function
const square = (a) => {
return a * a;
}
// const square = (a) => a * a;
// const square = a => a * a;
Essa é a maneira preferivél porque se comporta de maneira mais prefisivél com closures.
Uma arrow function não se importa com quem chama, enquanto uma funçao normal se preocupa muito com isso.
const X = function () {
// "this" here is the caller of X
};
A função acima sempre liga o valor para a palavra chave para o seu chamado, e não tiver um chamador explicit veja o que acontece:
pr.js
// "this" here is "exports"
this.id = 'exports';
const testerObj = {
func1: function () {
console.log('func1', this);
},
func2: () => {
console.log('func2', this);
},
};
testerObj.func1();
testerObj.func2();
node pr.js
resulta em
func1 { func1: [Function: func1, func2: [Function: func2]}
func2 { id: 'exports'}
Uma maneira
const obj = {
key: value
};
Podemos iniciar os objetos
const obj = {
p1: 10,
p2: 20,
f1() {},
f2: () => {},
};
Foi criado uma nova forma agora veja:
const mastery = 'answer';
const obj = {
p1: 10,
p2: 20,
f1() {},
f2: () => {},
[mastery]: 42
};
Não confunda com uma matrix [mastery]: 42
obj.mastery
resulta undefined
obj.answer
resulta em 42
Também podemos
const p2 = Math.PI;
const obj = {
p1: 10,
p2: p2
}
Podemos simplificar
const p2 = Math.PI;
const obj = {
p1: 10,
p2
}
// const PI = Math.PI;
// const E = Math.E;
// const SQRT2 = Math.SQRT2;
const { PI, E, SQRT2 } = Math;
console.log(PI);
A desestruturação funciona com objetos.
// With require
const { readFile } = require('fs');
readFile // [Function]
A desestruturação funciona também em argumentos da função
const circle = {
label: 'circleX',
radius: 2,
};
const circleArea = ({ radius }) =>
(PI * radius * radius).toFixed(2);
console.log(circleArea(circle));
Ao inves de passar o objeto, podemos usar a sintaxe de destruturação dentro do parenteses. Isso melhora a legibilidade das funções.
E se quiser colocar um objeto com uma propriedade opcional:
const circle = {
label: 'circleX',
radius: 2,
};
const circleArea = ({ radius }, { precision = 2} = {}) =>
(PI * radius * radius).toFixed(precision);
console.log(circleArea(circle)); // Podemos chamar assim, pois o segundo argumento é opcional
console.log(circleArea(circle, {precision: 5}));
A desestruturação também funciona para extrais dados de uma matrix.
const [first, second,,forth] = [10,20,30,40];
first // 10
Usando o operador rest
const [first, ...restOfItens] = [10,20,30,40];
first // 10
restOfItens // [20,30,40]
Em um objeto
const data = {
temp1: '00',
temp2: '002',
firstname: 'John',
lastName: 'Doe'
};
const {temp1, temp2, ...person} = data;
console.log(person); // { firstname: 'John', lastName: 'Doe' }
Podemos também fazer cópia rasa
const newObject = {
...person,
};
console.log(newObject);
Foi introduzido uma nova forma de criar uma string e que aceita interpolação de uma variavél e permite que escrevemos essa string em varias linhas.
const greeting = "Hello World";
const answer = 'Forty Two';
const html = `
<div>
${Math.random()}
</div>
`;
O javascript oferece muitos paradigmas de programação e a programação orientad a objetos é uma delas.
Tudo em javascript é objeto, incluindo funções. Javascript adicionou suporte para a sintaxe de classe.
Uma classe é um modelo para definir uma estrutura compartilhada e comportamento entre objetos semelhantes.
Podemos estender outras classes e instanciar, e também personalizar a construção de cada objeto e definir funções compartilhadas entre esses objetos.
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello ${this.name}!`);
}
}
class Student extends Person {
constructor(name, level) {
super(name);
this.level = level;
}
greet() {
console.log(`Hello ${this.name} from ${this.level}`);
}
}
const o1 = new Person("Max");
const o2 = new Student("Tina", "1st Grade");
const o3 = new Student("Mary", "2nd Grade");
o3.greet = () => console.log('I am special!');
o1.greet(); // Hello Max!
o2.greet(); // Hello Tina from 1st Grade
o3.greet(); // I am special!
Aqui, temos uma função de busca simples que lê uma resposta HTTPS.
const https = require('https');
function fetch (url) {
return new Promise((resolve, reject) => {
https.get(url, (res) => {
let data = '';
res.on('data', (rd) => data = data + rd);
res.on('end', () => resolve(data));
res.on('error', reject);
});
});
}
Para consumir de duas maneiras
Consumindo qualquer promisse
fetch('https://www.javascript.com/')
.then(data => {
console.log(data.length);
});
Ou consumindo usando aync/await
(async function read() {
const data = await fetch('https://www.javascript.com/');
console.log(data.length);
})();
Usamos a palavra await antes da promessa e isso nos dará acesso aos dados disponiveis após a ação assíncrona. Podemos usar esses dados agora após a linha de espera. mas precisamos transformar a função em async