questa immagine javascript è un pattern predefinito?

7

In qualche codice javascript sto lavorando al refactoring Ho gestito casi in cui volevo impostare come predefinito una proprietà dell'oggetto su true senza dover passare attraverso il code-base e aggiungere la proprietà a ogni istanza dell'oggetto facendo qualcosa così:

if(typeof(thisBool) === 'undefined' || thisBool) {
    //do cool stuff here;
}

quindi per le istanze esistenti ho dovuto solo correggere il modello nei casi in cui volevo impostare thisBool su un valore calcolato altrove, o impostarlo su false; se è stato disattivato, questo codice lo ha trattato come vero.

Gli oggetti vengono creati dinamicamente quando usati - non sono classi definite, ma sono "istanziati" qualcosa del genere:

var thing1 = {
    Name: 'thing No 1',
    HasCat: false,
    [thisBool: true]
};

e thing1 viene passato alla funzione

Questa è una pessima idea? Sto aggiornando quel codice (e tutte le istanze) quindi ora è il momento di sistemarlo, se è un odore di codice.

Per parte mia preferirei essere più esplicito, ma vedo anche il valore nel non dover fornire un thisBool: true in centinaia di posti, dove per impostazione predefinita thisBool dovrebbe essere true. C'è un modo migliore per raggiungere questo obiettivo?

    
posta cori 04.01.2013 - 18:43
fonte

3 risposte

8

Supponendo che questo sia un argomento di funzione non è necessario usare typeof poiché la variabile sarà sempre presente. Il modo più semplice e pulito per renderlo predefinito su true è questo:

if(thisBool === undefined || thisBool)

Ovviamente ciò potrebbe essere un po 'più esplicito:

if(thisBool === undefined) {
    thisBool = true;
}

if(thisBool) { ... }
    
risposta data 04.01.2013 - 18:46
fonte
0

Non penso che ci sia qualcosa di terribilmente sbagliato nelle dichiarazioni if fornite. Non è un grosso problema, ma non sono un fan di avere un metodo al di fuori di quell'oggetto istanziato che determina i valori predefiniti per quell'oggetto. Non conosco il codice base, quindi non posso dirvi se vale la pena rifattorizzare.

Se stai scrivendo qualcosa da zero, ti suggerirei di utilizzare l'ereditarietà per definire proprietà predefinite come bool stringhe e numeri.

function Thing(config) {
    for(key in config) {
        this[key] = config[key];
    }
}

Thing.prototype.bool = true;

new Thing().bool
>> true

new Thing({bool: false}).bool
>>false

Inoltre sarebbe abbastanza facile integrare l'oggetto Thing nella base di codice esistente. Invece di:

var thing1 = {
    Name: 'thing No 1',
    HasCat: false,
    [thisBool: true]
};

Sarebbe:

var thing1 = new Thing({
    Name: 'thing No 1',
    HasCat: false
});
    
risposta data 17.05.2013 - 15:59
fonte
0

thing oggetti dovrebbe essere responsabile per l'impostazione dei propri valori predefiniti. Se imponi ad altre funzioni di sapere che il valore predefinito per thisBool è true, il codice diventa più difficile da comprendere. Inoltre, corri il rischio che qualcuno possa aggiungere una nuova funzione ma non sapere che thisBool dovrebbe essere true per impostazione predefinita.

Di seguito è il mio suggerimento per una funzione simile al costruttore.

var createThing = function () {
  var myThing = {};
  myThing.thisBool = true;
  return myThing;
};

var thing1 = createThing();
thing1.name = "thing no 1";
...

Su una nota pragmatica, potrebbe non essere fattibile per te apportare le modifiche sopra descritte. Se hai migliaia di oggetti delle cose, un paio di funzioni e una mancanza di giustificazione per cambiare tutti gli oggetti delle cose, potresti aver bisogno di un'altra soluzione.

Un'opzione ti consente di cambiare la semantica di questo oggetto in modo che il valore predefinito sia falso. Poiché le proprietà non sono definite per impostazione predefinita e indefinite sono false, si ridurrebbe il rischio di sorprendenti programmatori futuri.

if (notThisBool) {  // hopefully you have better semantics than notThisBool
  // do special case
} else {
  // do default case
}

Come ultima risorsa, suggerirei che la funzione controlli esattamente la falsità e includa un commento che spieghi perché.

// check for exactly false because thisBool is an optional property
// that should be considered true unless it is set to false
if (myThing.thisBool === false) {
  // special case
} else {
  // default case
}

Mi rendo conto che "non esattamente falso" è leggermente diverso da "indefinito o veritiero". (Nel mio codice precedente un valore falso diverso da "false" avrebbe eseguito il caso predefinito). Penso che il mio codice sia più chiaro.

    
risposta data 17.05.2013 - 18:02
fonte

Leggi altre domande sui tag