Práticas recomendadas de JavaScript


Índice

    Mostrar índice


Evite variáveis globais, evite new, evite ==, evite avaliação()


Evite variáveis globais

Minimize o uso de variáveis globais.

Isso inclui todos os tipos de dados, objetos e funções.

Variáveis e funções globais podem ser substituídas por outros scripts.

Use variáveis locais e aprenda como usar fechamentos.


Sempre declare variáveis locais

Todas as variáveis usadas em uma função devem ser declaradas como variáveis locais.

Variáveis locais devem ser declaradas com var, a palavra-chave let ou const, caso contrário, elas se tornarão variáveis globais.

O modo estrito não permite variáveis não declaradas.


Declarações no topo

É uma boa prática de codificação colocar todas as declarações no topo de cada script ou função.

Isso vai:

  • Dê um código mais limpo

  • Forneça um único local para procurar variáveis locais

  • Torne mais fácil evitar variáveis globais indesejadas (implícitas)

  • Reduza a possibilidade de redeclarações indesejadas

// Declare at the beginning
let firstName, lastName, price, discount, fullPrice;
 
// Use later
firstName = "John";
lastName = "Doe";
price = 19.90;
discount = 0.10;
fullPrice = price - discount;

Isso também vale para variáveis de loop:

for (let i = 0; i < 5; i++) 
 {


Inicializar variáveis

É uma boa prática de codificação inicializar variáveis ao declará-las.

Isso vai:

  • Dê um código mais limpo

  • Forneça um único local para inicializar variáveis

  • Evite valores indefinidos

// Declare and initiate at the beginning
let firstName = "";
let lastName = "";
let price = 0;
let discount = 0;
let fullPrice = 0,
const myArray = [];
const myObject = {};

A inicialização de variáveis fornece uma ideia do uso pretendido (e do tipo de dados pretendido).


Declarar objetos com const

Declarar objetos com const evitará qualquer mudança acidental de tipo:

Exemplo

let car = {type:"Fiat", model:"500", color:"white"};
car = "Fiat";      // Changes object to string
const car = {type:"Fiat", model:"500", color:"white"};
car = "Fiat";      // Not possible

Declarar matrizes com const

Declarar arrays com const evitará qualquer mudança acidental de tipo:

Exemplo

let cars = ["Saab", "Volvo", "BMW"];
cars = 3;    // Changes array to number
const cars = ["Saab", "Volvo", "BMW"];
cars = 3;    // Not possible

Não use novo objeto()

  • Use "" em vez de new String()

  • Use 0 em vez de new Number()

  • Use false em vez de new Boolean()

  • Use {} em vez de new Object()

  • Use [] em vez de new Array()

  • Use /()/ em vez de new RegExp()

  • Use function(){} em vez de new Function()

Exemplo

let x1 = "";             // new primitive string
let x2 = 0;              // new primitive number
let x3 = false;          // new primitive boolean
const x4 = {};           // new object
const x5 = [];           // new array object
const x6 = /()/;         // new regexp object
const x7 = function(){}; // new function object

Experimente você mesmo →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Literal Constructors</h2>
<p id="demo"></p>

<script>
let x1 = "";
let x2 = 0;
let x3 = false;
const x4 = {};
const x5 = [];
const x6 = /()/;
const x7 = function(){};

document.getElementById("demo").innerHTML =
"x1: " + typeof x1 + "<br>" +
"x2: " + typeof x2 + "<br>" +
"x3: " + typeof x3 + "<br>" +
"x4: " + typeof x4 + "<br>" +
"x5: " + typeof x5 + "<br>" +
"x6: " + typeof x6 + "<br>" +
"x7: " + typeof x7 + "<br>";
</script>

</body>
</html>

Cuidado com as conversões automáticas de tipo

JavaScript é digitado livremente.

Uma variável pode conter todos os tipos de dados.

Uma variável pode alterar seu tipo de dados:

Exemplo

let x = "Hello";     // typeof x is a string
x = 5;               // changes typeof x to a number

Experimente você mesmo →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Variables</h2>

<p>A variable can chang its type. In this example x is first a string then a number:</p>

<p id="demo"></p>

<script>
let x = "Hello";
x = 5;
document.getElementById("demo").innerHTML = typeof x;
</script>

</body>
</html>

Cuidado, pois os números podem ser acidentalmente convertidos em strings ou NaN (não é um Número).

Ao realizar operações matemáticas, o JavaScript pode converter números em strings:

Exemplo

let x = 5 + 7;       // x.valueOf() is 12,  typeof x is a number
let x = 5 + "7";     // x.valueOf() is 57,  typeof x is a string
let x = "5" + 7;     // x.valueOf() is 57,  typeof x is a string
let x = 5 - 7;       // x.valueOf() is -2,  typeof x is a number
let x = 5 - "7";     // x.valueOf() is -2,  typeof x is a number
let x = "5" - 7;     // x.valueOf() is -2,  typeof x is a number
let x = 5 - "x";     // x.valueOf() is NaN, typeof x is a number

Experimente você mesmo →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Variables</h2>

<p>Remove the comment (at the beginning of the lines) to test each case:</p>

<p id="demo"></p>

<script>
let x = 5;
//x = 5 + 7;    // x.valueOf() is 12, typeof x is a number
//x = 5 + "7";  // x.valueOf() is 57, typeof x is a string
//x = "5" + 7;  // x.valueOf() is 57, typeof x is a string
//x = 5 - 7;    // x.valueOf() is -2, typeof x is a number
//x = 5 - "7";  // x.valueOf() is -2, typeof x is a number
//x = "5" - 7;  // x.valueOf() is -2, typeof x is a number
//x = 5 - "x";  // x.valueOf() is NaN, typeof x is a number

document.getElementById("demo").innerHTML = x.valueOf() + " " + typeof x;
</script>

</body>
</html>

Subtrair uma string de uma string não significa gera um erro, mas retorna NaN (não é um número):

Exemplo

"Hello" - "Dolly"    // returns NaN

Experimente você mesmo →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Variables</h2>

<p>Subtracting a string from a string, does not generate an error but returns NaN (Not a Number):</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = "Hello" - "Dolly";
</script>

</body>
</html> 

Usar === Comparação

O operador de comparação == sempre converte (para tipos correspondentes) antes comparação.

O operador === força a comparação de valores e tipo:

Exemplo

0 == "";        // true
1 == "1";       // true
1 == true;      // true

0 === "";       // false
1 === "1";      // false
1 === true;     
// false

Experimente você mesmo →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Comparisons</h2>

<p>Remove the comment (at the beginning of each line) to test each case:</p>

<p id="demo"></p>

<script>
let x;
//x = (0 == "");   // true
//x = (1 == "1");  // true
//x = (1 == true);   // true
//x = (0 === "");  // false
//x = (1 === "1");   // false
//x = (1 === true);  // false
document.getElementById("demo").innerHTML = x;
</script>

</body>
</html>


Usar padrões de parâmetros

Se uma função for chamada com um argumento faltante, o valor do argumento faltante argumento está definido como indefinido.

Valores indefinidos podem quebrar seu código. É um bom hábito atribuir padrões valores para argumentos.

Exemplo

function myFunction(x, y) {
    if (y === undefined) {
      y = 0;
     }
}

Experimente você mesmo →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Functions</h2>

<p>Setting a default value to a function parameter.</p>
<p id="demo"></p>

<script>
function myFunction(x, y) {
  if (y === undefined) {
    y = 0;
  }  
  return x * y;
}
document.getElementById("demo").innerHTML = myFunction(4);
</script>

</body>
</html>


ECMAScript 2015 permite parâmetros padrão na definição da função:

function (a=1, b=1) { /*function code*/  }

Leia mais sobre parâmetros e argumentos de função em Parâmetros de Função


Termine seus switches com padrões

Sempre termine suas instruções switch com um default. Mesmo se você achar que existe não há necessidade disso.

Exemplo

switch (new Date().getDay()) {
   
case 0:
      day = "Sunday";
      break;
  case 1:
      day = "Monday";
      break;
  case 2:
    day = "Tuesday";
     break;
   
case 3:
    day = "Wednesday";
      break;
   
case 4:
    day = "Thursday";
     break;
  case 5:
      day = "Friday";
      break;
  case 6:
    day = "Saturday";
      break;
  default:
    day = 
 "Unknown";
}

Experimente você mesmo →

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
let day;
switch (new Date().getDay()) {
  case 0:
    day = "Sunday";
    break;
  case 1:
    day = "Monday";
    break;
  case 2:
    day = "Tuesday";
    break;
  case 3:
    day = "Wednesday";
    break;
  case 4:
    day = "Thursday";
    break;
  case 5:
    day = "Friday";
    break;
  case  6:
    day = "Saturday";
    break;
  default:
     day = "unknown";
}
document.getElementById("demo").innerHTML = "Today is " + day;
</script>

</body>
</html>

Evite número, string e booleano como objetos

Sempre trate números, strings ou booleanos como valores primitivos. Não como objetos.

Declarar esses tipos como objetos diminui a velocidade de execução, e produz efeitos colaterais desagradáveis:

Exemplo

let x = "John";             
let y = new String("John");
(x === y) // is false because x is a string and y is an object.

Experimente você mesmo →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript String Objects</h2>
<p>Never create strings as objects.</p>
<p>Strings and objects cannot be safely compared.</p>

<p id="demo"></p>

<script>
let x = "John";        // x is a string
let y = new String("John");  // y is an object
document.getElementById("demo").innerHTML = (x === y);
</script>

</body>
</html>

Ou ainda pior:

Exemplo

let x = new String("John");             
let y = new String("John");
(x == y) // is false because you cannot compare objects.

Experimente você mesmo →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript String Objects</h2>
<p>Never create strings as objects.</p>
<p>JavaScript cannot compare objects.</p>

<p id="demo"></p>

<script>
let x = new String("John"); 
let y = new String("John");
document.getElementById("demo").innerHTML = (x == y);
</script>

</body>
</html>

Evite usar eval()

A função eval() é usada para executar texto como código. Em quase todos os casos, é não deve ser necessário usá-lo.

Por permitir a execução de código arbitrário, também representa uma segurança problema.