Advertencia: para los métodos en los que se confía JSON.parse
: las matrices y las cadenas entre comillas también pasarán (es decir console.log(JSON.parse('[3]'), JSON.parse('"\uD800"'))
) .
Para evitar todas las primitivas JSON que no sean objetos (booleano, nulo, matriz, número, cadena), sugiero usar lo siguiente:
/* 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
}
}
Explicación del código
- !! o - No es falso (excluye nulo, que se registra como tipo de 'objeto')
- (typeof o === 'objeto') - Excluye booleano, número y cadena
- ! Array.isArray (o) - Excluir matrices (que se registran como typeof 'object')
- intente ... JSON.stringify / JSON.parse - Pregunta al motor de JavaScript para determinar si JSON es válido
¿Por qué no usar la respuesta hasJsonStructure ()?
Confiar en toString()
no es una buena idea. Esto se debe a que diferentes motores de JavaScript pueden devolver una representación de cadena diferente. En general, los métodos que dependen de esto pueden fallar en diferentes entornos o pueden estar sujetos a fallar más tarde si el motor cambia el resultado de la cadena
¿Por qué atrapar una excepción no es un truco?
Se mencionó que atrapar una excepción para determinar la validez de algo nunca es el camino correcto. Este es generalmente un buen consejo, pero no siempre. En este caso, es probable que la captura de excepciones sea la mejor ruta porque se basa en la implementación del motor JavaScript para validar los datos JSON.
Confiar en el motor JS ofrece las siguientes ventajas:
- Más exhaustivo y continuamente actualizado a medida que cambian las especificaciones JSON
- Es probable que corra más rápido (ya que es un código de nivel inferior)
Cuando tenga la oportunidad de apoyarse en el motor de JavaScript, sugeriría hacerlo. Particularmente en este caso. Aunque puede parecer extraño detectar una excepción, en realidad solo está manejando dos posibles estados de retorno de un método externo.
eval()
si vuelveundefined
, entonces no es JSON