Práticas recomendadas para Javascript orientado a objetos? [fechadas]

251

Estou me vendo codificando um grande projeto em Javascript. Lembro que a última foi uma aventura, porque o JS hacky pode rapidamente se tornar ilegível e eu quero que esse código seja limpo.

Bem, estou usando objetos para construir uma biblioteca, mas existem várias maneiras de definir coisas em JS, implicando consequências importantes no escopo, no gerenciamento de memória, no espaço de nome etc. EG:

  • usando varou não;
  • definindo coisas no arquivo ou no (function(){...})()estilo jquery;
  • usando thisou não;
  • usando function myname()ou myname = function();
  • definir métodos no corpo do objeto ou usar "protótipo";
  • etc.

Então, quais são realmente as melhores práticas ao codificar OO em JS?

Explicações acadêmicas realmente esperadas aqui. Link para livros bem-vindos, desde que eles lidem com qualidade e robustez.

EDIT:

Recebi algumas leituras, mas ainda estou muito interessado nas respostas às perguntas acima e nas melhores práticas.

e-satis
fonte
2
Talvez "orientado a objetos" no título deva ser substituído por "moderno".
viam0Zah
43
Hmmm, 79 votos positivos, 82 favoritos, 91 votos positivos na resposta ... mas isso foi fechado como não construtivo ... por quê?
Brett Rossier
1
Eu escrevi uma classe simples portando C ++ OOP Features para javascript com uma sintaxe simples e natural. Veja minha resposta aqui: stackoverflow.com/a/18239463/1115652
14
Esse tipo de pergunta sempre fica fechado. Entendo as razões para isso, mas como são perguntas importantes e sempre populares (e como sempre as encontro quando tenho uma pergunta semelhante), pergunto-me se alguém pode nos direcionar para o local apropriado para fazer essas perguntas.
KP MacGregor
2
@BrettRossier De que adianta o poder se você não o exerce? SO é a demonstração ao vivo de como uma ordem hierárquica democrática funciona. Certamente alguns psicólogos estão olhando para ela ...

Respostas:

288

Usando `var` ou não

Você deve introduzir qualquer variável com a varinstrução, caso contrário ela chega ao escopo global.

Vale ressaltar que, no modo estrito ( "use strict";) , atribuições de variáveis ​​não declaradas são lançadasReferenceError .

No momento, o JavaScript não tem um escopo de bloco. A escola de Crockford ensina você a colocar instruções var no início do corpo da função , enquanto o Guia de Estilo do Dojo lê que todas as variáveis ​​devem ser declaradas no menor escopo possível . (A letdeclaração e a definição introduzidas no JavaScript 1.7 não fazem parte do padrão ECMAScript.)

É uma boa prática vincular propriedades de objetos usados ​​regularmente a variáveis ​​locais, pois é mais rápido do que pesquisar toda a cadeia de escopo. (Consulte Otimizando o JavaScript para obter desempenho extremo e baixo consumo de memória .)

Definindo coisas no arquivo ou em um `(function () {...}) ()`

Se você não precisar alcançar seus objetos fora do código, poderá agrupar todo o código em uma expressão de função - chamada de padrão do módulo. Possui vantagens de desempenho e também permite que seu código seja reduzido e oculto em alto nível. Você também pode garantir que ele não polua o espaço para nome global. As funções de agrupamento em JavaScript também permitem adicionar comportamento orientado a aspectos. Ben Cherry tem um artigo detalhado sobre o padrão do módulo .

Usando `this` ou não

Se você usa herança pseudo-clássica em JavaScript, dificilmente poderá evitar o uso this. É uma questão de gosto que padrão de herança você usa. Para outros casos, consulte o artigo de Peter Michaux sobre JavaScript Widgets Sem "this" .

Usando `function myname ()` ou `myname = function ();`

function myname()é uma declaração de função e myname = function();é uma expressão de função atribuído à variável myname. A última forma indica que as funções são objetos de primeira classe e você pode fazer qualquer coisa com elas, como com uma variável. A única diferença entre eles é que todas as declarações de função são transferidas para o topo do escopo, o que pode ser importante em certos casos. Caso contrário, eles são iguais. function foo()é uma forma abreviada. Mais detalhes sobre a elevação podem ser encontrados no artigo JavaScript Scoping and Hoisting .

Definindo métodos no corpo do objeto ou usando "prototype"

Você decide. O JavaScript possui quatro padrões de criação de objetos: pseudo-clássico, prototípico, funcional e partes ( Crockford, 2008 ). Cada um tem seus prós e contras, veja Crockford em suas palestras em vídeo ou obtenha seu livro The Good Parts, como Anon já sugeriu .

Frameworks

Sugiro que você escolha algumas estruturas de JavaScript, estude suas convenções e estilo e encontre as práticas e padrões que melhor se adequam a você. Por exemplo, o Dojo Toolkit fornece uma estrutura robusta para escrever código JavaScript orientado a objetos que suporta até várias heranças.

Padrões

Por fim, existe um blog dedicado a explorar padrões e antipadrões comuns de JavaScript . Verifique também a pergunta Existem padrões de codificação para JavaScript? no estouro de pilha.

viam0Zah
fonte
1
"O JavaScript tem quatro padrões de criação de objetos: pseudo-clássico, prototípico, funcional e partes" - eu apreciaria realmente um resumo dos prós e contras aqui.
21415 BadHorsie
2
"A letdeclaração e definição introduzida no JavaScript 1.7 não faz parte do padrão ECMAScript." Agora faz parte do ES6.
Michał Perłakowski 24/03
13

Vou escrever algumas coisas que li ou apliquei desde que fiz essa pergunta. Portanto, as pessoas que lêem isso não ficam frustradas, pois a maioria das respostas está disfarçada de RTMF (mesmo que eu deva admitir, os livros sugeridos SÃO bons).

Uso de Var

Qualquer variável deve já estar declarada no escopo mais alto em JS. Portanto, sempre que você desejar uma nova variável, declare-a para evitar surpresas ruins, como manipular uma var global sem perceber. Portanto, sempre use a palavra-chave var.

Em uma marca de objeto, var a variável private. Se você quiser apenas declarar uma variável pública, use this.my_var = my_value-o.

Métodos de declaração

Em JS, eles são inúmeras maneiras de declarar métodos. Para um programador de OO, a maneira mais natural e eficiente é usar a seguinte sintaxe:

Dentro do corpo do objeto

this.methodName = function(param) {

/* bla */

};

Há uma desvantagem: as funções internas não poderão acessar "this" por causa do engraçado escopo do JS. Douglas Crockford recomenda ignorar essa limitação usando uma variável local convencional denominada "that". Então torna-se

function MyObject() {

    var that = this;

    this.myMethod = function() {

        jQuery.doSomethingCrazy(that.callbackMethod);

    };

};

Não confie no fim da linha automático

JS tenta adicionar automaticamente ;no final da linha, se você esquecer. Não confie nesse comportamento, pois você receberá erros que são uma bagunça para depuração.

e-satis
fonte
8

Primeiro, você deve ler sobre a programação baseada em protótipo para saber com que tipo de animal está lidando e depois dar uma olhada no guia de estilo JavaScript no MDC e na página JavaScript no MDC . Eu também acho melhor forçar a qualidade do código com uma ferramenta, ie. JavaScript Lint ou outras variantes.

As práticas recomendadas com OO parecem mais que você deseja encontrar padrões do que se concentrar na qualidade do código. Portanto, observe a pesquisa do Google: padrões javascript e padrões jQuery .

Bleadof
fonte
5

Você pode conferir os Segredos do JavaScript Ninja de John Resig (jQuery). "Este livro pretende levar um desenvolvedor JavaScript intermediário e fornecer a ele o conhecimento necessário para criar uma biblioteca JavaScript entre navegadores, desde o início".

O rascunho está disponível no editor: http://www.manning.com/resig/

Douglas Crockford também tem alguns bons artigos sobre JavaScript em sua página inicial: http://www.crockford.com/

gregers
fonte
5

Costumo me sentir o único cara aqui que usa o MooTools para o meu javascript.

Fica para M y O bject O riented ferramentas, mootools.

Eu realmente gosto da opinião deles sobre o OOP em javascript. Você também pode usar a implementação de classes junto com o jquery, para não precisar abandonar o jquery (embora o mootools faça tudo isso da mesma forma).

De qualquer forma, dê uma boa leitura ao primeiro link e veja o que você pensa; o segundo link é para os documentos do mootools.

MooTools & Herança

Classes do MooTools

Ryan Florence
fonte
Não acho que tentar dobrar um idioma para torná-lo adequado ao seu velho hábito é uma coisa boa. É como essas pessoas em C, usando # para substituir, parece fortran, ou então. Eu acho que você deve tentar aprender o caminho das obras de linguagem (e seu melhor practicesà, e usá-lo da maneira que não incomodá-lo muito Mas não mudá-lo, realmente..
e-satis
2
Eu acho que o sistema de objetos do MooTools é bastante elegante e realmente me ajuda a manter meu código organizado / encapsulado.
22410 awesomo