Código limpo de JavaScript - práticas recomendadas rápidas
Tags: javascript, tutorial, programming
Published: 2022-12-28 20:26:05

Se você se preocupa com o código em si e como está escrito, em vez de se preocupar apenas se funciona ou não, pode dizer que pratica e se preocupa com o código limpo.

> _Um desenvolvedor profissional escreverá o código para o eu futuro e para o "outro cara", não apenas para a máquina._

Com base nisso, o código limpo pode ser definido como o código escrito de maneira autoexplicativa, fácil de entender por humanos e fácil de alterar ou estender.

> _Mesmo um código ruim pode funcionar, mas se o código não estiver limpo, ele pode colocar uma organização de desenvolvimento de joelhos._

Neste artigo, o foco será em JavaScript , mas os princípios podem ser aplicados a outras linguagens de programação.

1. Verificações de tipo forte

```jsx
0 == false // true
0 === false // false
2 == "2" // true
2 === "2" // false

// example
const val = "123";

if (val === 123) {
  console.log(val);
  // it cannot not be reached
}

if (val === "123") {
  console.log(val);
  // it can be reached
}
```
2. Variáveis

Nomeie suas variáveis ​​de forma que elas revelem a intenção por trás delas. Dessa forma, elas se tornam pesquisáveis ​​e fáceis de entender depois que uma pessoa os vê.

#### Ruim 👎

```jsx
let daysSLV = 10;

let y = new Date().getFullYear();

let ok;

if (user.age > 30) {
  ok = true;
}
```

#### Bom 👍

```jsx
const MAX_AGE = 30;

let daysSinceLastVisit = 10;

let currentYear = new Date().getFullYear();

...

const isUserOlderThanAllowed = user.age > MAX_AGE;
```
Não adicione palavras extras desnecessárias aos nomes das variáveis:

#### Ruim 👎

```jsx
let nameValue;
let theProduct;
```

#### Bom 👍

```jsx
let name;
let product;
```

Não imponha a necessidade de memorizar o contexto variável:

#### Ruim 👎

```jsx
const products = ["T-Shirt", "Shoes", "Watches", "Bags"];

products.forEach(p => {
  doSomething();
  doSomethingElse();
  // ...
  // ...
  // ...
  // ...
  // What is `p` for?
  register(p);
});
```

#### Bom 👍

```jsx

const products = ["T-Shirt", "Shoes", "Watches", "Bags"];

products.forEach(product => {
  doSomething();
  doSomethingElse();
  // ...
  // ...
  // ...
  register(product);
});
```
Não adicione contexto desnecessário:


#### Ruim 👎

```jsx
const product = {
  productId: 1,
  productName: "T-Shirt",
  productPrice: 8.99,
  productUnits: 12
};

...

product.productName;
```

#### Bom 👍

```jsx

const product = {
  id: 1,
  name: "T-Shirt",
  price: 8.99,
  units: 12
};

...

product.name;
```

Use o mesmo vocabulário para o mesmo tipo de variável

#### Ruim 👎

```jsx
getUserInfo();
getClientData();
getCustomerRecord();
```

#### Bom 👍

```jsx
getProduct();
```
3. Funções

Use nomes longos e descritivos.

Considerando que representa um determinado comportamento, o nome de uma função deve ser um verbo ou uma frase que exponha totalmente a intenção por trás dela, bem como a intenção dos argumentos.

Seu nome deve dizer o que elas fazem:


#### Ruim 👎

```jsx
function email(user) {
  // implementation
}
```

#### Bom 👍

```jsx
function sendEmailUser(emailAddress) {
  // implementation
}
```
Evite um longo número de argumentos, idealmente, uma função deve ter dois ou menos argumentos especificados. Quanto menos argumentos, mais fácil é testar a função:


#### Ruim 👎

```jsx
function getProducts(fields, fromDate, toDate) {
  // implementation
}
```

#### Bom 👍

```jsx
function getProducts({ fields, fromDate, toDate }) {
  // implementation
}

getProducts({
  fields: ['id', 'name', 'price', 'units],
  fromDate: '2020-07-01',
  toDate: '2020-07-22'
});
```
Use argumentos default em vez de condicionais;

#### Ruim 👎

```
function createShape(type) {
  const shapeType = type || "circle";
  // ...
}
```

#### Bom 👍

```jsx
function createShape(type = "circle") {
  // ...
}
```

Evite executar várias ações em uma única função:

#### Ruim 👎

```jsx
function notifyUsers(users) {
  users.forEach(user => {
    const userRecord = database.lookup(user);
    if (userRecord.isVerified()) {
      notify(user);
    }
  });
}
```

#### Bom 👍

```jsx
function notifyVerifiedUsers(users) {
  users.filter(isUserVerified).forEach(notify);
}

function isUserVerified(user) {
  const userRecord = database.lookup(user);
  return userRecord.isVerified();
```

Use 'Object.assign' para definir objetos default:

#### Ruim 👎

```jsx
const shapeConfig = {
  type: "circle",
  width: 150,
  height: null
};

function createShape(config) {
  config.type = config.type || "circle";
  config.width = config.width || 300;
  config.height = config.height || 300;
}
```

#### Bom 👍

```jsx
const shapeConfig = {
  type: "circle",
  width: 150
  // Exclude the 'height' key
};

function createShape(config) {
  config = Object.assign(
    {
      type: "circle",
      width: 300,
      height: 300
    },
    config
  );
  ...
}
  
```

Não use sinalizadores como parâmetros, porque eles estão dizendo que a função está fazendo mais do que deveria:

#### Ruim 👎

```jsx
function createFile(name, isPublic) {
  if (isPublic) {
    fs.create(`./public/${name}`);
  } else {
    fs.create(name);
  }
}
```

#### Bom 👍

```jsx
function createFile(name) {
  fs.create(name);
}

function createPublicFile(name) {
  createFile(`./public/${name}`);
}
```
Não polua os globais, se você precisar estender um objeto existente, use classes ES e herança em vez de criar a função na cadeia de protótipos do objeto nativo:

#### Ruim 👎

```jsx
Array.prototype.myFunction = function myFunction() {
  // implementation
};
```

#### Bom 👍

```jsx
class SuperArray extends Array {
  myFunc() {
    // implementation
  }
}
```

4. Condicionais

Evite condicionais negativas:

#### Ruim 👎

```jsx
function isPostNotPublished(post) {
  // implementation
}
if (!isPostNotPublished(post)) {
  // implementation
}
```

#### Bom 👍

```jsx
function isPostPublished(user) {
  // implementation
}
if (isPostPublished(user)) {
  // implementation
}
```

Use abreviação condicional, esta abordagem serve apenas para valores booleanos e se tiver certeza de que o valor não será null ou undefined:

#### Ruim 👎

```jsx
if (isValid === true) {
  // do something...
}
if (isValid === false) {
  // do something...
}
```

#### Bom 👍

```jsx
if (isValid) {
  // do something...
}
if (!isValid) {
  // do something...
}
```

Evite condicionais sempre que possível, em vez disso, use polimorfismo e herança:

#### Ruim 👎

```jsx
class Dog {
  // ...
  getBreed() {
    switch (this.type) {
      case "GermanShepherd":
        return this.getStandardSize("GermanShepherd");
      case "JackRussellTerrier":
        return this.getStandardSize("JackRussellTerrier");
      case "ShibaInu":
        return this.getStandardSize("ShibaInu");
    }
  }
}
```

#### Bom 👍

```jsx
class Dog {
  // ...
}

class GermanShepherd extends Dog {
  // ...
  getStandardSize() {
    return this.standardSize;
  }
}

class JackRussellTerrier extends Dog {
  // ...
  getSize() {
    return this.standardSize;
  }
}

class ShibaInu extends Dog {
  // ...
  getSize() {
    return this.standardSize;
  }
}
```

5. ES Classes

As classes são o novo açúcar sintático em JavaScript. Tudo funciona exatamente como antes com o protótipo, mas agora parece diferente e você deve preferi-los às funções simples do ES5:

#### Ruim 👍

```jsx
const Product = function(name) {
  if (!(this instanceof Product)) {
    throw new Error("Instantiate Product with `new` keyword");
  }
  this.name = name;
};

Product.prototype.getSize = function getSize() { /**/ };

const Tshirt = function(name, color) {
  if (!(this instanceof Tshirt)) {
    throw new Error("Instantiate Tshirt with `new` keyword");
  }
  Product.call(this, name);
  this.color = color;
};

Tshirt.prototype = Object.create(Product.prototype);
Tshirt.prototype.constructor = Tshirt;
Tshirt.prototype.printColor = function printColor() { /**/ };
```

#### Bom 👍

```jsx
class Product {
  
  constructor(name) {
    this.name = name;
  }
  
  getDiscount() {
    /* ... */
  }
}

class Tshirt extends Product {
  
  constructor(name, color) {
    super(name);
    this.color = color;
  }
  
  getSize() {
    /* ... */
  }
}
```

Use encadeamento de métodos, muitas bibliotecas, como jQuery e Lodash, usam esse padrão. Como resultado, seu código será menos detalhado. Em sua classe, simplesmente retorne isso no final de cada função e você poderá encadear outros métodos de classe nela:

#### Ruim 👍

```jsx
class Product {
  
  constructor(name) {
    this.name = name;
  }
  
  setPrice(price) {
    this.price = price;
  }
  
  setUnits(units) {
    this.units = units;
  }
  
  save() {
    console.log(this.name, this.price, this.units);
  }
}

const product = new Product("Bag");

product.setPrice(23.99);
product.setUnits(12);
product.save();
```

#### Bom 👍

```jsx
class Product {
  
  constructor(name) {
    this.name = name;
  }
  
  setName(name) {
    this.name = name;
    // Return this for chaining
    return this;
  }
  
  setPrice(price) {
    this.price = price;
    // Return this for chaining
    return this;
  }
  
  save() {
    console.log(this.name, this.price, this.units);
    // Return this for chaining
    return this;
  }
}

const product = new Product("T-Shirt")
    .setName("Jeans")
    .setAge(31.99)
    .save();
```

6. Evite usar Eval

A função Eval nos permite passar uma string para o compilador JavaScript e executá-la como JavaScript. Em termos simples, qualquer coisa que você passar em tempo de execução será executada como se tivesse sido adicionada em tempo de execução:

```jsx
eval("alert('Hi');");
```
Isso abriria uma caixa de alerta com a mensagem "Olá".

> _A função Eval deve ser evitada porque não é segura e abre um vetor de ameaça potencial para os programadores mal-intencionados explorarem._

7. Use ESLint

ESLint é uma ótima ferramenta para ajudá-lo a identificar problemas comuns em seu código JavaScript, ele irá detectar códigos ruins que estão sendo mascarados pelo navegador. Isso tornará seu código mais limpo e ajudará a evitar que esses bugs incômodos apareçam na produção.

8. Evite em geral

Em geral, você deve fazer o possível para não se repetir, o que significa que não deve escrever código duplicado e não deixar rastros para trás, como funções não utilizadas e código morto.

> _Remover código duplicado nessa situação significa abstrair as diferenças e tratá-las nesse nível._

E sobre o código morto , bem é o que o nome diz.

É o código parado em nossa base de código que não está fazendo nada porque, em algum momento do desenvolvimento, você decidiu que ele não tem mais um propósito .

Você deve procurar essas partes em sua base de código e excluir todas as funções e blocos de código desnecessários.

> _Um conselho que posso dar a você é que, assim que decidir que não é mais necessário, exclua-o._

## Conclusão

Isso é apenas uma fração do que você poderia fazer para melhorar seu código.

> _Na minha opinião, os princípios aqui alegados são aqueles que muitas vezes as pessoas não seguem._

Eles tentam, mas não é fácil manter a força mental e fazer um ótimo código o tempo todo .

Talvez no início do projeto, o código esteja organizado e limpo , mas quando se trata de cumprir os prazos, os princípios são frequentemente ignorados e movidos para uma seção “TODO” ou “REFACTOR” .

Obrigado por ler e até o próximo artigo!