Vinicius Baggio Fuentes

  1. Software Engineer — Medium
  2. Autor — Casa do Código
  3. Compre já!
04 Sep 2010 — Reaprendendo Javascript Parte 1

Reaprendendo JavaScript [parte 1]

Desde o colégio eu brinco com JavaScript, mesmo quando ela era uma linguagem meio problemática, na Grande Guerra dos Browsers, ou sei lá, a fase medieval da Web. O Iluminismo chegou, frameworks como prototype.js, jQuery e muitos outros acabaram com o fardo de fazer aplicações ricas em client-side.

JavaScript

Nessa história toda, eu nunca realmente aprendi JavaScript, apenas "fiz funcionar" (e admito isso com vergonha). Resolvi mudar.

Livros

Achei um post muito bom listando alguns livros de JavaScript para aqueles que querem levar a linguagem a sério. Comprei dois, o Object-Oriented JavaScript por Stoyan Stefanov, um pouco menos conhecido, e o famoso JavaScript: The Good Parts, de Douglas Crockford, também autor do JSLint.

Até agora, estou mais ou menos na metade do Object-Oriented JavaScript e tenho gostado bastante. Apesar de ser um livro voltado a iniciantes na programação, o conteúdo será bem aproveitado por programadores um pouco mais experientes. Descobri algumas coisas bem interessantes até agora, boas e ruins.

Exemplos JavaScript

Todos os exemplos abaixo foram executados no terminal interativo do Node.JS. Para instalá-lo no OS X, basta:

brew install node

arguments.callee

Uma das primeiras coisas que aprendi é a palavra reservada arguments. Ela retorna uma Array, que contém todos os parâmetros de uma função:

function E() {
    return arguments;
}E([1,2], "Hello world!"); // { '0': [ 1, 2 ], '1': 'Hello world!' }
E();                      // {}
E(1);                     // { '0': 1 }

Uma coisa curiosa é o arguments.callee

function F() {
    return arguments.callee;
}F(); // [Function]
F()()()()()()()()()()()(); // [Function]

O que isso significa? arguments.callee é a própria função. Pra que usar isso? Não sei. Mas veja o próximo exemplo, usando uma função anônima:

    (function(i) {
        console.log(i);
        if(i < 5) {
            arguments.callee(i+1);
        }
    })(0);
    /*
     * Saída:
     * 0
     * 1
     * 2
     * 3
     * 4
     * 5
     */

Closures e escopos léxicos

Uma das coisas mais legais de JavaScript, e Ruby também, é o uso de funções de primeira ordem (funções/métodos são dados) e closures.

Estamos acostumados com o uso de closure no dia a dia, mas eu achei um exemplo muito interessante de como observar como as closures tem seus escopos montados em tempo de definição, mas não guarda os valores das variáveis. Veja:

var a = [], i;
for(i = 0; i < 3; i++) {
    a[i] = function() {
        console.log(i);
    }
}

Espera-se, por razões lógicas, que o seguinte aconteça:

a[0]();  // Espera-se: 0, saída real: 3
a[1]();  // Espera-se: 1, saída real: 3
a[2]();  // Espera-se, 2, saída real: 3

Qual a razão disso? Quando a função anônima é criada, cria-se o escopo apontado para a variável i, mas não seu valor. E mais, o valor fica 3, pois é o valor de i quando foi feito o teste i < 3, que falha e o for é interrompido. Para resolver o problema, você é obrigado a introduzir um novo escopo, que só haja a possibilidade de i assumir um valor:

var a = [], i;
for(i = 0; i < 3; i++) {
    a[i] = (function(i) {
        return function() {
          console.log(i);
        }
    })(i);
}
a[0]();  //  0
a[1]();  //  1
a[2]();  //  2

undefined

Algumas coisas que eu não gosto de undefined:

undefined == null;   // true
!!undefined;         // false
!!null;              // false
undefined == false   // false
var a;
a == undefined;      // true
typeof undefined;    // 'undefined'
undefined = '123';
typeof undefined;    // 'string'
a == undefined;      // false

Bom, esses são alguns exemplos de código que eu vi até agora. Assim que eu der continuidade no livro postarei mais sobre o que venho aprendendo.

Pra finalizar...

Uma pequena dica. Quem trabalha com JavaScript com certeza conhece o JSLint. Ele aponta vários problemas comuns em código JavaScript, que podem te atrapalhar como desenvolvedor. Um exemplo clássico acontece com object literals terminados com vírgula:

    var a = {
        elem1: 1,
        elem2: 2,
    }

Esse código acima é inválido, porém browsers como Firefox e baseados em WebKit permite a existência desse tipo de código. Mas o Internet Explorer não. Então, o JSLint daria o seguinte erro:

trailing comma is not legal in ECMA-262 object initializers

Como já tive problemas por causa desse erro, seria muito interessante ter esse tipo de checagem durante o tempo de desenvolvimento. Mas há um problema: como executar o JSLint, que está rodando no browser?

Existem duas soluções:

A primeira opção é mais fácil de instalar (brew install jslint) e o plugin syntastic, do Vim, já possui integração para ele:

JavaScript

E como é sua experiência com JavaScript? Quais fontes de informação sobre o assunto? Deixe um feedback nos comentários!

Leia também

blog comments powered by Disqus