{"id":504,"date":"2021-07-23T21:05:08","date_gmt":"2021-07-23T21:05:08","guid":{"rendered":"https:\/\/escolhadev.com.br\/?p=504"},"modified":"2024-04-30T20:22:14","modified_gmt":"2024-04-30T20:22:14","slug":"como-utilizar-underscore-binding-no-backbone-js","status":"publish","type":"post","link":"https:\/\/escolhadev.com.br\/javascript\/como-utilizar-underscore-binding-no-backbone-js\/","title":{"rendered":"Como utilizar Underscore Binding no Backbone.js"},"content":{"rendered":"\n<p>Uma pr\u00e1tica muito comum no desenvolvimento de componentes usando Backbone.js \u00e9 o uso de uma fun\u00e7\u00e3o chamada&nbsp;<code>_.bindAll<\/code>. Esta fun\u00e7\u00e3o faz parte da biblioteca Underscore.js que \u00e9 uma depend\u00eancia obrigat\u00f3ria do Backbone.js assim como o jQuery tamb\u00e9m \u00e9.<\/p>\n\n\n\n<p>Quero inicialmente demonstrar com exemplos as dificuldades que existem de se utilizar a palavra reservada&nbsp;<code>this<\/code>&nbsp;em um componente JavaScript. Em seguida mostrarei solu\u00e7\u00f5es e gradativamente iremos evoluindo at\u00e9 voc\u00ea chegar em um cen\u00e1rio onde usamos o&nbsp;<code>this<\/code>&nbsp;e&nbsp;<code>_.bindAll<\/code>&nbsp;em um componente Backbone.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"o-uso-do-this-e-seus-problemas\">O uso do this e seus problemas<\/h2>\n\n\n\n<p>Na maioria das linguagens que suportam orienta\u00e7\u00e3o a objetos \u00e9 comum o uso do\u00a0<code>this<\/code>\u00a0para referenciar o pr\u00f3prio objeto. No caso do JavaScript tamb\u00e9m \u00e9 poss\u00edvel usar o\u00a0<code>this<\/code>, no entanto \u00e9 necess\u00e1rio um cuidado extra por que seu comportamento \u00e9 diferente se comparado com as demais linguagens. Para ficar mais simples prefiro demonstrar no c\u00f3digo os desafios de se utilizar o\u00a0<code>this<\/code>\u00a0em um projeto JavaScript.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(function () {\n\tconst hello = {\n\t\tgoodMorning: function () {\n\t\t\tconsole.log('Sample #1: Hello, good morning!');\n\t\t\tconsole.log(this); <em>\/\/ Window<\/em>\n\t\t},\n\t};\n\n\tsetTimeout(hello.goodMorning);\n})();\n<\/code><\/pre>\n\n\n\n<p>Se voc\u00ea executar o c\u00f3digo acima no seu navegador vai constatar que o&nbsp;<code>this<\/code>&nbsp;\u00e9 o objeto Window e n\u00e3o o objeto hello como voc\u00ea estava esperando. Agora quero demonstrar um segundo exemplo onde vamos escrever nosso c\u00f3digo de uma forma que seja poss\u00edvel imprimir o&nbsp;<code>this<\/code>&nbsp;corretamente, ou seja, deve imprimir algo pr\u00f3ximo \u00e0&nbsp;<code>Object { goodMorningWrapper }<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(function () {\n\tconst hello = {\n\t\tgoodMorningWrapper: function () {\n\t\t\tconst self = this;\n\n\t\t\tconst goodMorning = function () {\n\t\t\t\tconsole.log('Sample #2: Hello, good morning!');\n\t\t\t\tconsole.log(this); <em>\/\/ Object { goodMorningWrapper: ... }<\/em>\n\t\t\t};\n\n\t\t\treturn function () {\n\t\t\t\tgoodMorning.apply(self);\n\t\t\t};\n\t\t},\n\t};\n\n\tsetTimeout(hello.goodMorningWrapper());\n})();\n<\/code><\/pre>\n\n\n\n<p>Se voc\u00ea executar esta nova vers\u00e3o do objeto hello vai verificar que desta vez o&nbsp;<code>this<\/code>&nbsp;est\u00e1 apontando corretamente para o pr\u00f3prio objeto ao inv\u00e9s de apontar para o objeto Window. Sucesso!<\/p>\n\n\n\n<p>S\u00f3 me deixe fazer uma pergunta. Voc\u00ea gostou deste c\u00f3digo? \u00c9 f\u00e1cil de entender? Eu n\u00e3o gostei!<\/p>\n\n\n\n<p>Antes de falarmos sobre como o underscores pode ser \u00fatil para resolver este problema quero mostrar um terceiro exemplo. Nem sempre trabalho em projetos que utilizam alguma biblioteca como Underscores e Backbone. Nestes casos pode acontecer de eu precisar escrever c\u00f3digo JavaScript puro e usando objetos. Para meus objetos n\u00e3o ficarem complexos como no exemplo anterior procuro criar objetos seguindo uma organiza\u00e7\u00e3o parecida com a deste pr\u00f3ximo exemplo.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(function () {\n\tconst Hello = function () {\n\t\tconst self = this;\n\n\t\tself.goodMorning = function () {\n\t\t\tconsole.log('Sample #3: Hello, good morning!');\n\t\t\tconsole.log(self); <em>\/\/ Object { goodMorning: ... }<\/em>\n\t\t};\n\t};\n\n\tconst hello = new Hello();\n\n\tsetTimeout(hello.goodMorning);\n})();\n<\/code><\/pre>\n\n\n\n<p>Nada muito complicado. No momento da cria\u00e7\u00e3o do objeto a primeira a\u00e7\u00e3o \u00e9 criar uma propriedade chamada&nbsp;<code>self<\/code>&nbsp;para armazenar o valor do&nbsp;<code>this<\/code>. Da\u00ed em diante eu esque\u00e7o que o&nbsp;<code>this<\/code>&nbsp;existe para preferir usar sempre o&nbsp;<code>self<\/code>&nbsp;quando preciso referenciar o pr\u00f3prio objeto. At\u00e9 hoje essa solu\u00e7\u00e3o tem funcionado pra mim.<\/p>\n\n\n\n<p>Agora que voc\u00ea entendeu as dificuldades de se trabalhar com o&nbsp;<code>this<\/code>&nbsp;nos nossos objetos em JavaScript bora dar um pr\u00f3ximo passo. A biblioteca underscore possui algumas fun\u00e7\u00f5es \u00fateis que nos dar\u00e3o mais op\u00e7\u00f5es de usar o&nbsp;<code>this<\/code>&nbsp;de uma forma facil e agrad\u00e1vel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"function-bind\">Function _.bind()<\/h2>\n\n\n\n<p>O Underscore.js \u00e9 uma das depend\u00eancias obrigat\u00f3rias para se utilizar Backbone. \u00c9 exatamente esta a biblioteca que vamos explorar para encontrar uma solu\u00e7\u00e3o para tornar mais simples o uso do&nbsp;<code>this<\/code>&nbsp;em nossos objetos JavaScript.<\/p>\n\n\n\n<p>A primeira fun\u00e7\u00e3o \u00fatil que vou apresentar \u00e9 o&nbsp;<code>_.bind()<\/code>. Basicamente voc\u00ea deve passar primeiro como par\u00e2metro uma fun\u00e7\u00e3o e no segundo par\u00e2metro um objeto que dever\u00e1 atuar como sendo o&nbsp;<code>this<\/code>&nbsp;da fun\u00e7ao. O retorno \u00e9 uma fun\u00e7\u00e3o que caso seja executada vai preservar corretamente o&nbsp;<code>this<\/code>&nbsp;e evitar hacks como aqueles que criamos anteriormente.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(function () {\n\tconst Hello = function () {\n\t\tthis.goodMorning = function () {\n\t\t\tconsole.log('Sample #4: Hello, good morning!');\n\t\t\tconsole.log(this); <em>\/\/ Object { goodMorning: ... }<\/em>\n\t\t};\n\t};\n\n\tconst hello = new Hello();\n\n\thello.goodMorning = _.bind(hello.goodMorning, hello);\n\n\tsetTimeout(hello.goodMorning);\n})();\n<\/code><\/pre>\n\n\n\n<p>Com o uso do&nbsp;<code>_.bind<\/code>&nbsp;a classe&nbsp;<code>Hello<\/code>&nbsp;ficou menor e n\u00e3o precisamos criar nenhum hack. S\u00f3 n\u00e3o podemos esquecer que ap\u00f3s criar o objeto ser\u00e1 necess\u00e1rio chamar a fun\u00e7\u00e3o&nbsp;<code>_.bind<\/code>&nbsp;para cada m\u00e9todo existente em nossa classe. Mas ainda tem como melhorar &#8211; o pr\u00f3ximo passo agora \u00e9 entendermos um pouco sobre a fun\u00e7\u00e3o&nbsp;<code>_.bindAll<\/code>&nbsp;na pr\u00f3xima se\u00e7\u00e3o.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"function-bindall\">Function _.bindAll()<\/h2>\n\n\n\n<p>O uso do&nbsp;<code>_.bindAll<\/code>&nbsp;\u00e9 na minha opini\u00e3o a alternativa que parece mais interessante de se utilizar junto com o Backbone. A fun\u00e7\u00e3o recebe por par\u00e2metro um objeto e em seguida os pr\u00f3ximos par\u00e2metros s\u00e3o strings contendo o nome dos m\u00e9todos onde voc\u00ea deseja aplicar o bind de forma permanente. Vamos para mais um exemplo.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(function () {\n\tconst Hello = function () {\n\t\tthis.goodMorning = function () {\n\t\t\tconsole.log('Sample #5: Hello, good morning!');\n\t\t\tconsole.log(this); <em>\/\/ Object { goodMorning: ... }<\/em>\n\t\t};\n\t};\n\n\tconst hello = new Hello();\n\n\t_.bindAll(hello, 'goodMorning');\n\n\tsetTimeout(hello.goodMorning);\n})();\n<\/code><\/pre>\n\n\n\n<p>Se por um acaso voc\u00ea adicionasse o m\u00e9todo&nbsp;<code>goodNight<\/code>&nbsp;na classe&nbsp;<code>Hello<\/code>&nbsp;bastaria editar o&nbsp;<code>_.bindAll<\/code>&nbsp;adicionando um terceiro par\u00e2metro com o nome do novo m\u00e9todo.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>_.bindAll(hello, 'goodMorning', 'goodNight');\n<\/code><\/pre>\n\n\n\n<p>Agora que voc\u00ea me acompanhou em todos estes exemplos de c\u00f3digo resolvendo o uso do&nbsp;<code>this<\/code>&nbsp;manualmente e tamb\u00e9m utilizando o Underscore.js \u00e9 hora de ver como seria uma forma comum de se resolver isso no dia a dia programando com o Backbone.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"exemplo-1-usando-bindall-no-backbonemodel\">Exemplo #1: Usando _.bindAll no Backbone.Model<\/h2>\n\n\n\n<p>Finalmente agora vou mostrar como usualmente utilizam o&nbsp;<code>this<\/code>&nbsp;e o&nbsp;<code>bind<\/code>&nbsp;em um componente criado utilizando Backbone. Abaixo vou demonstrar uma classe similar aos exemplos anteriores, no entanto desta vez a classe&nbsp;<code>Hello<\/code>&nbsp;extende&nbsp;<code>Backbone.Model<\/code>.<\/p>\n\n\n\n<p>Um ponto importante para observar \u00e9 que no Backbone.js o m\u00e9todo&nbsp;<code>initialize<\/code>&nbsp;atua como um construtor, ou seja, ser\u00e1 executado sempre que um novo objeto for criado \u00e0 partir desta classe.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(function () {\n\tconst Hello = Backbone.Model.extend({\n\t\tinitialize: function () {\n\t\t\t_.bindAll(this, 'goodMorning');\n\t\t},\n\n\t\tgoodMorning: function () {\n\t\t\tconsole.log('Backbone.Model Sample #1: Hello, good morning!');\n\t\t\tconsole.log(this); <em>\/\/ Object { goodMorning: ... }<\/em>\n\t\t},\n\t});\n\n\tconst hello = new Hello();\n\n\tsetTimeout(hello.goodMorning);\n})();\n<\/code><\/pre>\n\n\n\n<p>O m\u00e9todo&nbsp;<code>initialize<\/code>&nbsp;em nosso caso \u00e9 o local ideal para voc\u00ea chamar a fun\u00e7\u00e3o&nbsp;<code>_.bindAll<\/code>. Lembrese que a fun\u00e7\u00e3o suporta realizar o bind de muitos m\u00e9todos em uma \u00fanica chamada. No entanto evite abusar deste recurso, caso contr\u00e1rio seu objeto poder\u00e1 sentir algum impacto na performance e consumo de mem\u00f3ria.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fa%C3%A7a-download-dos-exemplos-no-github\">Fa\u00e7a download dos exemplos no GitHub<\/h2>\n\n\n\n<p>Se voc\u00ea acompanhou este artigo at\u00e9 aqui e gostaria de acessar o c\u00f3digo fonte apresentado, tenho boas not\u00edcias. Disponibilizei no GitHub um projeto para voc\u00ea acessar e testar o conte\u00fado apresentado neste artigo.<\/p>\n\n\n\n<p><strong><a href=\"https:\/\/github.com\/backbonejsdescomplicado\/bd2020-underscore-bind\">Acesse este projeto no GitHub<\/a><\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclus%C3%A3o\">Conclus\u00e3o<\/h2>\n\n\n\n<p>Procurei demonstrar neste artigo alguns cen\u00e1rios onde o&nbsp;<code>this<\/code>&nbsp;n\u00e3o funciona conforme o esperado. Aos poucos evolui os exemplos para mostrar poss\u00edveis solu\u00e7\u00f5es para fazer com que o&nbsp;<code>this<\/code>&nbsp;fosse resolvido corretamente.<\/p>\n\n\n\n<p>Descobrimos neste artigo como o Underscore.js pode ser utilizado para fazer os binds utilizando as fun\u00e7\u00f5es&nbsp;<code>_.bind<\/code>&nbsp;e&nbsp;<code>_.bindAll<\/code>.<\/p>\n\n\n\n<p>Como gosto de escrever sobre Backbone.js neste blog aproveitei para mostrar como combinar o\u00a0<code>_.bindAll<\/code>\u00a0com um objeto criado usando Backbone. Talvez este foi o ponto mais importante do artigo, pois no dia a dia de um projeto Backbone.js essa \u00e9 a solu\u00e7\u00e3o mais utilizadas pelos programadores.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Uma pr\u00e1tica muito comum no desenvolvimento de componentes usando Backbone.js \u00e9 o uso de uma fun\u00e7\u00e3o chamada&nbsp;_.bindAll. Esta fun\u00e7\u00e3o faz parte da biblioteca Underscore.js que \u00e9 uma depend\u00eancia obrigat\u00f3ria do Backbone.js assim como o jQuery tamb\u00e9m \u00e9. Quero inicialmente demonstrar com exemplos as dificuldades que existem de se utilizar a palavra reservada&nbsp;this&nbsp;em um componente JavaScript. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/posts\/504"}],"collection":[{"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/comments?post=504"}],"version-history":[{"count":1,"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/posts\/504\/revisions"}],"predecessor-version":[{"id":756,"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/posts\/504\/revisions\/756"}],"wp:attachment":[{"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/media?parent=504"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/categories?post=504"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/escolhadev.com.br\/javascript\/wp-json\/wp\/v2\/tags?post=504"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}