Quando utilizzare Vanilla JavaScript e jQuery?


238

Durante il monitoraggio / il tentativo di rispondere a domande jQuery comuni, ho notato che esistono alcune pratiche che utilizzano javascript, anziché jQuery, che in realtà ti consentono di scrivere di meno e fare ... bene la stessa quantità. E può anche offrire vantaggi in termini di prestazioni.

Un esempio specifico

$(this) vs this

All'interno di un evento click che fa riferimento all'id oggetto cliccato

jQuery

$(this).attr("id");

Javascript

this.id;

Ci sono altre pratiche comuni come questa? Laddove alcune operazioni Javascript potrebbero essere realizzate più facilmente, senza portare jQuery nel mix. O è un caso raro? (di una "scorciatoia" jQuery che richiede effettivamente più codice)

EDIT: Mentre apprezzo le risposte riguardanti jQuery e le prestazioni javascript semplici, in realtà sto cercando risposte molto più quantitative. Durante l'utilizzo di jQuery , casi in cui si sarebbe effettivamente meglio (leggibilità / compattezza) per utilizzare javascript semplice invece di utilizzare $(). Oltre all'esempio che ho fornito nella mia domanda originale.


Non sono sicuro di aver capito la domanda. Stavi cercando opinioni sul merito dell'utilizzo del codice della libreria o stavi cercando altre tecniche compatibili non cross-browser con jQuery simili this.id?
user113716

1
dalle risposte sembra che tutti stiano prendendo questa domanda come filosofica, dal momento che intendevo che fosse molto quantitativa, da quasi compilare un elenco di casi come quello che ho delineato che sono pratiche (mal) comuni.
jondavidjohn,


Risposte:


207
  • this.id (come sai)
  • this.value(sulla maggior parte dei tipi di input. solo i problemi che conosco sono IE quando un <select>non ha valueproprietà impostate sui suoi <option>elementi o ingressi radio in Safari.)
  • this.className per ottenere o impostare un'intera proprietà "class"
  • this.selectedIndexcontro a <select>per ottenere l'indice selezionato
  • this.optionscontro a <select>per ottenere un elenco di <option>elementi
  • this.textcontro an <option>per ottenere il suo contenuto testuale
  • this.rowscontro a <table>per ottenere una raccolta di <tr>elementi
  • this.cellscontro a <tr>per ottenere le sue celle (td e th)
  • this.parentNode per avere un genitore diretto
  • this.checkedper ottenere lo stato verificato di un checkbox Thanks @Tim Down
  • this.selectedper ottenere lo stato selezionato di un option ringraziamento @Tim giù
  • this.disabledper ottenere lo stato disabilitato di un input Thanks @Tim Down
  • this.readOnlyper ottenere lo stato readOnly di un input Thanks @Tim Down
  • this.hrefcontro un <a>elemento per ottenere il suohref
  • this.hostnamecontro un <a>elemento per ottenere il suo dominiohref
  • this.pathnamecontro un <a>elemento per ottenere il suo percorsohref
  • this.searchcontro un <a>elemento per ottenere la sua stringa di queryhref
  • this.src contro un elemento in cui è valido avere un src

... Penso che tu abbia avuto l'idea.

Ci saranno momenti in cui le prestazioni sono cruciali. Ad esempio, se stai eseguendo qualcosa in un loop molte volte, potresti voler abbandonare jQuery.

In generale è possibile sostituire:

$(el).attr('someName');

con:

Sopra era formulato male. getAttributenon è un sostituto, ma recupera il valore di un attributo inviato dal server e il suo corrispondente setAttributelo imposterà. Necessario in alcuni casi.

Le frasi sottostanti lo hanno coperto. Vedi questa risposta per un trattamento migliore.

el.getAttribute('someName');

... per accedere direttamente a un attributo. Si noti che gli attributi non sono gli stessi delle proprietà (anche se a volte si rispecchiano a vicenda). Certo che c'è setAttributeanche.

Supponiamo che tu abbia avuto una situazione in cui hai ricevuto una pagina in cui devi scartare tutti i tag di un certo tipo. È breve e facile con jQuery:

$('span').unwrap();  // unwrap all span elements

Ma se ce ne sono molti, potresti voler fare una piccola API DOM nativa:

var spans = document.getElementsByTagName('span');

while( spans[0] ) {
    var parent = spans[0].parentNode;
    while( spans[0].firstChild ) {
        parent.insertBefore( spans[0].firstChild, spans[0]);
    }
    parent.removeChild( spans[0] );
}

Questo codice è piuttosto breve, funziona meglio della versione jQuery e può essere facilmente trasformato in una funzione riutilizzabile nella tua libreria personale.

Può sembrare che io abbia un ciclo infinito con l'esterno a whilecausa di while(spans[0]), ma poiché abbiamo a che fare con una "lista live", questa viene aggiornata quando eseguiamo il parent.removeChild(span[0]);. Questa è una caratteristica piuttosto ingegnosa che ci manca quando si lavora con un array (o un oggetto simile a un array).


2
bello ... quindi principalmente ruota attorno a questa parola chiave che viene involontariamente racchiusa in un oggetto jQuery.
jondavidjohn,

1
@jondavidjohn: Beh, ci sono alcune correzioni che sono belle in alcuni casi, come ad esempio this.valuedove ci sono un paio di stranezze del browser in alcuni casi. Tutto dipende dalle tue necessità. Ci sono molte belle tecniche che sono facili senza jQuery, specialmente quando le prestazioni sono cruciali. Proverò a pensare di più.
user113716

3
Stavo per scrivere una risposta ma invece aggiungerò suggerimenti per i tuoi. In generale, attr()è ampiamente abusato. Se hai a che fare solo con un elemento, raramente ne avrai bisogno attr(). Due dei miei preferiti sono la confusione intorno alla checkedproprietà di caselle di controllo (tutti i tipi di incantesimi mistici in giro che uno: $(this).attr("checked", "checked"), $(this).is(":checked")etc.) e allo stesso modo la selectedproprietà di <option>elementi.
Tim Down

1
Aaargh, @patrick, noooo: mi hai consigliato getAttribute(). Non ne hai quasi mai bisogno : è rotto in IE, non riflette sempre lo stato corrente e non è comunque ciò che fa jQuery. Usa solo le proprietà. stackoverflow.com/questions/4456231/…
Tim Down

1
Stavo usando JS da così tanto tempo e non sapevo di className, grazie.
IAdapter,

60

La risposta corretta è che subirai sempre una penalità prestazionale quando usi jQuery invece del JavaScript nativo "semplice". Questo perché jQuery è una libreria JavaScript. Non è una nuova versione di JavaScript.

Il motivo per cui jQuery è potente è che rende alcune cose eccessivamente noiose in una situazione cross-browser (AJAX è uno dei migliori esempi) e risolve le incoerenze tra la miriade di browser disponibili e fornisce un'API coerente. Inoltre facilita facilmente concetti come il concatenamento, l'iterazione implicita, ecc., Per semplificare il lavoro su gruppi di elementi insieme.

L'apprendimento di jQuery non sostituisce l'apprendimento di JavaScript. Dovresti avere una solida base nel secondo in modo da apprezzare appieno ciò che sapere che il primo ti sta rendendo più facile.

- Modificato per comprendere i commenti -

Come i commenti sono rapidi da sottolineare (e concordo con il 100%), le dichiarazioni sopra riportate si riferiscono al codice di benchmarking. Una soluzione JavaScript "nativa" (supponendo che sia ben scritta) supererà una soluzione jQuery che realizza la stessa cosa in quasi tutti i casi (mi piacerebbe vedere un esempio altrimenti). jQuery accelera i tempi di sviluppo, il che è un vantaggio significativo che non intendo minimizzare. Facilita il codice facile da leggere e da seguire, che è più di quanto alcuni sviluppatori siano in grado di creare da soli.

A mio avviso, quindi, la risposta dipende da ciò che stai tentando di ottenere. Se, come supponevo in base al tuo riferimento ai vantaggi in termini di prestazioni, stai cercando la migliore velocità possibile fuori dall'applicazione, l'utilizzo di jQuery comporta un sovraccarico ogni volta che chiami $(). Se stai cercando leggibilità, coerenza, compatibilità cross-browser, ecc., Ci sono sicuramente motivi per favorire jQuery rispetto a JavaScript "nativo".


8
Mi piacerebbe vedere un esempio di una situazione in cui jQuery può superare l'implementazione in JS puro. Indipendentemente da ciò che fai, se stai usando jQuery (o qualsiasi altra libreria per quella materia) hai un sovraccarico di funzioni che è inevitabile. Non c'è modo di allontanarsi dal (seppur) lieve sovraccarico generato dalla chiamata $(). Se non effettui quella chiamata, risparmi tempo.
gddc,

16
Una soluzione casalinga scritta male sarebbe probabilmente più lenta. Il team di jQuery ha eseguito alcuni JavaScript altamente efficienti nel pacchetto. Vedi la risposta di @ Freelancer.
Stephen

3
Una soluzione scritta male sarà sempre una soluzione scritta male, e non è colpa della lingua. Ciò non cambia il fatto che la libreria comporterà un sovraccarico che una funzione "nativa" potrebbe evitare se ben ponderata.
gddc,

11
@gddc Penso che l'esempio migliore in cui jQuery "superi" (leggi fuori dal riquadro di riferimento) JS puro stia riducendo i tempi di sviluppo (che è un valore enorme per il business) e semplificando la sperimentazione
Ben

13
Tutto ciò che hai scritto è vero, ma hai lasciato fuori quanto sopra @Ben. jQuery rende lo sviluppatore più veloce e più robusto. Guarda questa implementazione di KillClass () che ho scritto molti anni fa e che ho usato molto. Sai cosa? È rotto per alcuni casi limite. Il codice scadente è un codice scadente e il codice errato è un codice errato, ma l'uso di jQuery spesso rende lo sviluppatore a scrivere codice migliore e più corretto. Il più delle volte, i computer sono abbastanza veloci; sono gli sviluppatori che hanno bisogno dell'aiuto.
Phrogz,

38

C'è un framework chiamato ... oh indovina un po '? Vanilla JS. Spero che tu abbia capito la battuta ...: D Sacrifica la leggibilità del codice per le prestazioni ... Confrontandolo con il jQuerymuggito puoi vedere che il recupero di un DOMelemento IDè quasi 35 volte più veloce. :)

Quindi, se vuoi prestazioni, è meglio provare Vanilla JS e trarre le tue conclusioni. Forse non sperimenterai JavaScript che blocca la GUI del browser / blocca il thread dell'interfaccia utente durante il codice intenso come all'interno di un forciclo.

Vanilla JS è un framework multipiattaforma veloce, leggero per la creazione di incredibili e potenti applicazioni JavaScript.

Sulla loro homepage ci sono alcuni paragoni perf:

inserisci qui la descrizione dell'immagine


1
@Leniel Macaferi Oh amico, ho adorato questa risposta! Non mi ero reso conto che le prestazioni tra vaniglia e altri framework potessero fare la differenza! Comunque Hall of fame per questa risposta !! PS: hai creato anche il sito web?
Steve,

17

C'è già una risposta accettata ma credo che nessuna risposta digitata direttamente qui possa essere completa nel suo elenco di metodi / attributi javascript nativi che ha praticamente garantito il supporto cross-browser. Per questo posso reindirizzarti a quirksmode:

http://www.quirksmode.org/compatibility.html

È forse l'elenco più completo di ciò che funziona e ciò che non funziona su quale browser ovunque. Prestare particolare attenzione alla sezione DOM. È molto da leggere ma il punto non è leggere tutto ma usarlo come riferimento.

Quando ho iniziato seriamente a scrivere app Web, ho stampato tutti i tavoli DOM e li ho appesi al muro in modo da sapere a colpo d'occhio cosa è sicuro da usare e cosa richiede hack. In questi giorni ho solo google qualcosa come quirksmode parentNode compatibilityquando ho dei dubbi.

Come ogni altra cosa, il giudizio è principalmente una questione di esperienza. Non ti consiglierei davvero di leggere l'intero sito e memorizzare tutti i problemi per capire quando usare jQuery e quando usare JS semplice. Basta essere consapevoli dell'elenco. È abbastanza facile da cercare. Con il tempo svilupperai un istinto di quando è preferibile il semplice JS.


PS: PPK (l'autore del sito) ha anche un bel libro che consiglio di leggere


14

Quando:

  1. sapete che esiste un supporto incrociato senza browser per ciò che state facendo e
  2. non è significativamente più codice da digitare e
  3. non è significativamente meno leggibile, e
  4. sei abbastanza sicuro che jQuery non sceglierà implementazioni diverse in base al browser per ottenere prestazioni migliori, quindi:

usa JavaScript. Altrimenti usa jQuery (se puoi).

Modifica : questa risposta si applica sia quando si sceglie di utilizzare jQuery in generale piuttosto che tralasciandolo, oltre a scegliere se utilizzare JS alla vaniglia all'interno di jQuery. Scegliere tra attr('id')e .idsi appoggia a favore di JS, mentre scegliere tra removeClass('foo')versus .className = .className.replace( new Regexp("(?:^|\\s+)"+foo+"(?:\\s+|$)",'g'), '' )si appoggia a favore di jQuery.


3
Penso che l'OP abbia intenzione di usare jQuery, ma si chiede dove e quando usare JavaScript nativo all'interno dei suoi metodi jQuery.
Stephen

.classList.remove('foo')sembra funzionare bene nei browser più recenti
Tyilo,

3
@Tyilo classList.remove fa parte dell'API ClassList HTML5 che non è implementata in IE9, ad esempio caniuse.com/#feat=classlist
corbacho,

13

Le risposte degli altri si sono concentrate sull'ampia domanda di "jQuery vs. JS semplice". A giudicare dal tuo PO, penso che ti stavi semplicemente chiedendo quando è meglio usare Vanilla JS se hai già scelto di usare jQuery. Il tuo esempio è un esempio perfetto di quando dovresti usare la vaniglia JS:

$(this).attr('id');

È più lento e (secondo me) meno leggibile di:

this.id.

È più lento perché devi girare un nuovo oggetto JS solo per recuperare l'attributo nel modo jQuery. Ora, se hai intenzione di utilizzare $(this)per eseguire altre operazioni, allora memorizza l'oggetto jQuery in una variabile e agisci con quello. Tuttavia, mi sono imbattuto in molte situazioni in cui ho solo bisogno di un attributo dall'elemento (come ido src).

Ci sono altre pratiche comuni come questa? Laddove alcune operazioni Javascript potrebbero essere realizzate più facilmente, senza portare jQuery nel mix. O è un caso raro? (di una "scorciatoia" jQuery che richiede effettivamente più codice)

Penso che il caso più comune sia quello che descrivi nel tuo post; persone che si avvolgono $(this)in un oggetto jQuery inutilmente. Lo vedo più spesso con ide value(invece di usare $(this).val()).

Modifica: ecco un articolo che spiega perché l' uso di jQuery nel attr()caso sia più lento. Confessione: rubato dal tag wiki, ma penso che valga la pena menzionarlo per la domanda.

Modifica di nuovo: date le implicazioni in termini di leggibilità / prestazioni del solo accesso diretto agli attributi, direi che una buona regola empirica è probabilmente quella di provare a usare this.<attributename>quando possibile. Probabilmente ci sono alcuni casi in cui questo non funzionerà a causa di incoerenze del browser, ma è probabilmente meglio provare prima questo e ricorrere a jQuery se non funziona.


hah, grazie per aver letto la domanda;) ... quindi questa è più in generale l'eccezione?
jondavidjohn,

@jondavidjohn: Onestamente, sono titubante a fare quella chiamata. Penso di sì, di solito è a tuo vantaggio utilizzare jQuery a causa di problemi tra browser. Ci sono altri esempi, come this.style.display = 'none'. È meglio di $(this).hide()? Direi che il secondo è più leggibile, ma il primo è probabilmente più veloce. Non fa male sperimentare te stesso per vedere se certe azioni funzioneranno attraverso i browser senza jQuery - Questo è in genere ciò che faccio prima di avvolgere un elemento in un oggetto jQuery per eseguire un'operazione.
Andrew Whitaker,

10

Se sei principalmente preoccupato per le prestazioni, il tuo esempio principale colpisce l'unghia sulla testa. Invocare jQuery inutilmente o in modo ridondante è, IMHO, la seconda causa principale di prestazioni lente (la prima è una traversata DOM scadente).

Non è proprio un esempio di ciò che stai cercando, ma lo vedo così spesso da menzionare: uno dei modi migliori per accelerare le prestazioni degli script jQuery è memorizzare nella cache gli oggetti jQuery e / o usare il concatenamento:

// poor
$(this).animate({'opacity':'0'}, function() { $(this).remove(); });

// excellent
var element = $(this);
element.animate({'opacity':'0'}, function() { element.remove(); });

// poor
$('.something').load('url');
$('.something').show();

// excellent
var something = $('#container').children('p.something');
something.load('url').show();

interessante ... questa separazione tra var istanza e azione porta effettivamente all'aumento delle prestazioni di elaborazione? o permette semplicemente all'azione di essere eseguita da sola (rendendola meno
gravosa

1
Sicuramente porta a miglioramenti delle prestazioni, ma solo se riutilizzi l'elemento selezionato. Quindi, nell'ultimo caso var something, non avevo davvero bisogno di memorizzare nella cache l'oggetto jQuery (da quando ho usato il concatenamento), ma lo faccio comunque per abitudine.
Stephen

2
D'altra parte, prendi lo stesso esempio. Chiamare $('.something')due volte significa che jQuery deve attraversare il DOM due volte cercando tutti gli elementi con quel selettore.
Stephen

2
Nel caso del primo esempio, la memorizzazione nella cache $(this)riduce le chiamate alla funzione jQuery. Questo ti darà il massimo guadagno in uno scenario ad anello.
Stephen

2
@Alnitak Notare che elementè uguale a $(this). Ciò non contiene più elementi.
Stephen

8

Ho scoperto che c'è sicuramente una sovrapposizione tra JS e JQ. Il codice che hai mostrato ne è un buon esempio. Francamente, il miglior motivo per usare JQ su JS è semplicemente la compatibilità del browser. Mi affido sempre a JQ, anche se riesco a realizzare qualcosa in JS.


8
Sarebbe una meraviglia se non ci fossero sovrapposizioni, perché JQuery è JavaScript.
simon,

6

Questa è la mia opinione personale, ma dato che jQuery è comunque JavaScript, penso che teoricamente non possa mai funzionare meglio di JS vaniglia.

Ma praticamente potrebbe funzionare meglio di JS scritto a mano, poiché il codice scritto a mano potrebbe non essere efficiente come jQuery.

In conclusione: per cose più piccole tendo a usare JS alla vaniglia, per i progetti intensivi di JS mi piace usare jQuery e non reinventare la ruota: è anche più produttivo.


1
Ci sono molti esempi in cui le biblioteche superano JS vaniglia. Si scopre che molti dei metodi prototipo integrati di JS sono scritti male.
Statistiche di apprendimento con l'esempio

3

L'elenco delle proprietà live della prima risposta thiscome elemento DOM è abbastanza completo.

Potresti trovare interessante anche conoscerne altri.

Quando questo è il documento:

  • this.formsper ottenere uno HTMLCollectiondei moduli del documento corrente,
  • this.anchorsper ottenere una HTMLCollectiondi tutte HTMLAnchorElementscon nameessere impostato,
  • this.linksper ottenere una HTMLCollectiondi tutte le HTMLAnchorElements con hrefessere impostato,
  • this.imagesper ottenere una HTMLCollectiondi tutte le HTMLImageElements
  • e lo stesso con le applet obsolete come this.applets

Quando lavori con document.forms, document.forms[formNameOrId]ottiene il modulo così chiamato o identificato.

Quando questo è un modulo:

  • this[inputNameOrId] per ottenere il campo così chiamato o identificato

Quando questo è un campo modulo:

  • this.type per ottenere il tipo di campo

Quando impariamo i selettori jQuery, spesso saltiamo l'apprendimento delle proprietà degli elementi HTML già esistenti, che sono così veloci da accedere.


Le proprietà che hai citato sono definite nella specifica HTML DOM Level 2 e ampiamente supportate. document.embedse document.pluginssono anche ampiamente supportati (DOM 0). document.scriptsè anche una raccolta conveniente, definita nella specifica HTML5 e ampiamente supportata (e Firefox 9+ ).
Rob W,

@Robw Quindi l'elenco potrebbe ora essere completo, e sicuramente utile e veloce. Grazie;)
lib3d

2

Come al solito, arrivo tardi a questa festa.

Non è stata la funzionalità extra che mi ha fatto decidere di usare jQuery, per quanto attraente fosse. Dopo tutto nulla ti impedisce di scrivere le tue funzioni.

Era il fatto che c'erano molti trucchi da imparare quando si modifica il DOM per evitare perdite di memoria (sto parlando di te IE). Avere una risorsa centrale che gestisse per me quel tipo di problemi, scritto da persone che erano codificatori JS decisamente migliori di quanto io sia mai stato, che veniva continuamente rivisto, revisionato e testato, è stato mandato da Dio.

Immagino che questo tipo di cose rientri nell'argomento supporto / astrazione tra browser.

E ovviamente jQuery non preclude l'uso di JS etero quando ne avevi bisogno. Ho sempre pensato che i due sembrassero funzionare perfettamente insieme.

Naturalmente se il tuo browser non è supportato da jQuery o stai supportando un ambiente di fascia bassa (telefono più vecchio?), Un file .js di grandi dimensioni potrebbe essere un problema. Ricordi quando jQuery era piccolo?

Ma normalmente la differenza di prestazioni non è un problema. Deve solo essere abbastanza veloce. Con Gigahertz di cicli di CPU che sprecano ogni secondo, sono più preoccupato per le prestazioni dei miei programmatori, le uniche risorse di sviluppo che non raddoppiano in potenza ogni 18 mesi.

Detto questo, sto attualmente esaminando i problemi di accessibilità e apparentemente .innerHTML è un po 'no con quello. jQuery ovviamente dipende da .innerHTML, quindi ora sto cercando un framework che dipenderà dai metodi un po 'noiosi consentiti. E posso immaginare che un tale framework funzionerà più lentamente di jQuery, ma finché funzionerà abbastanza bene, sarò felice.


2

Ecco una risposta non tecnica: molti lavori potrebbero non consentire determinate librerie, come jQuery.

In effetti, infatti, Google non consente jQuery in nessuno dei loro codici (né React, perché è di proprietà di Facebook), che potresti non aver conosciuto fino a quando l'intervistatore non dice "Mi dispiace, ma non puoi usare jQuery, non è attivo l'elenco approvato della XYZ Corporation ". Vanilla JavaScript funziona assolutamente ovunque, ogni volta, e non ti darà mai questo problema. Se fai affidamento su una libreria sì, ottieni velocità e facilità, ma perdi l'universalità.

Inoltre, a proposito di interviste, l'altro aspetto negativo è che se dici che devi usare una libreria per risolvere un problema JavaScript durante un quiz sul codice, si presenta come se non capissi effettivamente il problema, il che sembra un po 'brutto. Considerando che se lo risolvi in ​​JavaScript vaniglia crudo dimostra che in realtà capisci e puoi risolvere ogni parte del problema che ti si presentano.


1

$(this)è diverso da this:

Usando $(this)si garantisce che il prototipo jQuery venga passato sull'oggetto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.