Dominação Global, parte dois

16 de abril de 2008 às 01:29 por Douglas Crockford | Em Desenvolvimento | 9 Comments

Enquanto eu continuar a prática do ofício de programação, estou sempre examinar minhas práticas. Posso melhorar os padrões que eu uso para que eu possa fazer meus programas mais clara, mais forte, melhor? Isto é particularmente importante quando se trabalha com uma linguagem como JavaScript, que tem um viés que privilegia padrões que são confusas, fracas, e pior.

Uma das piores características do JavaScript é a sua dependência de variáveis ​​globais. Isto pode ser mitigado com redução mundial eo padrão de módulo , que pode reduzir significativamente o número de variáveis ​​globais que temos a declarar.

Mas quando devemos declarar uma variável global, a melhor forma que devemos fazer isso? JavaScript oferece três maneiras de declarar uma variável global, e todos eles têm problemas. Que, pelo menos é o pior?

O primeiro é para atribuir um novo nome fora de qualquer função.

  pena = {} / / A primeira forma 

A segunda é usar o var palavra-chave fora de qualquer função.

  var pena = {} / / A segunda forma 

A terceira é a de atribuir a uma propriedade do objeto global.

  this.pity = {} / / A terceira forma 

Todas as três formas fazer a mesma coisa. (Há também um quarto caminho, o global abominável implícita, mas não vamos falar disso aqui. E não me fale sobre as formas quinta e sexta).

Assim, dado três maneiras de fazer a mesma coisa, que devemos usar? Eu costumava favorecer a segunda maneira. Ele olhou para mim a mais clara em afirmar (ou pelo menos sugerir) minha intenção de declarar alguma coisa.

Mas não foi completamente satisfatório. Primeiro, algumas pessoas lêem var nessa posição como declarar a variável no âmbito da unidade de compilação, similar à maneira static obras em C. Esta seria uma leitura útil, exceto que o JavaScript não têm escopo unidade de compilação. Um programador experiente deve saber que, mas um percentual alarmante de programa de desenvolvedores web na ignorância da língua, por isso esta é uma preocupação moderada.

A maior preocupação é que a segunda forma é maior do que a primeira forma, mas faz a mesma coisa. Geralmente, eu prefiro formas mínimas.

Mas a coisa que finalmente me convenceu de que a primeira forma é o menos pior é que o IE é a segunda forma errada, de modo que os programas com responsabilidade adaptativa falhar quando usando construções como

  var pena this.pity = | | {}; 

A fim de ser maximamente produtivo, eu quero evitar recursos que têm problemas de portabilidade. Levei muito tempo para aceitar que a segunda forma é problemático e deve ser evitada.

A coisa que eu gostei sobre a segunda forma foi que ele parecia mais intencional. Digitando var , eu declarei que este não é um erro ortográfico acidental. Estou intencionalmente declarando uma nova variável global. Mas JavaScript não prestou atenção. Eu ainda sinto a necessidade de afirmar que a intenção, então eu estado em que em um comentário.

  / * Pena global * /
     = piedade {}; 

JSLint é capaz de entender que o comentário, e pode alertar-me para qualquer variável global que eu não intencionalmente declarar. Isso me dá confiança de que não estou cometendo um erro comum. A segunda forma me fez sentir bem, mas não chegou a me dar qualquer garantia real.

Eu ainda estou aprendendo a programar. Eu li o código, e eu considerar as opiniões de outros programadores. Eu ainda tenho a capacidade de mudar as minhas práticas. É difícil, por vezes, a admitir que o meu práticas anteriores eram fracos. Mas isso é mais do que compensado pela adoção de práticas que são mais fortes.

Compartilhar e ampliar: Bookmark com del.icio.us | digg it! | reddit!

9 Comentários

  1. Testando o sistema de comentários, que foi para baixo por um tempo lá. Tudo parece voltar ao normal, embora, por isso dar-lhe um ir!

    Comentário por Administrator - 21 de abril de 2008 #

  2. Gostaria de pensar que é do conhecimento comum para verificar typeof pity === 'undefined' , em vez de usar uma construção como var pity = this.pity || {}; , especialmente considerando que o código em questão é o subproduto de uma razoável programa de adaptação.

    Se você assumir que o público desenvolvedor web que o programa na ignorância da língua e os leitores deste blog (ou o leitor de qualquer autor do blog JavaScript que adota este método) são mutuamente exclusivos, então pode-se tendência para concordar a sua terceira forma é apropriado .

    Mas, vendo que a maioria dos desenvolvedores "aprender" a partir de copiar e colar, parece que a segunda forma seria mais seguro, se por nenhuma outra razão do que para prevenir os globals abominável que todos nós abominamos.

    Comentário por Zach Leatherman - 21 de abril de 2008 #

  3. O "var pena this.pity = | | {}" e suas variantes se tornou bastante popular em bibliotecas recente Javascript, e eu gosto mim. Você vai ter que ceder à suposição de que você usá-lo em lugares onde não são valores booleanos que você espera.

    Um dos casos mais úteis para mim seria como um valor padrão para parâmetros de função. Considerar:

    função doSomething (a) {
    a = a | | 'defaultValue';
    }

    Se a variável 'a' é indefinido aqui, ele vai ter um valor padrão ao invés, tornando a variável 'a' úteis para o resto da função.

    Mas se você preferir, eu acho que poderia ser escrito como:

    função doSomething (a) {
    a = (! a == undefined a:? defaultValue ');
    }

    Comentário por Frode Danielsen - 1 de maio de 2008 #

  4. [...] Estar mentindo se eu dissesse que não foi influenciado externamente em um presente. Douglas Crockford tem um monte de recomendações grande, e isso é que eu tendo a concordar [...]

    Pingback por scriptNode / My New Habits Coding - 02 de agosto de 2008 #

  5. Eu gosto de como a biblioteca ExtJS lida com isso. Eles desenvolvedores abstrair do problema, fornecendo um utilitário para criar 'espaços'. Eu não sei exatamente como eles estão fazendo isso sob as cobertas, mas eu sei que o site de Douglas Crockford javascript é uma forte influência em seu desenvolvimento, então eu não ficaria surpreso ao descobrir que eles usam uma das formas apresentadas acima. Como um desenvolvedor, porém, tudo o que tenho a fazer é esta:
    Ext.namespace ('pena');
    ou esta forma mais curta:
    Ext.ns ('pena');
    Eu posso até declarar múltiplos níveis em uma única linha:
    Ext.ns ('piedade', 'pity.util', 'pity.util.text');

    Comentário por Bernie Margolis - 19 de novembro de 2008 #

  6. outra forma que eu normalmente prefiro é:

    this.pity | | (this.pity = {});

    a razão é que evita um extra "mesmo valor" atribuição se que já existem mundial e eu fazer o mesmo em funções de parâmetros passados:

    função doSomething (a) {
    a | | (a = "defaultValue");
    }

    boa para espalhar a voz qualquer que seja a correta ...

    Comentário por Diego Perini - 29 de janeiro de 2010 #

  7. Mas a coisa que finalmente me convenceu de que a primeira forma é o menos pior é que o IE é a segunda forma errada, de modo que os programas com responsabilidade adaptativa não

    Eu não tenho sido capaz de encontrar qualquer informação sobre a forma como o IE é a segunda forma errada.

    Pessoalmente, eu tenho usado:

    var fooObj;
    if (fooObj === undefined) {
    fooObj = {};
    }

    Comentário por Jay em Oregon - 12 de julho de 2010 #

  8. Não use o método descrito no artigo acima, se você sabe o que é bom para você. Seu código vai quebrar na ES-5 modo estrito.

    Como atribuições não declarado são uma parte tão enganosa da língua, ECMAScript 5 - versão mais recente do ECMAScript - especifica que, quando eles ocorrem em um modo estrito, um ReferenceError deve ser acionada. Isto faz para um código mais robusto, com menos chance de erros inesperados. E, desde modo estrito é mais ou menos uma direção futura da língua, faz sentido para evitar atribuições não declarado como se nunca tivessem existido.

    Comentário por Zach Leatherman - 29 mar 2011 #

  9. Eu recomendo usar apenas a forma da função de declaração de modo estrito. Comentário de Zach só se aplica à forma de arquivo.

    Comentário por Douglas Crockford - 29 de março de 2011 #

Desculpe, o formulário de comentário é fechado neste momento.

Hospedado por Yahoo!

Copyright © 2006-2011 Yahoo! Inc. Todos os direitos reservados. Política de Privacidade - Termos de Serviço

Alimentado por WordPress em Yahoo! Web Hosting .