非常教程

JavaScript参考手册

JSON

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);

规范

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)

JSON相关

JavaScript

JavaScript 是一种高级编程语言,通过解释执行,是一门动态类型,面向对象(基于原型)的解释型语言。它已经由ECMA(欧洲电脑制造商协会)通过 ECMAScript 实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器( Chrome、IE、FireFox、Safari、Opera )支持。JavaScript 是一门基于原型、函数先行的语言,是一门多范式的语言,它支持面向对象编程,命令式编程,以及函数式编程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持 I/O,比如网络