Crockford fez muito para popularizar boas técnicas de JavaScript. Sua posição opinativa sobre os principais elementos da linguagem provocou muitas discussões úteis. Dito isto, existem muitas pessoas que tomam cada proclamação de "mau" ou "prejudicial" como evangelho, recusando-se a olhar além da opinião de um homem. Às vezes pode ser um pouco frustrante.
O uso da funcionalidade fornecida pela new
palavra-chave tem várias vantagens sobre a construção de cada objeto do zero:
- Herança de protótipo . Embora muitas vezes sejam encaradas com uma mistura de suspeita e escárnio por aqueles acostumados a linguagens OO baseadas em classes, a técnica de herança nativa do JavaScript é um meio simples e surpreendentemente eficaz de reutilização de código. E a nova palavra-chave é o meio canônico (e apenas disponível em várias plataformas) de usá-lo.
- Atuação. Este é um efeito colateral do nº 1: se eu quiser adicionar 10 métodos a cada objeto que eu criar, eu poderia escrever uma função de criação que atribua manualmente cada método a cada novo objeto ... Ou poderia atribuí-los ao método funções de criação
prototype
e uso new
para carimbar novos objetos. Além de ser mais rápido (não é necessário código para todos os métodos do protótipo), ele evita o balão de cada objeto com propriedades separadas para cada método. Em máquinas mais lentas (ou especialmente, intérpretes JS mais lentos) quando muitos objetos estão sendo criados, isso pode significar uma economia significativa de tempo e memória.
E sim, new
tem uma desvantagem crucial, habilmente descrita por outras respostas: se você esquecer de usá-lo, seu código será quebrado sem aviso. Felizmente, essa desvantagem é facilmente mitigada - basta adicionar um pouco de código à própria função:
function foo()
{
// if user accidentally omits the new keyword, this will
// silently correct the problem...
if ( !(this instanceof foo) )
return new foo();
// constructor logic follows...
}
Agora você pode ter as vantagens de new
não ter que se preocupar com problemas causados por uso indevido acidental. Você pode até adicionar uma asserção à verificação se o pensamento de código quebrado funcionar silenciosamente o incomoda. Ou, como alguns comentaram, use a verificação para introduzir uma exceção de tempo de execução:
if ( !(this instanceof arguments.callee) )
throw new Error("Constructor called as a function");
(Observe que esse fragmento é capaz de evitar codificar o nome da função do construtor, pois, diferentemente do exemplo anterior, ele não precisa instanciar o objeto - portanto, ele pode ser copiado em cada função de destino sem modificação.)
John Resig detalha essa técnica em seu post de Instanciação "Classe" Simples , além de incluir um meio de transformar esse comportamento em suas "classes" por padrão. Definitivamente vale a pena ler ... assim como seu próximo livro, Secrets of the JavaScript Ninja , que encontra ouro oculto neste e em muitos outros recursos "prejudiciais" da linguagem JavaScript (o capítulo sobre with
é especialmente esclarecedor para aqueles que inicialmente descartaram esse recurso muito difamado como um artifício).