Crockford ha fatto molto per diffondere buone tecniche JavaScript. La sua posizione supponente su elementi chiave della lingua ha scatenato molte discussioni utili. Detto questo, ci sono troppe persone che prendono ogni annuncio di "cattivo" o "dannoso" come vangelo, rifiutando di guardare oltre l'opinione di un uomo. A volte può essere un po 'frustrante.
L'uso della funzionalità fornita dalla new
parola chiave presenta diversi vantaggi rispetto alla creazione di ogni oggetto da zero:
- Eredità del prototipo . Sebbene sia spesso considerata con un mix di sospetto e derisione da parte di coloro che sono abituati ai linguaggi OO di classe, la tecnica di ereditarietà nativa di JavaScript è un mezzo semplice e sorprendentemente efficace di riutilizzo del codice. E la nuova parola chiave è il mezzo canonico (e disponibile solo multipiattaforma) per usarlo.
- Prestazione. Questo è un effetto collaterale del n. 1: se voglio aggiungere 10 metodi a ogni oggetto che creo, potrei semplicemente scrivere una funzione di creazione che assegni manualmente ogni metodo a ciascun nuovo oggetto ... Oppure, potrei assegnarli al funzione di creazione
prototype
e uso new
per sradicare nuovi oggetti. Non solo è più veloce (non è necessario alcun codice per ogni singolo metodo sul prototipo), ma evita il palloncino di ogni oggetto con proprietà separate per ciascun metodo. Su macchine più lente (o in particolare su interpreti JS più lenti) quando vengono creati molti oggetti, ciò può significare un notevole risparmio di tempo e memoria.
E sì, new
ha uno svantaggio cruciale, abilmente descritto da altre risposte: se dimentichi di usarlo, il tuo codice si romperà senza preavviso. Fortunatamente, questo svantaggio è facilmente mitigato: basta aggiungere un po 'di codice alla funzione stessa:
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...
}
Ora puoi avere i vantaggi di new
senza doverti preoccupare dei problemi causati da un uso improprio accidentale. Potresti anche aggiungere un'asserzione al controllo se il pensiero di un codice non funzionante silenziosamente ti disturba. Oppure, come alcuni hanno commentato, utilizzare il segno di spunta per introdurre un'eccezione di runtime:
if ( !(this instanceof arguments.callee) )
throw new Error("Constructor called as a function");
(Si noti che questo frammento è in grado di evitare di codificare il nome della funzione di costruzione in quanto, diversamente dall'esempio precedente, non è necessario istanziare effettivamente l'oggetto, pertanto può essere copiato in ciascuna funzione di destinazione senza modifiche.)
John Resig approfondisce questa tecnica nel suo semplice post sull'istanza "Class" , oltre a includere un mezzo per incorporare questo comportamento nelle "classi" per impostazione predefinita. Sicuramente merita una lettura ... come lo è il suo prossimo libro, Secrets of the JavaScript Ninja , che trova l'oro nascosto in questa e molte altre caratteristiche "dannose" del linguaggio JavaScript (il capitolo su with
è particolarmente illuminante per quelli di noi che inizialmente hanno respinto questa caratteristica molto diffamata come un espediente).