Técnico

Você realmente precisa do Underscore?

Atualmente, bibliotecas úteis como Underscore e Lodash encontraram seu lugar reservado na caixa de ferramentas básicas de muitos desenvolvedores javascripts.

Enquanto essas bibliotecas deixam o desenvolvimento mais fácil, elas não necessariamente deixam o código simples ou fácil de entender. As pessoas que estão desenvolvendo no mesmo código, são obrigadas a conhecer a biblioteca que está sendo usada.

Bibliotecas vem e vão, e todo desenvolvedor tem a sua favorita. Mas sempre acabam se perguntando, qual é a ordem de argumentos que essa função recebe, ou qual biblioteca é essa mesmo, será que é underscore, será lodash ou talvez ramda, ou qualquer abstração que tiver hoje em dia.

Quando se desenvolve um código simples que usa funções da biblioteca padrão, é muito mais fácil para o futuro desenvolvedor que for manter aquele código (que provavelmente vai ser você mesmo) entender.

É muito mais fácil refatorar um código verboso com algumas abstrações do que um código conciso com abstrações incorretas. Quando você começa a ver padrões em seu código repetido várias e várias vezes, é hora de abstrair.

[markdown]

O javascript vem evoluindo continuamente, e com isso uma variedade de novas features, e com [Babel](https://babeljs.io/) torna-se muito fácil de usa-las. E essas novas features deixam algumas funções dessas bibliotecas úteis, obsoletas.

Bons recursos para aprender essas novas features é a [pagina no site Babel](https://babeljs.io/docs/learn-es2015/) ou o excelente livro escrito por Nicholas C. Zakas, [Entendendo ECMAScript 6](https://leanpub.com/understandinges6/read). Aprendendo a utilizar completamente o javascript lhe dá um poder de desenvolvimento absurdo, e é bem mais provável que irá ficar por muito mais tempo que as bibliotecas citadas.

Isso não quer dizer que não há lugar para mais nenhuma biblioteca instalada pelo [npm](https://www.npmjs.com/).

É que muitas funções que eram quase essenciais, a fim de ser produtivo quando estávamos desenvolvendo com ES3 não são mais necessárias, e hoje pode ser melhor, usando apenas javascript puro para realizar o desenvolvimento.

[/markdown]

[markdown]

##Exemplos
Os exemplos abaixo mostram algumas features contidas no ES5.1, ES2015 e ES2016 que deixa fácil a não necessidade de qualquer biblioteca de terceiros.

###O que preciso para usá-las?
**ES5** é hoje nativamente suportado por todos os browsers atuais e também pelo [NodeJS](https://nodejs.org/en/). Os exemplos com ES2015 e ES2016 podem ser compilados com [BabelJS](http://babeljs.io/docs/setup/), sendo muito fácil de adicionar em qualquer projeto.
###Arrays

####Iteração
**Função:**
O método each/foreach itera sobre uma lista de elementos. A interação é limitado ao contexto do objeto. Cada chamada do iterador é com 3 argumentos `(elemento, indice, lista)`. Se uma lista é um objeto javascript, os argumentos vão ser `(valor, chave, lista)`. Retornando a lista para o encadeamento.

**Underscore**

`
_.each(array, iteratee)
`

**ES5**

`
array.forEach(iteratee)
`
####Map
**Função:**
O método Map cria um novo array de valores mapeando cada valor da lista através de uma função de transformação `(iterador)`.

**Underscore**

`
_.map(array, iteratee)
`

**ES5**

`
array.map(iteratee)
`

####Reduce
**Função:**
O método reduce transforma uma lista de valores em um valor único.

**Underscore**

`
_.reduce(array, iteratee, memo)
`

**ES5**

`
array.reduce(iteratee, memo)
`

####Reduce Right
**Função:**
O método Reduce Right chama a função de retorno de chamada especificada para todos os elementos de uma matriz, em ordem decrescente

**Underscore**

`
_.reduceRight(array, iteratee, memo)
`

**ES5**

`
array.reduceRight(iteratee, memo)
`

####Every
**Função:**
O método every, testa todo os elementos da array passam no teste executado pela função em que fornecemos

**Underscore**

`
_.every(array, predicate)
`

**ES5**

`
array.every(predicate)
`

####Some
**Função:**
O método some faz basicamente o mesmo que o every, a única diferença é que ele testa se algum elemento do array passa no teste executado pela função que foi fornecida

**Underscore**

`
_.some(array, predicate)
`

**ES5**

`
array.some(predicate)
`

####Find
**Função:**
O método find retorna apenas o primeiro elemento que passe no teste especificado.

**Underscore**

`
_.find(array, predicate)
`

**ES5**

`
array.find(predicate)
`

####Pluck
**Função:**
O método pluck retorna uma lista formada por valores de uma propriedade específica.

**Underscore**

`
_.pluck(array, propertyName)
`

**ES5**

`
array.map(value => value[propertyName])
`
####Includes
**Função:**
O método includes checa se um array contem um elemento.

**Underscore**

`
_.includes(array, element)
`

**ES5**

`
array.includes(element)
`
####To Array
**Função:**
O método to array convert um objeto array para array.

**Underscore**

`
_.toArray(arguments)
`

**ES5**

`
[…arguments]
`

####Compact
**Função:**
O método compact convert cria uma copia de um array com todos valores falsos removidos.

**Underscore**

`
_.compact(array)
`

**ES5**

`
array.filter(Boolean)
`

####Uniq
**Função:**
O método uniq cria uma copia de um array com valores duplicados removidos.

**Underscore**

`
_.uniq(array)
`

**ES5**

`
[…new Set(array)]
`

####Index Of
**Função:**
O método indexof procura o indice de um valor em um array.

**Underscore**

`
_.indexOf(array, value)
`

**ES5**

`
array.indexOf(value)
`

####Range
**Função:**
O método range cria um array com n números, começão por x.

**Underscore**

`
_.range(x, x + n)
`

**ES5**

`
Array.from(Array(n), (v, k) => k + x)
`
###Objetos
####Keys
**Função:**
O método keys retorna um array com todos os nomes do próprio enumerador.

**Underscore**

`
_.keys(object)
`

**ES5**

`
Object.keys(object)
`

####Size
**Função:**
O método size retorna o numero de chaves em um objeto.

**Underscore**

`
_.size(object)
`

**ES5**

`
Object.keys(object).length
`

####All Keys
**Função:**
O método allkeys retorna um array com todos os nome de todos os enumeradores.

**Underscore**

`
_.allKeys(object)
`

**ES5**

`
[…Reflect.enumerate(object)]
`

####Values
**Função:**
O método values retorna todos os valores de um objeto.

**Underscore**

`
_.values(object)
`

**ES5**

`
Object.keys(object).map(key => object[key])
`

####Create
**Função:**
O método create cria um novo objeto com o dado prototype e propriedades.

**Underscore**

`
_.create(proto, properties)
`

**ES5**

`
Object.assign(Object.create(proto), properties)
`

####Assign
**Função:**
O método assign cria um novo objeto de um mesclado.

**Underscore**

`
_.assign({}, source, { a: false })
`

**ES5**

`
Object.assign({}, source, { a: false })
`

####IsArray
**Função:**
O método isArray verifica se um objeto é um array.

**Underscore**

`
_.isArray(object)
`

**ES5**

`
Array.isArray(object)
`

####IsNumber
**Função:**
O método isNumber verifica se um objeto é um numero finito.

**Underscore**

`
_.isNumber(object) && _.isFinite(object)
`

**ES5**

`
Number.isFinite(object)
`

###Funções
####Bind
**Função:**
O método bind vincula uma função em um objeto.

**Underscore**

“`
foo(_.bind(function () {
this.bar();
}, this));

foo(_.bind(object.fun, object));
“`

**ES5**

“`
foo(() => {
this.bar();
});

foo(::object.fun);
“`

[/markdown]

Autor(a)

Weslley Neri

Deixe um comentário

O seu endereço de e-mail não será publicado.