2009-06-29 8 views
6

Avvia la tua console firebug e prova questo.È giusto? Un bug jQuery che cancella l'archivio dati?

confrontare questo:

$('body').data('x',1); 
$(thisx).remove(); 
console.log($('body').data('x')); 

a questo:

$('body').data('x',1); 
$(this.x).remove(); 
console.log($('body').data('x')); 

notare la differenza? Se thisx non è definito, verrà immediatamente generato un errore di riferimento. Se x è una proprietà non definita di this, jQuery restituirà il documento come invece il suo set di risultati. JQuery successivo tenterà di rimuovere il documento (che non può), ma prima di farlo rimuoverà tutti i dati associati a qualsiasi elemento figlio del documento. Quindi, cancellando il tuo archivio dati.

Nota: this può essere qualsiasi riferimento di elemento o oggetto. Devi solo provare jQuery per accedere a una proprietà non definita.

(Parla di un dolore, fallisce silenziosamente, e sto cercando di capire perché i miei dati sono improvvisamente assenti, lo rintraccio in un caso speciale in cui un riferimento di elemento non era definito in una situazione specifica).

Così via alle mie domande:

1) Prima di segnalare un bug, sono io analizzando correttamente questo? Inoltre, se qualcuno capisce che questo è un problema noto, fammi sapere. Non sono riuscito a trovarlo nel bug tracker, ma l'interfaccia non è eccezionale (o forse ho sbagliato).

2) Perché alla fine c'è qualche differenza? Sto indovinando thisx viene valutato immediatamente che causa l'eccezione mentre this.x è un riferimento che viene passato e valutato nella funzione chiamata, giusto? (dove penso sia la causa selector = selector || document;

3) Suggerimenti su come gestirlo? Immagino che dovrei controllare che ogni ogni/ogni elemento di riferimento o proprietà di un oggetto (ad esempio stringhe di selettore memorizzate) sia definito prima di passarlo a jQuery quando si rimuove qualcosa.

risposta

3

Perché c'è infine qualche differenza?

Sia thisx e this.x vengono valutate quando viene chiamata la funzione. Il primo si riferisce a un nome di variabile non definito e questo genera un errore di riferimento. Il secondo accede a una proprietà non definita di un oggetto, che risulta nel valore undefined. Questo è il modo in cui javascript si comporta in questi casi.

Ora, quando JQuery viene chiamato nel secondo caso, la chiamata restituisce $(undefined), che equivale a se fosse stato chiamato $(). Dal momento che guarda a JQuery come se non fosse stato fornito alcun argomento, utilizza invece un valore predefinito, e in questo caso il valore predefinito è document. Quindi procede cercando di eliminare document, poiché è stato effettivamente chiamato come $().remove(), nel qual caso ci si aspetterebbe.

Suggerimenti su come gestirlo?

La differenza con lo ReferenceError è una differenza Javascript fondamentale, non molto da fare al riguardo. Il comportamento di JQuerys è sfortunato e una conseguenza dell'impostazione delle impostazioni predefinite da arg = arg||default. Si potrebbe usare l'utente arguments.length per ottenere il numero reale di parametri di chiamata, ma una modifica come questa comporterebbe sicuramente un sacco di codice rotto che si basava sull'impostazione predefinita utilizzata quando viene passato undefined o 0, quindi è improbabile che accada.

3

Provate a digitare questi nella console troppo (senza variabili aggiuntive definite in anticipo):

> a 
    ReferenceError: Can't find variable: a 
> b = {} 
    Object 
> b.a 
    undefined 

uno è un errore di javascript, si ritorna in silenzio indefinito (che jQuery interpreterà come $() perché JavaScript e jQuery può' t dire le funzioni a parte)

questo è il modo in cui funziona javascript, bug o funzionalità che lascio aperto al dibattito, ma non penso che questo sia colpa o problema di jQuery.

modifica: perché jQuery ha $() definito?

Dalla documentazione:

Per impostazione predefinita, se non viene specificato alcun contesto, $() cerca elementi DOM all'interno del contesto del documento HTML corrente. Se si specifica un contesto, ad esempio un elemento DOM o un oggetto jQuery, l'espressione verrà confrontata con i contenuti di di quel contesto.

modificare: i documenti si riferivano all'argomento contesto passato a $(), di non chiamare $() senza argomenti, quindi non è qui rilevante.

Si noti inoltre che

$().get(0) == $("").get(0) 
+0

Penso che diventi problematico quando undefined diventa l'elemento del documento. Ci sono altri casi in cui questo è utile in jQuery? –

+0

Hmm .... Mi chiedo se potrebbe essere meglio gestito dove $ ('') è usato per quel caso. Non che lo cambiassero ora per ragioni ereditarie. Ancora il codice potrebbe distinguere tra una stringa vuota e un valore non definito. Potrebbe anche controllare la lunghezza degli argomenti. Un valore non definito avrebbe ancora un argomento. Lunghezza == 1 mentre $() sarebbe 0, giusto? –

+0

ah, buon punto. non ha pensato alla variabile argomenti. – cobbal

Problemi correlati