{"id":3533,"date":"2014-09-12T13:59:31","date_gmt":"2014-09-12T16:59:31","guid":{"rendered":"http:\/\/blog.turbosite.com.br\/?p=3533"},"modified":"2014-09-12T13:59:31","modified_gmt":"2014-09-12T16:59:31","slug":"conheca-16-hacks-de-javascript-que-podem-facilitar-muito-o-desenvolvimento","status":"publish","type":"post","link":"https:\/\/www.turbosite.com.br\/blog\/conheca-16-hacks-de-javascript-que-podem-facilitar-muito-o-desenvolvimento\/","title":{"rendered":"Conhe\u00e7a 16 Hacks Ninja de JavaScript que podem facilitar o desenvolvimento"},"content":{"rendered":"<p><span data-reactid=\".5d.1:3:1:$comment767337753324666_767341956657579:0.0.$right.0.$left.0.0.1:$comment-body.0.$end:0:$2:0\">Caio Ribeiro Pereira do blog <a href=\"http:\/\/udgwebdev.com\/15-javascript-hacks\/\" target=\"_blank\">UndergroundDev<\/a>, postou um artigo inspirador chamado &#8216;<strong>15 JavaScript Hacks<\/strong>&#8216;. Resolvemos dar nossa contribui\u00e7\u00e3o e acrescentamos mais\u00a0uma, confira:<\/span><\/p>\n<p>Neste post vamos\u00a0compartilhar 16 Hacks extremamente \u00fateis para se aplicar em JavaScript. As dicas s\u00e3o um acumulado de magias avan\u00e7adas que visam diminuir o tamanho do c\u00f3digo ou realizar um c\u00f3digo de forma muito eficiente. Ent\u00e3o\u00a0vamos l\u00e1!<\/p>\n<div class=\"post-content\">\n<h3>1) Concatenando strings direito<\/h3>\n<p>Com certeza um dev j\u00e1 precisou uma vez na vida montar uma string com base na concatena\u00e7\u00e3o de outras strings e de alguma forma acabou criando um c\u00f3digo similar a este:<\/p>\n<pre class=\"lang:js decode:true \">var result = \"\";\n  for (var i = 0; i &lt; 100000; i++) {\n      var user = \"user: \" + i + \"\\n\";\n      result += user;\n  }\n  console.log(result);<\/pre>\n<p>Sem d\u00favidas, a primeira solu\u00e7\u00e3o que vem em mente \u00e9 a de utilizar o operador <code>+=<\/code> para concatenar dados para uma string principal, isso \u00e9 muito comum e largamente utilizado. Por\u00e9m o problema surge somente quando voc\u00ea precisar concatenar muitos dados (principalmente quando s\u00e3o dados grandes!).<\/p>\n<p>Neste caso o recomendado \u00e9 trabalhar com arrays. Primeiro voc\u00ea cria o array (<code>var result = [];<\/code>), a cada itera\u00e7\u00e3o voc\u00ea vai adicionando os dados usando<code>result.push(valor)<\/code>, para que no final do loop a gera\u00e7\u00e3o da string concatenada seja realizada via fun\u00e7\u00e3o <code>result.join(\"\")<\/code>, veja abaixo:<\/p>\n<pre class=\"lang:js decode:true\">var result = [];\n  for (var i = 0; i &lt; 100000; i++) {\n      var user = \"User: \" + i + \"\\n\";\n      result.push(user);\n  }\n  console.log(result.join(\"\"));<\/pre>\n<h3>2) Convertendo para boolean usando &#8220;!!&#8221;<\/h3>\n<p>Muitas vezes precisamos checar a exist\u00eancia de uma vari\u00e1vel, ou seja, se ela possui um valor v\u00e1lido que seja considerado como <strong>&#8220;valor verdadeiro&#8221;<\/strong>, para isso, utilizar <code>if (variavel)<\/code> automaticamente vai retornar falso se a variavel conter qualquer um desses valores: <code>false, 0, null, \"\", [], {}, undefined ou NaN<\/code>, e \u00e9 claro que diferente desses valores citados a condicional vai retornar verdadeiro.<br \/>\nPor\u00e9m as vezes, voc\u00ea pode precisar converter uma var\u00edavel para boolean e ae neste caso o jeito eficiente \u00e9 usar o operador <code>!!<\/code>, por exemplo:<\/p>\n<pre class=\"lang:js decode:true \">function User(name) {\n    this.name = name;\n    this.hasName = !!name;\n  }\n  var user = new User(\"Caio\");\n  console.log(user.name); \/\/ Caio\n  console.log(user.hasName); \/\/ true<\/pre>\n<p>Neste caso qualquer tipo de valor v\u00e1lido que voc\u00ea inserir em <code>new User(\"Joao\")<\/code> o seu atributo <code>this.hasName<\/code> ser\u00e1 verdadeiro.<\/p>\n<h3>3) Convertendo para numbers usando o operador &#8220;+&#8221;<\/h3>\n<p>Essa magia \u00e9 muito, mas muito foda! E tamb\u00e9m simples de se fazer. Quando uma string cont\u00e9m apenas n\u00fameros ela pode ser convertida para number utilizando apenas o operador <code>+<\/code>, caso contr\u00e1rio ser\u00e1 retornado um <code>NaN<\/code> <strong>(Not a Number)<\/strong>. Veja esse exemplo:<\/p>\n<pre class=\"lang:js decode:true\">function toNumber(strNumber) {\n    return +strNumber;\n  }\n  console.log(toNumber(\"1234\")); \/\/ 1234<\/pre>\n<h3>4) Capturando milisegundos de uma data usando denovo o &#8220;+&#8221;<\/h3>\n<p>Assim como o operador <code>+<\/code> converte uma string para number, ele tamb\u00e9m converte um objeto Date para um number que consequentemente seu retorno ser\u00e1 os milisegundos de uma data:<\/p>\n<pre class=\"lang:js decode:true\">console.log(+new Date()) \/\/ 1410480611962<\/pre>\n<h3>5) Condicionais usando short-circuits<\/h3>\n<p>Se voc\u00ea tem um c\u00f3digo semelhante a esse:<\/p>\n<pre class=\"lang:js decode:true\">if (conected) {\n    login();\n  }<\/pre>\n<p>Voc\u00ea pode encurt\u00e1-lo usando apenas a combina\u00e7\u00e3o de uma vari\u00e1vel com uma fun\u00e7\u00e3o atrav\u00e9s do operador l\u00f3gico <code>&amp;&amp;<\/code>. Resumindo, o c\u00f3digo anterior pode ficar em uma \u00fanica linha, da seguinte forma:<\/p>\n<pre class=\"lang:js decode:true\">conected &amp;&amp; login();<\/pre>\n<p>O mesmo pode ser feito quando se precisa checar seu um objeto existe, para em seguida executar seu respectivo m\u00e9todo:<\/p>\n<pre class=\"lang:js decode:true\">user &amp;&amp; user.login();<\/pre>\n<h3>6) Use o operador &#8220;||&#8221; para criar default values<\/h3>\n<p>Quando se tem um objeto que precisa de valores default quando nenhum par\u00e2metro \u00e9 passado para ele, voc\u00ea pode usar o operador l\u00f3gico <code>||<\/code> para checar se ser\u00e1 usado os par\u00e2metros v\u00e1lidos do construtor ou se ser\u00e1 usado um valor default, por exemplo:<\/p>\n<pre class=\"lang:js decode:true\">function User(name, age) {\n    this.name = name || \"No name\";\n    this.age = age || 18;\n  }\n  var user1 = new User();\n  console.log(user1.name); \/\/ No name\n  console.log(user1.age); \/\/ 18\n\n  var user2 = new User(\"Caio\", 25);\n  console.log(user2.name); \/\/ Caio\n  console.log(user2.age); \/\/ 25<\/pre>\n<h3>7) Cacheando array.length em um loop<\/h3>\n<p>Essa dica \u00e9 muito simples e tem um impacto imenso quando se trabalha com arrays gigantes. Basicamente todo mundo itera um array da seguinte maneira:<\/p>\n<pre class=\"lang:js decode:true\">for(var i = 0; i &lt; array.length; i++) {\n    console.log(array[i]);\n  }<\/pre>\n<p>Por\u00e9m o grande erro do c\u00f3digo anterior \u00e9 que a cada itera\u00e7\u00e3o do loop o <code>array.length<\/code> \u00e9 contabilizado, em arrays gigantes isso pode causar uma lentid\u00e3o e a solu\u00e7\u00e3o \u00e9 simples, basta armazenar o <code>array.length<\/code> em uma vari\u00e1vel para us\u00e1-la no loop:<\/p>\n<pre class=\"lang:js decode:true\">var length = array.length;\n  for(var i = 0; i &lt; length; i++) {\n    console.log(array[i]);\n  }<\/pre>\n<p>Ou caso queria deixar esse loop mais enxuto, fa\u00e7a isso:<\/p>\n<pre class=\"lang:js decode:true\">for(var i = 0, length = array.length; i &lt; length; i++) {\n    console.log(array[i]);\n  }<\/pre>\n<h3>8) Detectando propriedades em um objeto<\/h3>\n<p>Sabe quando voc\u00ea precisa executar um m\u00e9todo de um objeto, pelo qual voc\u00ea n\u00e3o sabe se o objeto existe? Um exemplo cl\u00e1ssico s\u00e3o as distintas APIs do HTML que cada browser possui ou n\u00e3o possui, por exemplo, o Internet Explorer n\u00e3o possui as fun\u00e7\u00f5es <code>document.querySelector<\/code> e <code>document.querySelectorAll<\/code>. Se voc\u00ea pretende criar uma biblioteca JavaScript cross-browser voc\u00ea ter\u00e1 que <strong>previnir null pointers<\/strong> checando se tal objeto possui um determinado m\u00e9todo ou atributo. Neste caso voc\u00ea pode usar o operador <code>in<\/code> comparando se uma string (referente ao nome do atributo ou m\u00e9todo) existe em um objeto. Para detectar se o browser possui a fun\u00e7\u00e3o <code>document.querySelector<\/code> voc\u00ea pode fazer o seguinte c\u00f3digo:<\/p>\n<pre class=\"lang:js decode:true \">if ('querySelector' in document) {\n    document.querySelector(\"#id\");\n  } else {\n    document.getElementById(\"id\");\n  }<\/pre>\n<h3>9) Pegando o \u00faltimo elemento do array<\/h3>\n<p>A fun\u00e7\u00e3o <code>Array.prototype.slice(begin, end)<\/code> tem o poder de cortar um array ou string com base nos par\u00e2metros <code>begin<\/code> e <code>end<\/code>. Se voc\u00ea n\u00e3o informar o par\u00e2metro <code>end<\/code>automaticamente ser\u00e1 considerado o valor m\u00e1ximo do array, outro detalhe legal \u00e9 que essa fun\u00e7\u00e3o tamb\u00e9m pode ser usada em strings, pelo qual tem o mesmo comportamento das fun\u00e7\u00f5es <code>String.prototype.substr()<\/code> e <code>String.prototype.substring()<\/code>.<br \/>\nO que pouca gente sabe \u00e9 que ao usar um valor negativo na fun\u00e7\u00e3o slice, voc\u00ea consegue pegar exatamente o \u00faltimo elemento ou os \u00faltimos elementos de um array, por exemplo:<\/p>\n<pre class=\"lang:js decode:true\">var arr = [1,2,3,4,5,6];\n  console.log(arr.slice(-1)); \/\/ [6]\n  console.log(arr.slice(-2)); \/\/ [5,6]\n  console.log(arr.slice(-3)); \/\/ [4,5,6]<\/pre>\n<h3>10) Array trucation<\/h3>\n<p>Array trucation \u00e9 a t\u00e9cnica de travar o tamanho de um array, for\u00e7ando que o mesmo tenha um n\u00famero restrito de elementos e caso o array tenha mais elementos do que o valor que pretende truncar, os elementos que sobrarem s\u00e3o exclu\u00eddos. Na pr\u00e1tica basta voc\u00ea definir um valor para o atributo <code>array.length<\/code> e pronto!<\/p>\n<pre class=\"lang:js decode:true\">var arr = [1,2,3,4,5,6];\n  console.log(arr.length); \/\/ 6\n  arr.length = 3;\n  console.log(arr.length); \/\/ 3<\/pre>\n<h3>11) Replace all<\/h3>\n<p>A fun\u00e7\u00e3o <code>string.replace()<\/code> \u00e9 muito \u00fatil quando se precisa substituir determinados trechos de uma string, o que torna ela muito foda \u00e9 que ela permite utilizar<strong>express\u00e3o regular<\/strong> para fazer um <strong>match<\/strong> de caracteres. E gra\u00e7as a isso, \u00e9 poss\u00edvel fazer com que essa fun\u00e7\u00e3o substitua numa \u00fanica execu\u00e7\u00e3o v\u00e1rias ocorr\u00eancias repetidas, para isso basta utilizar o <code>\/g<\/code> no final do match que pretende buscar:<\/p>\n<pre class=\"lang:js decode:true\">var string = \"jo\u00e3o jo\u00e3o\";\n  console.log(string.replace(\/\u00e3o\/, \"ana\")); \/\/ \"joana jo\u00e3o\"\n  console.log(string.replace(\/\u00e3o\/g, \"ana\")); \/\/ \"joana joana\"<\/pre>\n<h3>12) Combinando arrays<\/h3>\n<p>A t\u00e9cnica de combinar arrays pode ser feita utilizando a fun\u00e7\u00e3o:<\/p>\n<pre class=\"lang:js decode:true\">var array1 = [1,2,3];\n  var array2 = [4,5,6];\n  console.log(array1.concat(array2)); \/\/ [1,2,3,4,5,6];<\/pre>\n<p>O \u00fanico problema dessa fun\u00e7\u00e3o, \u00e9 que ela \u00e9 recomendada apenas quando se pretende combinar pequenos arrays, afinal essa fun\u00e7\u00e3o aumenta o uso de mem\u00f3ria dos arrays at\u00e9 que o array final seja gerado e isso pode causar lentid\u00e3o quando se pretende combinar dois ou <strong>mais arrays de 50000 elementos cada<\/strong>.<br \/>\nSe esse for o seu caso, utilize a fun\u00e7\u00e3o: <code>array.push.apply()<\/code> que \u00e9 otimizada para trabalhar com arrays gigantes:<\/p>\n<pre class=\"lang:js decode:true\">var array1 = [1,2,3];\n  var array2 = [4,5,6];\n  console.log(array1.push.apply(array1, array2)); \/\/ [1,2,3,4,5,6];<\/pre>\n<h3>13) Transformando NodeList em arrays<\/h3>\n<p>Se voc\u00ea executar <code>document.querySelectorAll(\"p\")<\/code> com certeza ser\u00e1 retornado um array de elementos do HTML, mais conhecidos como <code>NodeList<\/code>.<br \/>\nPor\u00e9m um <code>NodeList<\/code> n\u00e3o possui todas fun\u00e7\u00f5es de um array e caso voc\u00ea precise usar fun\u00e7\u00f5es do tipo: <code>sort(), reduce(), map(), filter()<\/code>, voc\u00ea ter\u00e1 que converter um<code>NodeList<\/code> em um array. Para fazer essa convers\u00e3o basta executar a fun\u00e7\u00e3o <code>[].slice.call(arguments)<\/code>, por exemplo:<\/p>\n<pre class=\"lang:js decode:true\">var elements = document.querySelectorAll(\"p\"); \/\/ NodeList\n  var arrayElements = [].slice.call(elements); \/\/ Array de Nodes<\/pre>\n<h3>14) Embaralhando elementos do array<\/h3>\n<p>Se voc\u00ea precisa embaralhar a ordem dos elementos de um array, fa\u00e7a a seguinte magia:<\/p>\n<pre class=\"lang:js decode:true\">var list = [1,2,3];\n  console.log(list.sort(function() Math.random() - 0.5)); \/\/ [2,1,3]<\/pre>\n<h3>15) Calculando idade<\/h3>\n<p>Se voc\u00ea um dia precisar criar uma fun\u00e7\u00e3o que calcule a idade com base em uma data de nascimento, recomendo que utilize essa fun\u00e7\u00e3o que faz uma magia extremamente perform\u00e1tica:<\/p>\n<pre class=\"lang:js decode:true\">function calcAge(dateString) {\n    var birthday = +new Date(dateString);\n    return ~~((Date.now() - birthday) \/ (31557600000));\n  }<\/pre>\n<p>Essa fun\u00e7\u00e3o eu achei no link: <a href=\"http:\/\/jsperf.com\/birthday-calculation\" target=\"_blank\">http:\/\/jsperf.com\/birthday-calculation<\/a> e desde ent\u00e3o passei a us\u00e1-la como refer\u00eancia, pois obteve uma alta performance em um c\u00f3digo minimalista.<\/p>\n<h3>16)\u00a0Passando n\u00famero para Inteiro<\/h3>\n<p>Normalmente utilizamos parsetInt para transformar em inteiro, mas existe uma forma mais f\u00e1cil, utilizando o operador ~.<\/p>\n<p>Da forma parseInt ficaria desta forma:<\/p>\n<pre class=\"lang:js decode:true \">console.log(parseInt(\"10\")) ;        \/\/ 10\nconsole.log(parseInt(\"10.00\")) ;     \/\/ 10\nconsole.log(parseInt(\"10.33\")) ;     \/\/ 10\nconsole.log(parseInt(\"34 45 66\")) ;  \/\/ 34\nconsole.log(parseInt(\" 60 \")) ;      \/\/ 60\nconsole.log(parseInt(\"40 years\")) ;  \/\/ 40\nconsole.log(parseInt(\"He was 40\")) ; \/\/ NaN\n\nconsole.log(parseInt(\"10\",10)); \/\/ 10\nconsole.log(parseInt(\"010\"));   \/\/ 10\nconsole.log(parseInt(\"10\",8));  \/\/ 8\nconsole.log(parseInt(\"0x10\"));  \/\/ 16\nconsole.log(parseInt(\"10\",16)); \/\/ 16<\/pre>\n<p>Da forma contra\u00edda, ficaria:<\/p>\n<pre class=\"lang:js decode:true \">console.log(~~(\"10\")) ;       \/\/ 10\nconsole.log(~~(\"10.00\")) ;     \/\/ 10\nconsole.log(~~(\"10.33\")) ;     \/\/ 10\nconsole.log(~~(\"34 45 66\")) ;  \/\/ 0\nconsole.log(~~(\" 60 \")) ;      \/\/ 60\nconsole.log(~~(\"40 years\"));   \/\/ 0\nconsole.log(~~(\"He was 40\")) ; \/\/ 0\n\nconsole.log(~~(\"10\",10)); \/\/ 10\nconsole.log(~~(\"010\"));   \/\/ 10\nconsole.log(~~(\"10\",8));  \/\/ 8\nconsole.log(~~(\"0x10\"));  \/\/ 16\nconsole.log(~~(\"10\",16)); \/\/ 16<\/pre>\n<p>Como podem ver, ele traz o numeral zero\u00a0como retorno, quando n\u00e3o consegue fazer a convers\u00e3o. As diferen\u00e7as s\u00e3o poucas, mas vale a pena utilizar. Deixamos o console.log para copiarem e colarem no console do Browser para testarem.<\/p>\n<p><strong>Refer\u00eancias:<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/code.google.com\/p\/jslibs\/wiki\/JavascriptTips\" target=\"_blank\">https:\/\/code.google.com\/p\/jslibs\/wiki\/JavascriptTips<\/a><\/li>\n<li><a href=\"http:\/\/davidwalsh.name\/combining-js-arrays\" target=\"_blank\">http:\/\/davidwalsh.name\/combining-js-arrays<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/jed\/140bytes\/wiki\/Byte-saving-techniques\" target=\"_blank\">https:\/\/github.com\/jed\/140bytes\/wiki\/Byte-saving-techniques<\/a><\/li>\n<li><a href=\"http:\/\/blog.mdnbar.com\/javascript-common-tricks\" target=\"_blank\">http:\/\/blog.mdnbar.com\/javascript-common-tricks<\/a><\/li>\n<li><a href=\"http:\/\/jsperf.com\/birthday-calculation\" target=\"_blank\">http:\/\/jsperf.com\/birthday-calculation<\/a><\/li>\n<li><a href=\"http:\/\/www.w3schools.com\/jsref\/jsref_parseint.asp\">http:\/\/www.w3schools.com\/jsref\/jsref_parseint.asp<\/a><\/li>\n<\/ul>\n<p>Via:\u00a0<a href=\"http:\/\/udgwebdev.com\/15-javascript-hacks\/\">http:\/\/udgwebdev.com\/15-javascript-hacks\/<\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Programar em Javascript de forma eficaz, utilizando t\u00e9cnicas pouco divulgadas, seu c\u00f3digo ficar\u00e1 escrito como um Ninja. Veja as 16 dicas e surpreenda-se com o resultado.<\/p>\n","protected":false},"author":1,"featured_media":3541,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,6,15,28],"tags":[31,180,369,447,508],"class_list":["post-3533","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvimento","category-dicas","category-javascript","category-tutoriais","tag-16-tecnicas-javascript","tag-destaque","tag-js-ninja","tag-ninja-javascript","tag-programar-em-javascript"],"_links":{"self":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts\/3533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/comments?post=3533"}],"version-history":[{"count":0,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts\/3533\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/media\/3541"}],"wp:attachment":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/media?parent=3533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/categories?post=3533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/tags?post=3533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}