We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

Метод JSON.stringify() подає об'єкт чи просту величину як JSON-рядок, певним чином перетворюючи або оминаючи ті чи ті властивості, якщо вказано необов'язковий другий аргумент — функцію або масив replacer.

Синтаксис

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

Параметри

value
Значення, яке слід перетворити на рядок JSON.
replacer Optional
Функція, що змінює значення перед їхнім перетворенням на JSON, або масив рядків та чисел, що окреслюють множину властивостей, які буде включено у створений JSON-рядок. Якщо цей аргумент відсутній чи вказано null, до створеного JSON-рядка потраплять всі наявні властивості об'єкта без змін.
space Optional
Значення типу String або Number що використовується для додавання відступів у JSON задля покращення легкочитності. Якщо вказано число — воно означає кількість пропусків в одному відступі. Якщо передати число більше за 10, буде використано 10. Значення менші за 1 вказують на те що відступи не використовуватимуться. Якщо вказано рядок, то його (або перші 10 символів, якщо він задовгий) буде використано як відступ. Якщо ж параметр не вказано (або null), відступи не додаватимуться.

Вертає

Рядок JSON, створений із вказаного значення.

Опис

Функція JSON.stringify() перетворює значення на рядок, що містить JSON-запис того значення:

  • Жодного впорядкування властивостей для об'єктів, що не є масивами, не передбачено. Не покладайтеся на жодний порядок властивостей одного об'єкта, перетворюваного на JSON;
  • Об'єкти Boolean, Number та String в типовий спосіб перетворюються на відповідні прості величини;
  • Функцію, undefined або значення типу Symbol під час перетворення буде або вилучено (якщо знайдено в об'єкті), або обернено на null (якщо знайдено в масиві). Метод JSON.stringify також може вертати undefined, якщо йому передано «щирі» величини, як-от JSON.stringify(function(){}) чи JSON.stringify(undefined);
  • Всі властивості, що мають за ключ величину типу 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}' or '{"y":6,"x":5}'
JSON.stringify([new Number(1), new String('false'), new Boolean(false)]);
// '[1,"false",false]'

JSON.stringify({ x: [10, undefined, function(){}, Symbol('')] }); 
// '{"x":[10,null,null,null]}' 
 
// Значення типу Symbol:
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';
  }
});
// '{}'

// Неперелічувані властивості:
JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } }) );
// '{"y":"y"}'

Параметер replacer

Параметр replacer може бути функцією або масивом. Якщо то функція, вона прийматиме два параметри: ключ та значення, яке са́ме перетворюється. Об'єкт, якому належить перетворювана властивість, доступний всередині replacer через this. Спершу функцію буде викликано з порожнім рядком замість ключа й тим об'єктом, який має бути перетворено, а відтак для кожної властивості того об'єкта буде здійснено окремий виклик replacer. Кожен виклик має вертати значення, що належить додати до рядка JSON:

  • Якщо повернути Number, до JSON буде додано текстовий запис числа як значення властивості;
  • Якщо повернути String, до JSON буде додано рядок як значення властивості;
  • Якщо повернути Boolean, до JSON буде додано «true» або «false» як значення властивості;
  • Якщо повернути інший об'єкт або масив, його буде рекурсивно перетворено на JSON в той самий спосіб (викликаючи replacer для кожної його властивості), а тоді додано до JSON як значення властивості (якщо повернутий об'єкт є функцією, до JSON нічого додано не буде);
  • Якщо повернути undefined, властивість не потрапить до JSON.
Заувага: Вилучати елементи масиву за допомогою replacer неможливо — якщо повернути undefined, значення елемента лише обернеться на null. Проте тієї ж мети можна досягти, зробивши відповідні зміни рівнем вище — коли сам масив потрапляє до replacer як значення властивості.

Функція replacer

Наведений приклад перетворює певний об'єкт на рядок JSON, попередньо вилучивши з нього всі властивості, значення яких є рядками. Завважте, що в масивах рядки перетворюються на null, а не вилучаються:

// Вилучити всі рядкові значення
function replacer(key, value) {
  if (typeof value === "string") {
    return undefined;
  }
  return value;
}

var word = {
  value: "розкішниця",
  syllables: ["роз", "кіш", "ни", "ця"],
  length: 5
};

// Вертає рядок '{"syllables":[null,null,null,null],"length":5}'
JSON.stringify(word, replacer);

Тож для цього прикладу функцію replacer доведеться трохи вдосконалити:

function replacer(key, value) {
  if (typeof value === "string") {
    return undefined;
  }
  if (Array.isArray(value)) {
    return value.filter(function(element) {
      if (typeof element === "string") {
        return undefined;
      }
      return element;
    });
  }
  return value;
}

Тепер виклик JSON.stringify() дійсно вилучить рядки звідусіль:

// Вертає рядок '{"syllables":[],"length":5}'
JSON.stringify(word, replacer);

Масив replacer

Якщо значенням параметра replacer є масив, його елементи буде використано як перелік імен властивостей, що слід залишити (решту властивостей буде вилучено). Завважте, що вказаний перелік «прийнятних» імен властивостей застосується не лише до властивостей кореневого об'єкта, а й до властивостей вкладених об'єктів (звісно, це стосується лише тих об'єктів, що є значеннями збережених властивостей):

var obj = {
  name: 'Words',
  words: {
    noun: 'поштурховисько',
    verb: 'штурхати',
    adjective: 'кволий'
  }
};

// Вертає рядок '{"name":"Words","words":{"verb":"штурхати"}}'
JSON.stringify(obj, ['name', 'words', 'verb']);

Також зверніть увагу, що елементи масивів лишаються без змін:

var obj = {
  name: 'Words',
  words: ['поштурховисько', 'штурхати', 'кволий']
};

// Вертає рядок '{"words":["поштурховисько","штурхати","кволий"]}'
JSON.stringify(obj, ['words']);

Параметер space

Якщо передбачається, що отриманий JSON-рядок читатиме людина, його можна належним чином відформатувати задля легкочитності. Для цього призначено третій необов'язковий параметр функції JSON.stringify():

  • Якщо його не вказано, отриманий JSON не міститиме ані розривів рядка, ані відступів;
  • Якщо вказано число, воно позначатиме кількість пропусків, що відповідає одному відступові (число більше від 10 матиме ту саму дію, що й 10);
  • Якщо вказано рядок, його (або перших 10 символів, якщо він довший) буде використано як один відступ.

Цей приклад вживає потрійний пропуск як відступ:

JSON.stringify({ a: 1, b: {c: 2} }, null, 3);
// Вертає рядок:
// '{
//    "a": 1,
//    "b": {
//       "c": 2
//    }
// }'

А тут замість пропусків буде вжито символ табуляції:

JSON.stringify({ a: 1, b: {c: 2} }, null, '\t');
// Вертає рядок:
// '{
//     "a": 1,
//     "b": {
//         "c": 2
//     }
// }'

Особливий метод toJSON()

Й хоча методи перетворюваних об'єктів загалом нехтуються, метод з ім'ям toJSON має особливе призначення. Якщо перетворюваний об'єкт має метод toJSON(), його буде викликано, а повернене значення вжито (перетворено на JSON) замість того об'єкта:

var obj = {
  foo: 'foo',
  toJSON: function() {
    return 'bar';
  }
};
JSON.stringify(obj);        // '"bar"'
JSON.stringify({ x: obj }); // '{"x":"bar"}'

Як і звичайний метод, toJSON() матиме за this об'єкт, якому належить. Крім того, метод приймає аргумент key, що передає ім'я властивості, значенням якої є перетворюваний об'єкт:

var obj = {
  integer: {
    value: 123,
    toJSON: function(key) {
      // Ключ: integer
      console.log('Ключ: ' + key);
      return this.value;
    }
  }
};

JSON.stringify(obj);  // вертає '{"integer":123}'

Тлумачення отриманого JSON як коду JavaScript

Завважте, що JSON не є точнісінькою підмножиною JavaScript. Два розділювачі (рядка та параграфу) не треба екранувати у JSON, але треба у JavaScript. Тож якщо ви маєте намір застосувати функцію eval() або скористатися JSONP, доведеться здійснити невеличкі перетворення:

function toCompatibleJson(value) {
    return JSON.stringify(value).
        replace(/\u2028/g, '\\u2028').
        replace(/\u2029/g, '\\u2029');
}

var s = {
    a: String.fromCharCode(0x2028),
    b: String.fromCharCode(0x2029)
};

// Спробуймо витлумачити отриманий JSON як код JavaScript
try {
    eval('(' + JSON.stringify(s) + ')');
} catch (e) {
    console.log(e);  // "SyntaxError: unterminated string literal"
}

// Безпечне перетворення
eval('(' + toCompatibleJson(s) + ')');

// Виводить '{"a":"\u2028","b":"\u2029"}'
console.log(toCompatibleJson(s));

Використання JSON.stringify() із localStorage

Заувага: Функції не є прийнятним типом даних у JSON, тож для них перетворення не діє. Втім, функцію можна заздалегідь перетворити на рядок (наприклад, всередині replacer) за допомогою метода toString, що є в кожної функції. Крім того такі об'єкти як Date метод JSON.stringify() перетворить на рядки, а JSON.parse() під час зворотнього перетворення про це не знатиме і залишить рядок рядком.

Використовуючи методи JSON.stringify() та JSON.parse() можна зберегти довільний об'єкт, а згодом (навіть після закриття переглядача) його відновити. В наведеному прикладі дані зберігаються, а тоді одразу ж відновлюються:

// Умовний об'єкт, що має зберігатися між запусками переглядача
var activity = {
  cart: [],
  viewed: []
};

// ...

activity.cart.push({id: 123, name: 'Бубен', price: 318});

activity.viewed.push({id: 182, name: 'Планшет (10.1" IPS, RAM 2 ГБ)', price: 5715});
activity.viewed.push({id: 877, name: 'Захисна плівка', price: 49});
activity.viewed.push({id: 424, name: 'Духова шафа', price: 12375});

// Перетворюємо об'єкт на JSON-рядок та зберігаємо у localStorage
localStorage.setItem('activity', JSON.stringify(activity));

// Отримаємо JSON-рядок з localStorage та відновимо об'єкт
var restoredActivity = JSON.parse(localStorage.getItem('activity'));

// Відновлений об'єкт:
// {
//   cart: [
//     {id: 123, name: "Бубен", price: 318}
//   ],
//   viewed: [
//     {id: 182, name: "Планшет (10.1" IPS, RAM 2 ГБ)", price: 5715},
//     {id: 877, name: "Захисна плівка", price: 49},
//     {id: 424, name: "Духова шафа", price: 12375}
//   ]
// }
console.log(restoredActivity);

Специфікації

Специфікація Статус Коментар
ECMAScript 5.1 (ECMA-262)
The definition of 'JSON.stringify' in that specification.
Standard Початкова виознака. Запроваджено у 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.
Draft  

Підтримка веб-переглядачами

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Basic support Yes Yes3.5810.54
FeatureAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Basic support Yes Yes Yes4 Yes Yes Yes

Див. також

Мітки документа й учасники

Зробили внесок у цю сторінку: asmforce, olehsrh, linevich, tbunyk
Востаннє оновлена: asmforce,