Proteja seus métodos organizando seu código JavaScript

Publicado por Christian Nascimento no dia dev

Desenvolvido por Bredan Eich em meados de 1995, o JavaScript – projetado como uma linguagem de script aberto – tornou-se uma linguagem poderosa e popular. Entretanto, organizá-lo sempre foi uma missão difícil para desenvolvedores que estão iniciando na área. Este post pretende mostrar como proteger e organizar seus métodos JavaScript sem que os mesmos estejam expostos e acessíveis desnecessariamente num escopo global.

Para iniciar, vamos começar com 3 dicas que podem ajudar na hora de desenvolver e organizar seu script.

1. Familiarize-se com as boas práticas

Ninguém nasce sabendo, não é? Para ajudar, existe muito material na internet falando sobre boas práticas de desenvolvimento. Nós da Resultados Digitais temos nosso próprio styleguide. Sinta-se em casa para contribuir. :wink:

2. Estude sobre padrões de projeto (Design pattern)

Design patterns are reusable solutions to commonly occurring problems in software design. They are both exciting and a fascinating topic to explore in any programming language.

Addy Osmani, Learning JavaScript Design Patterns

O JavaScript possui alguns padrões bastante conhecidos e cada um deles tem seus prós e contras.

Alguns dos modelos atuais são:

Também é possível fazer um mixin dos módulos, ou seja, utilizar o Module Pattern com o Facade, por exemplo.

3. Leia bastante

Quem mal lê, mal ouve, mal fala, mal vê.

Monteiro Lobato

Segundo especialistas, o hábito da leitura exercita as funções cerebrais e é uma ótima solução para manter a mente saudável. Portanto, sempre reserve um horário no dia para ler. Existem bons livros e artigos disponíveis sobre design patterns. Eu separei alguns artigos e dicas de livros que valem a pena serem lidos.

Colocando a mão na massa, ou melhor, no código

Codificando em JavaScript

Aqui na Resultados Digitais utilizamos alguns padrões já citados antes. Também utilizamos o jQuery (Yes, we love it! :heart:) e Rails – fabuloso framework focado em desenvolvimento ágil.

Como era antes (sem os patterns)

As variáveis e funções eram definidas globalmente. Sendo assim, a chance deles colidirem com outros códigos na aplicação eram grandes. No exemplo abaixo temos o arquivo books.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var books = ["Eloquent JavaScript", "JavaScript: The Good Parts"];

var addBook = function(book) {
  books.push(book);
  $(".books").html(books.join("<br>"));
};

var removeBook = function(book) {
  var index = books.indexOf(book);
  books.splice(index, 1);
};

$(document).on("ready page:change", function() {
  $(".btn-add").click(function() {
    addBook($("#book-name").val());
  });
  $(".books").html(books.join("<br>"));
});

Se incluíssemos o books.js, tanto a variável books quanto os métodos addBook e removeBook estariam acessíveis num escopo global. Neste exemplo, não teríamos problemas. Entretanto, se tivessemos uma requisição Ajax que passa o nome do livro como parâmetro via post, teríamos sérios problemas. Abaixo, um exemplo do método addBook() com requisição Ajax via Post:

1
2
3
4
5
6
var addBook = function(book) {
  $.post("http://books.com.br/api/v1/book", {title: book})
    .done(function(data){
      $(".books").html(data);
    });
};

Como proteger e evitar que seu método seja exposto?

Protejendo seus métodos em JavaScript

Simples, basta utilizarmos um design pattern que possibilite proteger seus métodos e variáveis.

Vamos refatorar o exemplo acima utilizando o Module Pattern e compará-lo com o Revealing Module Pattern. Abaixo, o books.js utilizando o Module Pattern:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var BooksModule = ( function( $ ) {
  "use strict";

  var books = ["Eloquent JavaScript", "JavaScript: The Good Parts"];

  var _book = { //Private Methods
    add: function(book){
      books.push(book);
      this.get();
    },
    remove: function(book){
      var index = books.indexOf(book);
      books.splice(index, 1);
    },
    get: function(){
      $(".books").html(books.join("<br>"));
    }
  };


  function BooksModule() {

    this.init = function init() {
      $(".btn-add").click(function(){
        _book.add($("#book-name").val());
      });
      _book.get();
    };

    this.myOtherMethod = function myOtherMethod() {
      console.log( 'my other method' );
    };

  }

  return BooksModule;

})(jQuery);
var Books = new BooksModule();
Books.init();
Books.myOtherMethod();

Neste exemplo, utilizei um objeto chamado de _book para guardar os métodos que quero que sejam privados, isto é apenas uma convenção, você pode definir seus métodos privados como você, ou sua equipe desejar. Desta forma, os métodos init() e myOtherMethod() estarão disponíveis globalmente. Abaixo, o books.js utilizando o Revealing Module Pattern:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var BooksModule = (function($) {
  "use strict";

  var books = ["Eloquent JavaScript", "Learning JavaScript Design Patterns"],
      // Public methods
      init = function() {
        _book.get();

        $(".btn-add").click(function() {
          _book.add($("#book-name").val());
        });
      },
      myOtherMethod = function() {
        console.log( 'my other method' );
      },
      // Private Methods
      _book = {
        add: function(book) {
          books.push(book);
          this.get();
        },
        remove: function(book) {
          var index = books.indexOf(book);
          books.splice(index, 1);
        },
        get: function() {
          $(".books").html(books.join("<br>"));
        }
      };
  return {
    init: init
  };
})(jQuery);

$(window).load(BooksModule.init);

Este pattern adota o mesmo conceito que o Module Pattern. A diferença entre eles é que consigo retornar apenas as variáveis ou métodos que quero e protegê-los de serem acessíveis globalmente.

Conclusão

Uma das melhores coisas a se considerar sobre design patterns é que alguém, no passado, já os aplicou e testou com sucesso. Existem vários códigos open source que implementam vários padrões em JavaScript. Como desenvolvedores, precisamos estar atentos à sua existência e quando aplicá-los. Além disso, usar métodos de minificação e de obfuscação torna nossa aplicação ainda mais segura.

Referências

Christian Nascimento

Christian Nascimento

Front End Developer

Comentários