Avvertenza: per metodi basati suJSON.parse
- Anche le matrici e le virgolette racchiudono le stringhe (es. console.log(JSON.parse('[3]'), JSON.parse('"\uD800"'))
)
Per evitare tutte le primitive JSON non oggetto (booleano, null, array, numero, stringa), suggerisco di utilizzare quanto segue:
/* Validate a possible object ie. o = { "a": 2 } */
const isJSONObject = (o) =>
!!o && (typeof o === 'object') && !Array.isArray(o) &&
(() => { try { return Boolean(JSON.stringify(o)); } catch { return false } })()
/* Validate a possible JSON object represented as string ie. s = '{ "a": 3 }' */
function isJSONObjectString(s) {
try {
const o = JSON.parse(s);
return !!o && (typeof o === 'object') && !Array.isArray(o)
} catch {
return false
}
}
Spiegazione del codice
- !! o - Not falsy (esclude null, che si registra come typeof 'oggetto')
- (typeof o === 'oggetto') - Esclude booleano, numero e stringa
- ! Array.isArray (o) - Escludi matrici (che si registrano come typeof 'oggetto')
- prova ... JSON.stringify / JSON.parse - Chiede al motore JavaScript di determinare se JSON valido
Perché non usare la risposta hasJsonStructure ()?
Contare su toString()
non è una buona idea. Questo perché motori JavaScript diversi possono restituire una rappresentazione di stringa diversa. In generale, i metodi che si basano su questo possono fallire in ambienti diversi o possono essere soggetti a guasti in seguito qualora il motore dovesse mai cambiare il risultato della stringa
Perché catturare un'eccezione non è un hack?
È stato sollevato il fatto che catturare un'eccezione per determinare la validità di qualcosa non è mai la strada giusta da percorrere. Questo è generalmente un buon consiglio, ma non sempre. In questo caso, la rilevazione delle eccezioni è probabilmente la strada migliore perché si basa sull'implementazione del motore JavaScript di convalida dei dati JSON.
Affidarsi al motore JS offre i seguenti vantaggi:
- Più approfondito e continuamente aggiornato con il variare delle specifiche JSON
- Probabilmente correre più veloce (dato che è un codice di livello inferiore)
Quando viene data la possibilità di appoggiarsi al motore JavaScript, suggerirei di farlo. Soprattutto in questo caso. Anche se può sentirsi hacky per intercettare un'eccezione, sei davvero solo gestire due possibili stati di ritorno da un metodo esterno.
eval()
se ritornaundefined
allora, non è JSON