JSON.stringify()
method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
JSON.stringify(value[, replacer[, space]])
value
The value to convert to a JSON string.
replacer
可选
String
and
Number
that serve as an allowlist for selecting/filtering the properties of the value object to be included in the JSON string. If this value is
null
or not provided, all properties of the object are included in the resulting JSON string.
space
可选
String
or
Number
object that's used to insert white space into the output JSON string for readability purposes.
If this is a
Number
, it indicates the number of space characters to use as white space; this number is capped at 10 (if it is greater, the value is just
10
). Values less than 1 indicate that no space should be used.
If this is a
String
, the string (or the first 10 characters of the string, if it's longer than that) is used as white space. If this parameter is not provided (or is
null
), no white space is used.
A JSON string representing the given value.
TypeError
("cyclic object value") exception when a circular reference is found.
TypeError
("BigInt value can't be serialized in JSON") when trying to stringify a
BigInt
值。
JSON.stringify()
converts a value to JSON notation representing it:
toJSON()
method, it's responsible to define what data will be serialized.
布尔
,
Number
,和
String
objects are converted to the corresponding primitive values during stringification, in accord with the traditional conversion semantics.
undefined
,
Function
s, and
Symbol
s are not valid JSON values. If any such values are encountered during conversion they are either omitted (when found in an object) or changed to
null
(when found in an array).
JSON.stringify()
can return
undefined
when passing in "pure" values like
JSON.stringify(function(){})
or
JSON.stringify(undefined)
.
Symbol
-keyed properties will be completely ignored, even when using the
replacer
函数。
Date
implement the
toJSON()
function by returning a string (the same as
date.toISOString()
). Thus, they are treated as strings.
Infinity
and
NaN
, as well as the value
null
, are all considered
null
.
Object
instances (including
Map
,
Set
,
WeakMap
,和
WeakSet
) will have only their enumerable properties serialized.
JSON.stringify({}); // '{}'
JSON.stringify(true); // 'true'
JSON.stringify('foo'); // '"foo"'
JSON.stringify([1, 'false', false]); // '[1,"false",false]'
JSON.stringify([NaN, null, Infinity]); // '[null,null,null]'
JSON.stringify({ x: 5 }); // '{"x":5}'
JSON.stringify(new Date(2006, 0, 2, 15, 4, 5))
// '"2006-01-02T15:04:05.000Z"'
JSON.stringify({ x: 5, y: 6 });
// '{"x":5,"y":6}'
JSON.stringify([new Number(3), new String('false'), new Boolean(false)]);
// '[3,"false",false]'
// String-keyed array elements are not enumerable and make no sense in JSON
let a = ['foo', 'bar'];
a['baz'] = 'quux'; // a: [ 0: 'foo', 1: 'bar', baz: 'quux' ]
JSON.stringify(a);
// '["foo","bar"]'
JSON.stringify({ x: [10, undefined, function(){}, Symbol('')] });
// '{"x":[10,null,null,null]}'
// Standard data structures
JSON.stringify([new Set([1]), new Map([[1, 2]]), new WeakSet([{a: 1}]), new WeakMap([[{a: 1}, 2]])]);
// '[{},{},{},{}]'
// TypedArray
JSON.stringify([new Int8Array([1]), new Int16Array([1]), new Int32Array([1])]);
// '[{"0":1},{"0":1},{"0":1}]'
JSON.stringify([new Uint8Array([1]), new Uint8ClampedArray([1]), new Uint16Array([1]), new Uint32Array([1])]);
// '[{"0":1},{"0":1},{"0":1},{"0":1}]'
JSON.stringify([new Float32Array([1]), new Float64Array([1])]);
// '[{"0":1},{"0":1}]'
// toJSON()
JSON.stringify({ x: 5, y: 6, toJSON(){ return this.x + this.y; } });
// '11'
// Symbols:
JSON.stringify({ x: undefined, y: Object, z: Symbol('') });
// '{}'
JSON.stringify({ [Symbol('foo')]: 'foo' });
// '{}'
JSON.stringify({ [Symbol.for('foo')]: 'foo' }, [Symbol.for('foo')]);
// '{}'
JSON.stringify({ [Symbol.for('foo')]: 'foo' }, function(k, v) {
if (typeof k === 'symbol') {
return 'a symbol';
}
});
// undefined
// Non-enumerable properties:
JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } }) );
// '{"y":"y"}'
// BigInt values throw
JSON.stringify({x: 2n});
// TypeError: BigInt value can't be serialized in JSON
replacer
parameter
replacer
parameter can be either a function or an array.
As a function
, it takes two parameters: the
key
和
value
being stringified. The object in which the key was found is provided as the replacer's
this
参数。
Initially, the
replacer
function is called with an empty string as key representing the object being stringified. It is then called for each property on the object or array being stringified.
It should return the value that should be added to the JSON string, as follows:
Number
,
String
,
布尔
,或
null
, the stringified version of that value is
used as the property's value.
Function
,
Symbol
, or
undefined
, the property is not included in the output.
replacer
function on each property.
注意:
You cannot use the
replacer
function to remove values from an array. If you return
undefined
or a function then
null
is used instead.
注意: If you wish the replacer to distinguish an initial object from a key with an empty string property (since both would give the empty string as key and potentially an object as value), you will have to keep track of the iteration count (if it is beyond the first iteration, it is a genuine empty string key).
function replacer(key, value) {
// Filtering out properties
if (typeof value === 'string') {
return undefined;
}
return value;
}
var foo = {foundation: 'Mozilla', model: 'box', week: 45, transport: 'car', month: 7};
JSON.stringify(foo, replacer);
// '{"week":45,"month":7}'
若
replacer
is an array, the array's values indicate the names of the properties in the object that should be included in the resulting JSON string.
JSON.stringify(foo, ['week', 'month']);
// '{"week":45,"month":7}', only keep "week" and "month" properties
space
argument
space
argument may be used to control spacing in the final string.
JSON.stringify({ a: 2 }, null, ' ');
// '{
// "a": 2
// }'
Using a tab character mimics standard pretty-print appearance:
JSON.stringify({ uno: 1, dos: 2 }, null, '\t');
// returns the string:
// '{
// "uno": 1,
// "dos": 2
// }'
toJSON()
behavior
If an object being stringified has a property named
toJSON
whose value is a function, then the
toJSON()
method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the
toJSON()
method when called will be serialized.
JSON.stringify()
calls
toJSON
with one parameter:
JSON.stringify()
was directly called on this object
例如:
var obj = {
data: 'data',
toJSON (key) {
if (key)
return `Now I am a nested object under key '${key}'`;
else
return this;
}
};
JSON.stringify(obj);
// '{"data":"data"}'
JSON.stringify({ obj }); // Shorthand property names (ES2015).
// '{"obj":"Now I am a nested object under key 'obj'"}'
JSON.stringify([ obj ]);
// '["Now I am a nested object under key '0'"]'
JSON.stringify()
when serializing circular references
Note that since the
JSON format
doesn't support object references (although an
IETF draft exists
), a
TypeError
will be thrown if one attempts to encode an object with circular references.
const circularReference = {};
circularReference.myself = circularReference;
// Serializing circular references throws "TypeError: cyclic object value"
JSON.stringify(circularReference);
To serialize circular references you can use a library that supports them (e.g. cycle.js by Douglas Crockford) or implement a solution by yourself, which will require finding and replacing (or removing) the cyclic references by serializable values.
JSON.stringify
for use as JavaScript
Historically, JSON was
not a completely strict subset of JavaScript
. The literal code points U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR could appear literally in string literals and property names in JSON text. But they could not appear literally in similar context in JavaScript text, only using Unicode escapes as
\u2028
and
\u2029
. This recently changed: now both code points may appear literally in strings in JSON and JavaScript both.
Therefore, if compatibility with older JavaScript engines is required, it is perilous to directly substitute the string returned by
JSON.stringify
into a JavaScript string to be passed to
eval
or
new Function
or as part of a
JSONP
URL, and the following utility can be used:
function jsFriendlyJSONStringify (s) {
return JSON.stringify(s).
replace(/\u2028/g, '\\u2028').
replace(/\u2029/g, '\\u2029');
}
var s = {
a: String.fromCharCode(0x2028),
b: String.fromCharCode(0x2029)
};
try {
eval('(' + JSON.stringify(s) + ')');
} catch (e) {
console.log(e); // "SyntaxError: unterminated string literal"
}
// No need for a catch
eval('(' + jsFriendlyJSONStringify(s) + ')');
// console.log in Firefox unescapes the Unicode if
// logged to console, so we use alert
alert(jsFriendlyJSONStringify(s)); // {"a":"\u2028","b":"\u2029"}
注意 : Properties of non-array objects are not guaranteed to be stringified in any particular order. Do not rely on ordering of properties within the same object within the stringification.
var a = JSON.stringify({ foo: "bar", baz: "quux" })
//'{"foo":"bar","baz":"quux"}'
var b = JSON.stringify({ baz: "quux", foo: "bar" })
//'{"baz":"quux","foo":"bar"}'
console.log(a !== b) // true
// some memoization functions use JSON.stringify to serialize arguments,
// which may cause a cache miss when encountering the same object like above
JSON.stringify()
with
localStorage
In a case where you want to store an object created by your user and allowing it to be restored even after the browser has been closed, the following example is a model for the applicability of
JSON.stringify()
:
// Creating an example of JSON
var session = {
'screens': [],
'state': true
};
session.screens.push({ 'name': 'screenA', 'width': 450, 'height': 250 });
session.screens.push({ 'name': 'screenB', 'width': 650, 'height': 350 });
session.screens.push({ 'name': 'screenC', 'width': 750, 'height': 120 });
session.screens.push({ 'name': 'screenD', 'width': 250, 'height': 60 });
session.screens.push({ 'name': 'screenE', 'width': 390, 'height': 120 });
session.screens.push({ 'name': 'screenF', 'width': 1240, 'height': 650 });
// Converting the JSON string with JSON.stringify()
// then saving with localStorage in the name of session
localStorage.setItem('session', JSON.stringify(session));
// Example of how to transform the String generated through
// JSON.stringify() and saved in localStorage in JSON object again
var restoredSession = JSON.parse(localStorage.getItem('session'));
// Now restoredSession variable contains the object that was saved
// in localStorage
console.log(restoredSession);
JSON.stringify()
Engines implementing the
well-formed JSON.stringify specification
will stringify lone surrogates, any code point from U+D800 to U+DFFF, using Unicode escape sequences rather than literally. Before this change
JSON.stringify
would output lone surrogates if the input contained any lone surrogates; such strings could not be encoded in valid UTF-8 or UTF-16:
JSON.stringify("\uD800"); // '"�"'
But with this change
JSON.stringify
represents lone surrogates using JSON escape sequences that
can
be encoded in valid UTF-8 or UTF-16:
JSON.stringify("\uD800"); // '"\\ud800"'
This change should be backwards-compatible as long as you pass the result of
JSON.stringify
to APIs such as
JSON.parse
that will accept any valid JSON text, because they will treat Unicode escapes of lone surrogates as identical to the lone surrogates themselves.
Only
if you are directly interpreting the result of
JSON.stringify
do you need to carefully handle
JSON.stringify
's two possible encodings of these code points.
| 规范 |
|---|
|
ECMAScript (ECMA-262)
The definition of 'JSON.stringify' in that specification. |
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
stringify
|
Chrome 3 | Edge 12 | Firefox 3.5 | IE 8 | Opera 10.5 | Safari 4 | WebView Android ≤37 | Chrome Android 18 | Firefox Android 4 | Opera Android 11 | Safari iOS 4 | Samsung Internet Android 1.0 | nodejs 0.1.100 |
| Well-formed JSON.stringify | Chrome 72 | Edge 79 | Firefox 64 | IE No | Opera 60 | Safari 12.1 | WebView Android 72 | Chrome Android 72 | Firefox Android 64 | Opera Android 50 | Safari iOS 12.2 | Samsung Internet Android No | nodejs No |
完整支持
不支持
JSON.parse()
JSON.decycle
and
JSON.retrocycle
. These allow encoding and decoding of cyclical structures and DAGs into an extended and retrocompatible JSON format.
JSON
JSON.parse()
JSON.stringify()
Object
Object.prototype.__defineGetter__()
Object.prototype.__defineSetter__()
Object.prototype.__lookupGetter__()
Object.prototype.__lookupSetter__()
Object.prototype.hasOwnProperty()
Object.prototype.isPrototypeOf()
Object.prototype.propertyIsEnumerable()
Object.prototype.toLocaleString()
Object.prototype.toSource()
Object.prototype.toString()
Object.prototype.valueOf()
Object.setPrototypeOf()