2012-03-11 12 views
13

jQuery ha un ottimo metodo extend, che unisce 2 oggetti in uno.Perché passare un oggetto vuoto al metodo di estensione di jQuery?

Sulla jQuery Plugins authoring page che mostrano un esempio come segue:

var settings = $.extend({ 
    'location'   : 'top', 
    'background-color' : 'blue' 
}, options); 

Tuttavia, ho visto molti plugin passano un oggetto vuoto come primo parametro, in questo modo:

var settings = $.extend({}, { 
    'location'   : 'top', 
    'background-color' : 'blue' 
}, options); 

quanto come posso dire, questi due fanno esattamente la stessa cosa. L'unica differenza sarebbe se il defaults sarebbe stato memorizzato nella propria variabile:

var defaults = { 
    'location'   : 'top', 
    'background-color' : 'blue' 
}, 
settings = $.extend({}, defaults, options); 

In questo modo, è sempre possibile accedere ai valori di default senza che vengano sovrascritti dal options.


Ecco la domanda: Perché così tanti autori di plugin scelgono di passare un oggetto vuoto per extend, anche quando non memorizzare le impostazioni predefinite in una variabile?

Mi manca qualcosa?

+1

sembra inutile per me. Sta facendo un popolato, copiandolo in uno vuoto e scartandolo. Il tuo terzo esempio mostra un motivo valido. Immagino che le persone lo facciano perché non pensano a quello che stanno facendo. –

+0

@amnotiam Questo è esattamente quello che sto pensando, ma ho visto * tanti plug-in * fare questo. Chiaramente mi manca qualcosa ... –

+0

No, penso che il problema sia che stai * ricevendo * qualcosa. –

risposta

8

motivi possibili (per il secondo esempio) ...

  • ignoranza Inherited ...(lo vide fatto in questo modo, e copiato la pratica)

  • ignoranza intrinseca ... (lo vide fatto correttamente, come nel blocco di codice scorso, ma sostituito l'oggetto in cache con un oggetto on-the-fly e non sapeva che l'oggetto vuoto dovrebbe essere rimosso)

  • Riscaldamento globale.

  • La mancanza di attenzione per i dettagli ... (simile al punto 2, sa che non è necessario, ma mai veramente preso il tempo di esaminare il codice)

  • raffreddamento globale.

  • codifica eccessivamente difensivo ... (paura che i default possono un giorno essere rielaborato in un oggetto riutilizzabile, e teme che l'oggetto vuoto non verrà inserito in quel momento)

  • sviluppatori jQuery fai sempre quello che le voci dicono loro ;-)

Nel complesso, hai ragione. L'oggetto centrale viene creato, copiato su un oggetto vuoto, quindi scartato. È una pratica inutile e dispendiosa.

9

Estendi è una funzione molto utile per copiare oggetti.

Ad esempio si consideri questo:

foo = {'foo':'a'} 
f = foo 
f.foo = 'hello' 
console.log(f) 
    Object {foo="hello"} 
console.log(foo) 
    Object {foo="hello"} 

f = $.extend({},foo) 
f.foo = 'hello world' 
console.log(f) 
    Object {foo="hello world"} 
console.log(foo) 
    Object {foo="hello"} 

Quindi, come potete vedere $ .extend in realtà copiato l'oggetto.

EDIT

Il motivo per cui il primo parametro deve essere un oggetto vuoto è causa di come funziona extend. Ecco come jQuery definisce extend:

jQuery.extend(target [, object1] [, objectN]) 
    target An object that will receive the new properties 
      if additional objects are passed in or that will 
      extend the jQuery namespace if it is the sole argument. 
    object1 An object containing additional properties to merge in. 
    objectN Additional objects containing properties to merge in. 

E inoltre questa frase è importante:

Tenete a mente che l'oggetto di destinazione (primo argomento) sarà modificato, e sarà anche tornato da $ .estendere().

Quindi passando lo {} come primo parametro, tale oggetto vuoto viene esteso e quindi restituito.

Torna al tuo esempio di settings = $.extend({}, defaults, options);. Se lo cambi in settings = $.extend(defaults, options);, le impostazioni saranno identiche, tuttavia qui verranno modificate anche le impostazioni predefinite. Ecco perché è necessario il primo argomento per essere {}.

+0

Grazie per il tuo aggiornamento, ma questo è esattamente quello che ho descritto nella mia domanda. Capisco il vantaggio di utilizzare un oggetto vuoto nel mio terzo esempio. Quello che sto cercando di capire è la differenza tra il mio primo e il secondo esempio ... –

+0

Immagino di non aver seguito la tua domanda. Mi piace la risposta del wiki della comunità sul motivo per cui alla gente piace scrivere l'esempio n. – miki725

+0

Finalmente ho capito che hai ragione quando rovino accidentalmente il mio primo oggetto in "$ .extend {}" che non mi aspetto che cambi. – jasonslyvia

3

Un altro modo di mettere quello che miki ha detto:

var defaults = { 
    one: 'foo', 
    two: 'bar' 
}; 

var options = { 
    two: 'apples', 
    three: 'bananas' 
}; 

// The safe way to extend 
var settings = $.extend({}, defaults, options); 

console.log(settings); // {one: 'foo', two: 'apples', three: 'bananas'} 
console.log(defaults); // {one: 'foo', two: 'bar'} 
console.log(options); // {two: 'apples', three: 'bananas'} 
console.log(settings === defaults); // false 

// Careless way to extend 
var settings = $.extend(defaults, options); 

console.log(settings); // {one: 'foo', two: 'apples', three: 'bananas'} 
console.log(defaults); // {one: 'foo', two: 'apples', three: 'bananas'} 
console.log(options); // {two: 'apples', three: 'bananas'} 
console.log(settings === defaults); // true 
+0

Ancora, questo è esattamente ciò che ho delineato nella mia domanda. Vedi il mio terzo pezzo di codice (e il suo paragrafo precedente). –

+0

Immagino di non capire che tu sia una domanda allora. Mi chiedi: perché così tanti autori di plug-in scelgono di passare un oggetto vuoto da estendere? La mia risposta è probabilmente perché. Memorizzare i valori predefiniti in una variabile non impedirà che vengano sovrascritti. – ianstarz

+0

La mia domanda è: perché così tanti autori di plug-in scelgono di passare un oggetto vuoto per estendere * anche se non memorizzano i valori di default in una variabile *? Ho aggiornato la mia domanda per chiarirlo. –

Problemi correlati