Trabalhando com Escopo em JavaScript–Palavra chave ‘With’    

Olá pessoal!

Voltando a falar novamente de JavaScript, vou fazer um rápido post sobre uma palavra chave que dificilmente se vê por ai, a palavra with.

Todos nós já sabemos que o JavaScript tem uma forma um pouco diferente de trabalhar com escopos, e que chaves não têm o mesmo comportamento que têm em C#, por exemplo, não definindo escopo de forma alguma.

Veja o código abaixo:

   1: for (var i=0; i<3; ++i)
   2: {
   3:        var num = i;
   4:        setTimeout(function() { alert(num); }, 10);
   5: }
   6: alert(num);

Em C#, por exemplo, o num da linha 6, daria erro, por não estar definido, porém, o valor dele em JavaScript estará válido. No final da execução do código acima, o resultado será quatro alertas com o mesmo valor: 2. Isso porque no JavaScript, por padrão, uma variável tem contexto global, e os valores estão naturalmente definidos com a ordem de execução, e não com o momento ou local que elas aparecem no código.

Se eu fizer uma pequena alteração no código, atribuindo um valor fora do FOR, mesmo a variável dentro do método anônimo, dentro do setTimeout, que por sua vez está dentro do FOR será afetada:

   1: for (var i=0; i<3; ++i)
   2: {
   3:        var num = i;
   4:        setTimeout(function() { alert(num); }, 10);
   5: }
   6: var num = 9;
   7: alert(num);

Agora os quatro alertas que aparecem serão 9.

Dentro de funções, porém, isso não acontece. Por exemplo, o seguinte código daria um erro ao invocar o método metodoB, pois no contexto dele o metodoB não tem a variável num definida:

   1: function metodoA(){
   2:     var num = 2;
   3: }
   4:  
   5: function metodoB(){
   6:     alert(num);
   7: }
   8:  
   9: metodoA();
  10: metodoB();

Utilizando a palavra-chave With para definir escopo

Bacana, agora que já passamos por uma brevíssima introdução a escopo no JavaScript, vamos ver como utilizar a palavra chave With. Talvez você nunca tenha vista essa palavra chave, mas em alguns casos ela pode ser muito útil.

O que o With faz é definir que tudo que for criado dentro do seu bloco, terá um escopo novo, mesmo que seja dentro de um loop, por exemplo, se utilizarmos o primeiro código com um block with, ele ficaria assim:

   1: for (var i=0; i<3; ++i)
   2: {
   3:     with({num : i}){  
   4:        setTimeout(function() { alert(num); }, 10);
   5:    }
   6: }
   7: var num = 10;
   8: alert(num);

Agora os alertas seriam um diferente do outro, seria primeiro um 10, e depois um 0, 1 e 2. Dentro do próprio bloco poderíamos criar mais variáveis que elas não compartilhariam escopo.

Uma outra forma de utilizar o with é dizendo qual é o escopo dentro dele, como fazemos com o with da linguagem VB, por exemplo:

   1: var Pessoa = function(){
   2:     
   3:     this.Nome = "Frederico";
   4:     this.Idade = 25;
   5:  
   6:     this.Escrever = function(){
   7:  
   8:         with(this){
   9:             alert(Nome + " - " + Idade);
  10:         }
  11:     }
  12: }
  13:  
  14: var p = new Pessoa();
  15: p.Escrever();

Veja que legal: dentro do bloco with, estou definindo que o escopo da variável é o this, então não preciso utilizar this.Nome e this.Idade para acessar as variáveis da minha classe!

Agora imagina o quanto de código isso vai poupar quando você for fazer grandes interfaces com JavaScript, utilizando muito JQuery, Knockout, etc. Lembre que cada palavra no JavaScript pode mudar muito o tamanho do seu arquivo, o que faz uma bela diferença na Web.

Bom, era isso pessoal, espero que essa dica os ajude!

Abraços e até o próximo!

22. outubro 2011 09:32 by Frederico B. Emídio | Comments (0) | Permalink

Comments

Comments are closed

Sobre mim

Minha Imagem

Meu nome é Frederico Batista Emídio, trabalho com desenvolvimento de sistemas profissionalmente a oito anos, porém, já faço sites pessoais a pelo menos dez anos.

Para saber mais clique aqui.

Páginas

Calendário

<<  novembro 2017  >>
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET