Funções em Diferentes Escopos

Se você programa em JavaScript orientado a objeto (1, 2, 3), provavelmente já teve alguns problemas com funções que deveriam ser executadas em um determinado escopo. Nesse post vou explicar como executar e vincular funções ao escopo de algum objeto.

Executando

Para chamar um método no escopo de outro objeto, utilizamos o método Function.apply. O objeto Function pode ser qualquer função que será chamada no escopo que deve ser passado como primeiro parâmetro. Vamos a um exemplo:

var Class = function() {

 this.text = "Escopo da Classe";

}

Class = new Class();

var showText = function() {

 alert(this.text);

}

// Escopo Global

showText(); // undefined

// Escopo de Class

showText.apply(Class); // "Escopo da Classe"

O resultado da primeira chamada a função é obvio: não há this.text definido. Quando aplicamos a mesma função no escopo de Class, o retorno sai como esperado.

O método Function.apply também pode receber um segundo parâmetro, contendo os parãmetros que devem ser passados à função. Esse parâmetro deve ser obrigatoriamente um array, e deve ser definido na ordem em que os parâmetros precisam ser recebidos.

var Class = function() {

 this.text = "Também podemos passar parâmetros:";

}

var Class = new Class();

var showText = function(text) {

 alert(this.text + " " + text);

}

showText(); // undefined undefined

showText.apply(Class, ["Viva!"]); // "Também podemos passar parâmetros: Viva!"

Também há o método Function.call, que tem a mesma função de Function.aplly. A diferença está em como os parâmetros para a função são definidos. Em Function.apply, eles são passados como um array, e em Function.call são passados como vários argumentos, sem a necessidade de estarem dentro de algum array.

var Class = function() {

 this.text = "Também podemos passar parâmetros:";

}

var Class = new Class();

var showText = function(text) {

 alert(this.text + " " + text);

}

showText(); // undefined undefined

showText.call(Class, "Eba!"); // "Também podemos passar parâmetros: Eba!"

Vinculando

O Function.apply resolve os problemas de muita gente, mas não todos os problemas. Imagine a seguinte situação (pela qual eu também já passei), onde precisamos recuperar uma variável da classe de dentro do objeto XMLHttpRequest:

function() {

 this.msgToShow = "Completo!";

 XMLHttpRequest.onreadystatechange = show;

}

var show = function() {

 alert(this.msgToShow);

}

E agora? Precisamos executar a função show no escopo da classe, e não no escopo do XMLHttpRequest. Poderíamos usar o Function.apply, mas ele executaria a função assim que fosse chamado. A solução é vincular a função ao escopo do objeto XMLHttpRequest. A solução mais comum é o uso de closures:

function() {

 var self = this;

 this.msgToShow = "Completo!";

 XMLHttpRequest.onreadystatechange = function() {

 	show.apply(self);

 }

}

var show = function() {

 alert(this.msgToShow);

}

Nos aproveitamos da capacidade do JavaScript de compartilhar variáveis entre funções, e armazenamos o escopo correto na variável self, que utilizamos para aplicar a função.

Reutilização

Tudo funcionando dentro do esperado, mas não estamos pensando na parte mais bela da programação orientada a objetos: a reutilização. Teríamos que criar closures toda vez em que uma execução em outro escopo fosse necessária. Pra isso existe o método Function.bind, criado para vincular a função a qualquer escopo. A função é a seguinte:

Function.prototype.bind = function() {

 var self = this, args = $A(arguments), scope = args.shift();

 return function() {

 	return self.apply(scope, args.concat($A(arguments)));

 }

}

var $A = function(object) {

 var array = [];

 for(var i = 0; i < object.length; i++)

 	array[i] = object[i];

 return array;

}

Esse método cria o closure e retorna uma função que executa o que for necessário. A função $A só serve para transformar os argumentos em um array. Modificando nosso script anterior:

function() {

 this.msgToShow = "Completo!";

 XMLHttpRequest.onreadystatechange = show.bind(this);

}

var show = function() {

 alert(this.msgToShow);

}

Quem não trabalha com POO, eventos ou timeouts talvez não tenha se deparado com nenhum problema deste tipo, mas duvido que alguém desse ramo nunca tenha recebido um “undefined” sem querer…

19 de dezembro, 2007

Voltando ao Trabalho

Um mês de férias quase obrigadas, um mês longe de qualquer coisa que se conectasse com a Internet, um mês sem saber o que acontecia no mundo. Devo ter perdido muita coisa por aí.

A Mudança

Depois de mais de 12 anos morando em cidade pequena, volto a morar em Farroupilha – RS, pertinho de Caxias do Sul. Cinco anos em Vacaria foram terríveis, embora tenha sido lá que aprendi muito do que sei hoje. Mas já era hora de mudar.

Ainda não tive muito tempo de conhecer a cidade, chegamos aqui na terça, e ainda estamos montando tudo, o que vai levar mais algum tempo. Também ainda não conheço ninguém, se alguém que lê o blog mora por aqui, deixe um comentário.

Momento desabafo: embora seja muito bom morar aqui, vai ser difícil reconstruir o que tinha na cidade anterior. Deixei meu emprego, meus freelances, meus contatos, tudo. Já estou a procura de um emprego novo, já falei com algumas pessoas, mas se alguém tiver algo para sugerir eu agradeço.

O Blog

O blog está meio abandonado faz tempo, eu sei. Tentei fazer de tudo pra escrever algo, mas o tempo e criatividade em baixa não deixaram. Agora tenho um pouco mais de tempo sobrando, de férias nos estudos, desempregado, nenhum curso. O reflexo da mudança está me tomando algum tempo, e isso se extenderá até o final de janeiro, mas o blog não ficará mais abandonado.

Já tenho idéia para alguns posts, também vou lançar um tema novo (o último teve alguns problemas e teve que ser retirado) e estou extremamente feliz com os 108 assinantes do feed principal. Quanto mais fico longe, mais assinantes. Estranho…

Estou no ar novamente. Por quanto tempo ainda não sei, mas voltei. Até, agora sim, breve!

16 de dezembro, 2007

Novidades

Bem, estou aqui mais pra dizer que estou vivo mesmo. Vocês ainda não se livraram de mim… E tenho algumas novidades. A primeira delas, como dá pra notar (pra quem não lê direto nos feeds) é o tema novo, criado com a ajuda do Fabian, da Six Interfaces. Ainda não está como eu quero, tenho alguns pequenos ajustes e correções, mas está quase.

A outra novidade, não tão boa: ficarei um mês de férias aqui do blog (mais um???), e de toda minha vida on-line. Estou de mudança para Farroupilha em 15 de dezembro, e até lá estou impossibilitado de conseguir contato a qualquer cabo azul. Estou pensando em deixar alguns posts agendados, mas não é nada certo. Comentários, e-mails, feeds, tudo vai ficar de molho nesse tempo. Pretendo voltar com mais força somente no final de janeiro, mas as atividades recomeçarão logo que chegar à casa nova.

E vou ficando por aqui, e até (nem tão) breve!

10 de novembro, 2007

Meus Feeds Favoritos

Convidado pelo Rodrigo Fante (desmotivado, eu??? Não, ocupado mesmo…), cá estou eu para escrever meus feeds favoritos.

Todo mundo sabe que é chato escolher apenas alguns feeds dentre os vários que se assina. Eu poderia colocar aquela lista “quase-padrão” do pessoal que eadrão” do pessoal que está ali no blogroll, mas dessa vez vou fazer diferente, e vou colocar alguns meio fora do assunto principal do blog, mas que leio e gosto bastante.

  • Nerdson não vai à escola: um blog muito divertido, com quadrinhos relacionados ao pessoal nerd. Muito legal…
  • Efetividade.net, sobre lifehacking, produtividade e coisas do gênero. Aprendi muita coisa por lá, até estou me organizando…
  • Escrita Torta em Linha Reta, sobre blogs, monetização, e essas coisas que todo mundo devia saber. Assinado há pouco, mas já gostei!
  • MouseOver Studio, do Diego Carrion. Não foge do assunto aqui do blog, mas eu tinha que linkar ele, um blog muito bom!

E agora uma missão ainda mais ingrata, como diz o Rodrigo: escolher alguém pra continuar o negócio… Então convido o Klaus Paiva, o Tiago Floriano e, diretamente de minha lista, o Diego Carrion. Ahh, vou tentar estar “mais motivado”, certo? Até!

16 de setembro, 2007

“The Power of Schmooze Award”

Depois de muito tempo afastado da vida blogueira, aqui estou eu novamente. Peço desculpas pela ausência muito estendida, mas ela foi realmente necessária. Estou voltando, mas não prometo que consiga manter a freqüência de postagem, embora eu esteja tentando.

Há algum tempo atrás fui premiado pelo Tiago Floriano com o The Power of Schooze Award. É uma espécie de meme, onde o blog premiado indica 5 pessoas que o recomendam e participam.

Bem, então vamos ao que interessa. E os premiados são… que rufem os tambores…

E este é o pessoal premiado. Blogs muito interessantes, quem não conhece deveria visitar! Vou ficando por aqui, volto quando der tempo…

02 de setembro, 2007