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!
e74b63da-c6e2-45ab-bc71-b8b9b4249008|1|2.0