Tableless

Busca Menu

Property accessors e porque você deveria saber usá-los

Seja o primeiro a comentar por

Este é um artigo que se propõe a explicar uma forma mais eficaz de utilizar Objetos em JavaScript.

Muitos talvez conheçam este conteúdo, outros tantos nunca ouviram falar, justamente por aprenderem jQuery antes de aprender JavaScript. Mas enfim, esperamos que todos possam tirar algum proveito desta matéria.

Lidando com objetos em JavaScript

Um objeto em JavaScript nada mais é do que um array associativo onde cada “associação” é uma propriedade do objeto. Isso dito, todo sabemos que para acessar um array, precisamos fornecer um índice. É nesse momento que entram os property accessors.

Existem duas notações para acessar o índice desejado em um objeto JavaScript:

var meuObj = {indice1: 'foo', indice2: 'bar'};
//Bracket Notation
meuObj['indice1']; //retorna foo
//Dot Notation
meuObj.indice2;    //retorna bar

A notação que acabou se tornando o mais popular é a Dot Notation porque também ela é usada para encadeamento de métodos, por exemplo:

$('.myEl').addClass('sticky').stop().fadeIn();

Essa notação é muito poderosa e certamente deve ser adotada como padrão, mas há limitações e casos onde o mais aconselhado é utilizar Bracket Notation. Vamos a alguns exemplos:

Acessando múltiplas propriedades:

Se você utiliza modularização de JavaScript, já deve ter deparado com o seguinte cenário:

var PROD = {};
PROD.clients = {
  init: function(){},
  method1: function(){}
};
PROD.pages = {
  init: function(){},
  method1: function(){}
};
PROD.accounts = {
  init: function(){},
  method1: function(){}
};

//roda tudo
PROD.clients.init();
PROD.pages.init();
PROD.accounts.init();

Ok, tudo certo, mas suponhamos que, ao invés de apenas clients, pages e accounts, como no exemplo acima, eu tenha 15 módulos para iniciar.

//roda tudo
PROD.clients.init();
PROD.pages.init();
PROD.accounts.init();
PROD.wow.init();
PROD.such.init();
PROD.code.init();
PROD.much.init();
PROD.lines.init();
PROD.wowwow.init();
PROD.ta.init();
PROD.ficando.init();
PROD.chato.init();
PROD.isso.init();
PROD.aqui.init();
PROD.chega.init();

Mas isso é horrível! E se eu quiser rodar métodos de forma dinâmica? Quem poderá nos ajudar? Aí que entra a beleza do Bracket Notation. Vamos ver duas formas de fazer isso:

//roda tudo
var keys = Object.keys(PROD);
var len  = keys.length;
for(var i = 0; i < len; i++){
  PROD[keys[i]].init();
}

O código acima utiliza o método nativo keys() do objeto JavaScript. Esse método retorna um array com todos os índices do nosso objeto. Baseado nisso, fazemos um for para executar o método init() que definimos para cada um dos módulos.

Outra forma de fazer isso é utilizando o for…in. Vejamos:

//roda tudo
for(var key in PROD){
  PROD[key].init();
}

Muito melhor, não? Outra possibilidade é você executar apenas os módulos que deseja. Suponhamos que você queira carregar módulos por página, basta fazer:

//roda tudo
var home = ['clients', 'pages', 'wow', 'chato'];
for(var key in home){
  PROD[home[key]].init();
}

Quando o laço for…in é executado em um array, ele retorna como key sempre o índice numérico, logo, nosso código está rodando o método init de cada módulo que tem o nome naquele array. Isso é muito legal.

Executando métodos de forma dinâmica:

Quando entendemos o conceito, muitas possibilidades se abrem. Vamos a outro exemplo prático: um sticky menu. Esses dias me deparei com o seguinte código:

if($(window).scrollTop() > 300){
  $("#header").addClass('sticky');
}else{
  $("#header").removeClass('sticky');
}

O que está errado? Nada. Mas poderíamos fazer isso de forma mais simples com bracket notation utilizando um ternário:

var action = ($(window).scrollTop() > 300) ? 'addClass' : 'removeClass';
$('#header')[action]('sticky');

Isso é possível porque um objeto jQuery tem as suas propriedades como qualquer outro objeto, logo, nós podemos acessá-las da forma como bem entendermos.

Enfim, estes são apenas exemplos simples da liberdade que temos quando compreendemos de fato como funcionam os property accessors. Este simples conceito pode mudar a forma como desenvolvemos e nos fornecer uma liberdade incrível.

E quanto a performance? Nunca tema usar a Bracket Notation: ela é mais performática. Veja em http://jsperf.com/filipe-property-accessors.

Comparação de performance usando brackets notation

Publicado no dia