Buscar..
Introducción
JSON (JavaScript Object Notation) es un formato ligero de intercambio de datos. Es fácil para los humanos leer y escribir y fácil para que las máquinas analicen y generen. Es importante darse cuenta de que, en JavaScript, JSON es una cadena y no un objeto.
Se puede encontrar una descripción básica en el sitio web json.org que también contiene enlaces a implementaciones del estándar en muchos lenguajes de programación diferentes.
Sintaxis
- JSON.parse (entrada [, reviver])
- JSON.stringify (valor [, reemplazo [, espacio]])
Parámetros
Parámetro | Detalles |
---|---|
JSON.parse | Analizar una cadena JSON |
input(string) | Cadena JSON para ser analizada. |
reviver(function) | Prescribe una transformación para la cadena JSON de entrada. |
JSON.stringify | Serializar un valor serializable |
value(string) | Valor a ser serializado según la especificación JSON. |
replacer(function o String[] o Number[]) | Incluye selectivamente ciertas propiedades del objeto de value . |
space(String o Number ) | Si un number se proporciona, a continuación, space se insertará el número de espacios en blanco de la legibilidad. Si se proporciona una string , la cadena (primeros 10 caracteres) se utilizará como espacios en blanco. |
Observaciones
Los métodos de utilidad JSON se estandarizaron por primera vez en ECMAScript 5.1 §15.12 .
El formato se definió formalmente en The application / json Media Type para JSON (RFC 4627 julio de 2006), que se actualizó posteriormente en The JSON Data Interchange Format (RFC 7158 de marzo de 2013, ECMA-404 de octubre de 2013 y RFC 7159 de marzo de 2014).
Para que estos métodos estén disponibles en navegadores antiguos como Internet Explorer 8, use json2.js de Douglas Crockford.
Analizar una simple cadena JSON
El método JSON.parse()
analiza una cadena como JSON y devuelve una primitiva, matriz u objeto de JavaScript:
const array = JSON.parse('[1, 2, "c", "d", {"e": false}]');
console.log(array); // logs: [1, 2, "c", "d", {e: false}]
Serializar un valor
Un valor de JavaScript se puede convertir en una cadena JSON utilizando la función JSON.stringify
.
JSON.stringify(value[, replacer[, space]])
-
value
El valor para convertir a una cadena JSON.
/* Boolean */ JSON.stringify(true) // 'true'
/* Number */ JSON.stringify(12) // '12'
/* String */ JSON.stringify('foo') // '"foo"'
/* Object */ JSON.stringify({}) // '{}'
JSON.stringify({foo: 'baz'}) // '{"foo": "baz"}'
/* Array */ JSON.stringify([1, true, 'foo']) // '[1, true, "foo"]'
/* Date */ JSON.stringify(new Date()) // '"2016-08-06T17:25:23.588Z"'
/* Symbol */ JSON.stringify({x:Symbol()}) // '{}'
-
replacer
Una función que altera el comportamiento del proceso de clasificación o una matriz de objetos de Cadena y Número que sirven como una lista blanca para filtrar las propiedades del objeto de valor que se incluirán en la cadena de JSON. Si este valor es nulo o no se proporciona, todas las propiedades del objeto se incluyen en la cadena JSON resultante.
// replacer as a function
function replacer (key, value) {
// Filtering out properties
if (typeof value === "string") {
return
}
return value
}
var foo = { foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7 }
JSON.stringify(foo, replacer)
// -> '{"week": 45, "month": 7}'
// replacer as an array
JSON.stringify(foo, ['foundation', 'week', 'month'])
// -> '{"foundation": "Mozilla", "week": 45, "month": 7}'
// only the `foundation`, `week`, and `month` properties are kept
-
space
Para facilitar la lectura, el número de espacios utilizados para la sangría puede especificarse como el tercer parámetro.
JSON.stringify({x: 1, y: 1}, null, 2) // 2 space characters will be used for indentation
/* output:
{
'x': 1,
'y': 1
}
*/
Alternativamente, se puede proporcionar un valor de cadena para usar para la sangría. Por ejemplo, pasar '\t'
hará que el carácter de la pestaña se use para la sangría.
JSON.stringify({x: 1, y: 1}, null, '\t')
/* output:
{
'x': 1,
'y': 1
}
*/
Serialización con una función sustitutiva.
Se puede usar una función de replacer
para filtrar o transformar los valores que se están serializando.
const userRecords = [
{name: "Joe", points: 14.9, level: 31.5},
{name: "Jane", points: 35.5, level: 74.4},
{name: "Jacob", points: 18.5, level: 41.2},
{name: "Jessie", points: 15.1, level: 28.1},
];
// Remove names and round numbers to integers to anonymize records before sharing
const anonymousReport = JSON.stringify(userRecords, (key, value) =>
key === 'name'
? undefined
: (typeof value === 'number' ? Math.floor(value) : value)
);
Esto produce la siguiente cadena:
'[{"points":14,"level":31},{"points":35,"level":74},{"points":18,"level":41},{"points":15,"level":28}]'
Analizando con una función de revivimiento
Se puede usar una función de recuperación para filtrar o transformar el valor que se está analizando.
var jsonString = '[{"name":"John","score":51},{"name":"Jack","score":17}]';
var data = JSON.parse(jsonString, function reviver(key, value) {
return key === 'name' ? value.toUpperCase() : value;
});
const jsonString = '[{"name":"John","score":51},{"name":"Jack","score":17}]';
const data = JSON.parse(jsonString, (key, value) =>
key === 'name' ? value.toUpperCase() : value
);
Esto produce el siguiente resultado:
[
{
'name': 'JOHN',
'score': 51
},
{
'name': 'JACK',
'score': 17
}
]
Esto es particularmente útil cuando se deben enviar datos que deben ser serializados / codificados cuando se transmiten con JSON, pero uno quiere acceder a ellos deserializados / decodificados. En el siguiente ejemplo, una fecha se codificó en su representación ISO 8601. Usamos la función reviver para analizar esto en una Date
JavaScript.
var jsonString = '{"date":"2016-01-04T23:00:00.000Z"}';
var data = JSON.parse(jsonString, function (key, value) {
return (key === 'date') ? new Date(value) : value;
});
const jsonString = '{"date":"2016-01-04T23:00:00.000Z"}';
const data = JSON.parse(jsonString, (key, value) =>
key === 'date' ? new Date(value) : value
);
Es importante asegurarse de que la función de recuperación devuelve un valor útil al final de cada iteración. Si la función de recuperación devuelve undefined
, ningún valor o la ejecución cae hacia el final de la función, la propiedad se elimina del objeto. De lo contrario, la propiedad se redefine para ser el valor de retorno.
Serialización y restauración de instancias de clase.
Puede usar un método toJSON
personalizado y una función de recuperación para transmitir instancias de su propia clase en JSON. Si un objeto tiene un método toJSON
, su resultado se serializará en lugar del objeto en sí.
function Car(color, speed) {
this.color = color;
this.speed = speed;
}
Car.prototype.toJSON = function() {
return {
$type: 'com.example.Car',
color: this.color,
speed: this.speed
};
};
Car.fromJSON = function(data) {
return new Car(data.color, data.speed);
};
class Car {
constructor(color, speed) {
this.color = color;
this.speed = speed;
this.id_ = Math.random();
}
toJSON() {
return {
$type: 'com.example.Car',
color: this.color,
speed: this.speed
};
}
static fromJSON(data) {
return new Car(data.color, data.speed);
}
}
var userJson = JSON.stringify({
name: "John",
car: new Car('red', 'fast')
});
Esto produce una cadena con el siguiente contenido:
{"name":"John","car":{"$type":"com.example.Car","color":"red","speed":"fast"}}
var userObject = JSON.parse(userJson, function reviver(key, value) {
return (value && value.$type === 'com.example.Car') ? Car.fromJSON(value) : value;
});
Esto produce el siguiente objeto:
{
name: "John",
car: Car {
color: "red",
speed: "fast",
id_: 0.19349242527065402
}
}
Literales de JSON contra JavaScript
JSON significa "notación de objetos de JavaScript", pero no es JavaScript. Piense en ello como sólo un formato de serialización de datos que pasa a ser directamente utilizable como JavaScript literal. Sin embargo, no es recomendable ejecutar directamente (es decir, a través de eval()
) JSON que se obtiene de una fuente externa. Funcionalmente, JSON no es muy diferente de XML o YAML: se puede evitar cierta confusión si JSON se imagina como un formato de serialización que se parece mucho a JavaScript.
Aunque el nombre solo implica objetos, y aunque la mayoría de los casos de uso a través de algún tipo de API siempre son objetos y matrices, JSON no es solo para objetos o matrices. Los siguientes tipos primitivos son compatibles:
- Cadena (por ejemplo,
"Hello World!"
) - Número (ej.
42
) - Booleano (por ejemplo,
true
) - El valor
null
undefined
no se admite en el sentido de que una propiedad no definida se omitirá de JSON tras la serialización. Por lo tanto, no hay forma de deserializar JSON y terminar con una propiedad cuyo valor undefined
esté undefined
.
La cadena "42"
es JSON válida. JSON no siempre tiene que tener un sobre exterior de "{...}"
o "[...]"
.
Si bien nome JSON también es válido de JavaScript y algo de JavaScript también es válido de JSON, existen algunas diferencias sutiles entre ambos idiomas y ninguno de los dos es un subconjunto del otro.
Tome la siguiente cadena JSON como ejemplo:
{"color": "blue"}
Esto se puede insertar directamente en JavaScript. Será sintácticamente válido y dará el valor correcto:
const skin = {"color": "blue"};
Sin embargo, sabemos que "color" es un nombre de identificador válido y las comillas alrededor del nombre de la propiedad se pueden omitir:
const skin = {color: "blue"};
También sabemos que podemos usar comillas simples en lugar de comillas dobles:
const skin = {'color': 'blue'};
Pero, si tomáramos estos dos literales y los tratáramos como JSON, ninguno será JSON sintácticamente válido :
{color: "blue"}
{'color': 'blue'}
JSON exige estrictamente que todos los nombres de propiedades estén entre comillas dobles y que los valores de las cadenas también estén entre comillas dobles.
Es común que los recién llegados a JSON intenten usar extractos de código con literales de JavaScript como JSON, y se sorprendan de los errores de sintaxis que están recibiendo del analizador JSON.
Más confusión comienza a surgir cuando se aplica una terminología incorrecta en el código o en la conversación.
Un antipatrón común es nombrar variables que contienen valores no JSON como "json":
fetch(url).then(function (response) {
const json = JSON.parse(response.data); // Confusion ensues!
// We're done with the notion of "JSON" at this point,
// but the concept stuck with the variable name.
});
En el ejemplo anterior, response.data
es una cadena JSON que es devuelta por alguna API. JSON se detiene en el dominio de respuesta HTTP. La variable con el nombre inapropiado "json" contiene solo un valor de JavaScript (podría ser un objeto, una matriz o incluso un número simple)
Una forma menos confusa de escribir lo anterior es:
fetch(url).then(function (response) {
const value = JSON.parse(response.data);
// We're done with the notion of "JSON" at this point.
// You don't talk about JSON after parsing JSON.
});
Los desarrolladores también tienden a lanzar mucho la frase "objeto JSON". Esto también conduce a la confusión. Debido a que como se mencionó anteriormente, una cadena JSON no tiene que contener un objeto como un valor. "Cadena JSON" es un término mejor. Al igual que "cadena XML" o "cadena YAML". Obtienes una cadena, la analizas y terminas con un valor.
Valores de objeto cíclicos
No todos los objetos se pueden convertir en una cadena JSON. Cuando un objeto tiene autorreferencias cíclicas, la conversión fallará.
Este suele ser el caso de las estructuras de datos jerárquicas en las que tanto el padre como el hijo se hacen referencia entre sí:
const world = {
name: 'World',
regions: []
};
world.regions.push({
name: 'North America',
parent: 'America'
});
console.log(JSON.stringify(world));
// {"name":"World","regions":[{"name":"North America","parent":"America"}]}
world.regions.push({
name: 'Asia',
parent: world
});
console.log(JSON.stringify(world));
// Uncaught TypeError: Converting circular structure to JSON
Tan pronto como el proceso detecta un ciclo, se genera la excepción. Si no hubiera detección de ciclos, la cadena sería infinitamente larga.