JSON.stringify

JSON.stringify

JSON.stringify()方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,如果指定了replacer是一个函数,则可以替换值,或者如果指定了replacer是一个数组,可选的仅包括指定的属性。

语法

JSON.stringify(value[, replacer[, space]])

参数

value要转换为JSON字符串的值。replacerOptionalA函数改变字符串化过程的行为,或阵列StringNumber充当用于选择/过滤值对象的属性被包括在JSON字符串的白名单的对象。如果此值为空或未提供,则该对象的所有属性都将包含在生成的JSON字符串中。space可选的A StringNumber用于将空白插入输出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

规范

SpecificationStatusComment
ECMAScript 5.1 (ECMA-262)The definition of 'JSON.stringify' in that specification.StandardInitial 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

浏览器兼容性

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Basic Support(Yes)(Yes)3.5810.54

FeatureAndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
Basic Support(Yes)(Yes)(Yes)1(Yes)(Yes)(Yes)