JSON.stringify
JSON.stringify
JSON.stringify()
方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,如果指定了replacer是一个函数,则可以替换值,或者如果指定了replacer是一个数组,可选的仅包括指定的属性。
语法
JSON.stringify(value[, replacer[, space]])
参数
value
要转换为JSON字符串的值。replacer
OptionalA函数改变字符串化过程的行为,或阵列String
和Number
充当用于选择/过滤值对象的属性被包括在JSON字符串的白名单的对象。如果此值为空或未提供,则该对象的所有属性都将包含在生成的JSON字符串中。space
可选的A String
或Number
用于将空白插入输出JSON字符串以便可读性的对象。如果这是a Number
,则表示要用作空白的空格字符数; 这个数字被限制在10(如果它更大,那么这个值就是10)。值小于1表示不应该使用空格。如果这是一个String
,字符串(或字符串的前10个字符,如果它比这更长)用作空白。如果未提供此参数(或为空),则不使用空格。
返回值
一个表示给定值的JSON字符串。
描述
关于序列化,有下面五点注意事项:
- 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。
undefined、
任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成null
(出现在数组中时)。
- 所有以 symbol 为属性键的属性都会被完全忽略掉,即便
replacer
参数中强制指定包含了它们。
- 不可枚举的属性会被忽略
JSON.stringify{} // '{}'
JSON.stringify(true // 'true'
JSON.stringify('foo' // '"foo"'
JSON.stringify([1, 'false', false] // '[1,"false",false]'
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)]
// '[1,"false",false]'
JSON.stringify{ x: [10, undefined, function(){}, Symbol('')] }
// '{"x":[10,null,null,null]}'
// 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';
}
}
// '{}'
// Non-enumerable properties:
JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } })
// '{"y":"y"}'
replacer参数
replacer参数可以是一个函数或者一个数组。作为函数,它有两个参数,键(key)值(value)都会被序列化。
- 如果返回a
Number
,则添加到JSON字符串时,与该数字对应的字符串将用作该属性的值。
- 如果返回a
String
,那么在将该字符串添加到JSON字符串时,该字符串将用作该属性的值。
- 如果返回a
Boolean
,则在将其添加到JSON字符串时,会将“true”或“false”用作属性的值。
- 如果返回任何其他对象,该对象递归地序列化成JSON字符串,对每个属性调用replacer方法。除非该对象是一个函数,这种情况将不会被序列化成JSON字符串。
- 如果返回
undefined
,该属性值不会在JSON字符串中输出。
注意:
不能用replacer方法,从数组中移除值(values),如若返回undefined或者一个函数,将会被null取代。
例子(function)
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}'
例子(array)
如果replacer是一个数组,数组的值代表将被序列化成JSON字符串的属性名。
JSON.stringify(foo, ['week', 'month']
// '{"week":45,"month":7}', only keep "week" and "month" properties
space 参数
space
参数用来控制结果字符串里面的间距。如果是一个数字, 则在字符串化时每一级别会比上一级别缩进多这个数字值的空格(最多10个空格);如果是一个字符串,则每一级别会比上一级别多缩进用该字符串(或该字符串的前十个字符)。
JSON.stringify{ a: 2 }, null, ' '
// '{
// "a": 2
// }'
使用制表符(\t)来缩进:
JSON.stringify{ uno: 1, dos: 2 }, null, '\t'
// returns the string:
// '{
// "uno": 1,
// "dos": 2
// }'
toJSON() 操作
如果一个被序列化的对象拥有toJSON
方法,那么该toJSON
方法就会覆盖该对象默认的序列化行为:不是那个对象被序列化,而是调用toJSON
方法后的返回值会被序列化,例如:
- 如果这个对象是属性值,则为属性名称
- 如果它是一个数组中的索引,则作为一个字符串
- 如果直接在此对象上调用JSON.stringify,则为空字符串
例如:
var obj = {
foo: 'foo',
toJSON: function() {
return 'bar';
}
};
JSON.stringify(obj // '"bar"'
JSON.stringify{ x: obj } // '{"x":"bar"}'
var obj2 = {
foo: 'foo',
toJSON: function(key) {
if (key === '') {
return 'bar only';
} else {
return 'bar in ' + key;
}
}
};
JSON.stringify(obj2 // '"bar only"'
JSON.stringify{ x: obj2 } // '{ "x":"bar in x"}'
JSON.stringify([obj2, obj2] // '["bar in 0", "bar in 1"]'
JSON.stringify用作 JavaScript
注意JSON不是javascript严格意义上的子集,在JSON中不需要省略两条终线(Line separator和Paragraph separator)但在JavaScript中需要被省略。因此,如果JSON被用作JSONP时,下面方法可以使用:
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"}
使用 JSON.stringify 结合 localStorage 的例子
一些时候,你想存储用户创建的一个对象,并且,即使在浏览器被关闭后仍能恢复该对象。下面的例子是JSON.stringify
适用于这种情形的一个样板:
函数不是有效的JSON数据类型因此它们不工作。但是,如果首先通过函数的toString方法将其转换为字符串(例如在替换器中),则可以显示它们。另外,像一些对象Date
将会是JSON.parse()
之后的一个字符串。
// 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
规范
Specification | Status | Comment |
---|---|---|
ECMAScript 5.1 (ECMA-262)The definition of 'JSON.stringify' in that specification. | Standard | Initial definition. Implemented in JavaScript 1.7. |
ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'JSON.stringify' in that specification. | Standard | |
ECMAScript Latest Draft (ECMA-262)The definition of 'JSON.stringify' in that specification. | Living Standard | |
浏览器兼容性
Feature | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic Support | (Yes) | (Yes) | 3.5 | 8 | 10.5 | 4 |
Feature | Android | Chrome for Android | Edge mobile | Firefox for Android | IE mobile | Opera Android | iOS Safari |
---|---|---|---|---|---|---|---|
Basic Support | (Yes) | (Yes) | (Yes) | 1 | (Yes) | (Yes) | (Yes) |