JSON.stringify()‎

من موسوعة حسوب

الدالة JSON.stringify()‎ تحوِّل قيمةً في JavaScript إلى سلسلة نصية بصيغة JSON، وتستطيع -اختياريًّا- استبدال القيم إذا حُدِّدَت دالة استبدال (replacer)، أو تضمين خاصيات مُعيّنة إذا حُدِّدة مصفوفة استبدال (replacer).

البنية العامة

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

value

القيمة التي نريد تحويلها إلى صيغة JSON.

replacer

الدالة التي ستُغيّر من سلوك عملية التحويل، أو مصفوفة من كائنات String و Number التي تعمل كقائمة بالخاصيات المسموحُ تضمينها في الكائن؛ إذا كانت هذه القيمة null أو لم تضبَط فستضمَّن جميع الخاصيات.

space

كائن من النوع String أو Number الذي يُستخدَم لإضافة فراغات في الناتج لأغراضٍ تتعلق بتسهيل قابلية القراءة. إذا لم توفَّر قيمة هذا الوسيط (أو كانت null) فلن توضع فراغات في السلسلة النصية.

إذا كانت قيمة هذا الوسيط هي Number، فهذا يُشير إلى عدد الفراغات التي ستُستخدَم؛ والحد الأقصى لعدد هذه الفراغات هو 10 (أي لو كانت قيمة الوسيط أكبر من 10 فستصغَّر إلى 10)؛ القيم الأقل من 1 تُشير إلى أنَّه لن يُستخدَم أيّ فراغ.

إذا كانت القيمة سلسلةً نصيةً String، فستُستخدَم تلك السلسلة النصية (أو أوّل 10 محارف منها) كفراغ.

القيمة المعادة

سلسلة نصية بصيغة JSON تُمثِّل القيمة المعطية.

الوصف

الدالة JSON.stringify()‎ تحوّل قيمة من قيم JavaScript إلى صيغة JSON:

  • كائنات Boolean و Number و String ستحوّل إلى القيم الأوليّة الموافقة لها.
  • إذا وجدت القيمة undefined أو دالة أو رمز (symbol) أثناء عملية التحويل، فإما أن تُحذَف (إذا كانت موجودةً في كائن) أو تحوّل إلى null (إذا كانت موجودةً في مصفوفة. لاحظ أنَّ الدالة JSON.stringify ستُعيد القيمة undefined عند تمرير القيم «الصافية» مثل JSON.stringify(function(){})‎ أو JSON.stringify(undefined)‎.
  • جميع الخاصيات التي يكون مفتاحها رمزًا (symbol) سيتم تجاهلها كليًّا، حتى عند استخدام الدالة replacer.
  • سيتم تجاهل جميع الخاصيات غير القابلة للإحصاء (non-enumerable).
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)]);
// '[3,"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 إما دالةً أو مصفوفةً. إذا كان دالةً فستأخذ معاملين هما مفتاح وقيمة الخاصية التي يجري تحويلها؛ وهي تُستدعى بدايةً دون تمرير مفتاح وذلك عند تمثيل الكائن نفسه، ثم تُستدعى لكل خاصية في الكائن أو المصفوفة التي يجري تحويلها؛ ويجب أن تُعيد هذه الدالة قيمةً التي ستُضاف إلى السلسلة النصية بصيغة JSON:

  • إذا أعادت Number، فالسلسلة النصية التي ترتبط بذاك الرقم ستُستخدَم كقيمة للخاصية المُضافة إلى سلسلة JSON.
  • إذا أعادت String، فالسلسلة النصية ستُستخدَم كقيمة للخاصية المُضافة إلى سلسلة JSON.
  • إذا أعادت Boolean، فستُستخدَم "true" أو "false" كقيمة للخاصية بما يناسب.
  • إذا أعادت كائنًا آخر، فسيحوّل ذلك الكائن إلى سلسلة JSON تعاوديًا (recursively) مما يستدعي الدالة replacer مرةً أخرى على كل خاصية، ما لم يكن الكائن دالةً، ففي تلك الحالة لن يُضاف شيءٌ إلى سلسلة JSON.
  • إذا أعادت القيمة undefined، فلن تُضمَّن الخاصية في سلسلة JSON.

ملاحظة: لا يمكنك استخدام دالة replacer لإزالة القيم من مصفوفة، فلو أعدتَ القيمة undefined (أو دالة) فستُستخدَم القيمة null بدلًا من قيمة عنصر المصفوفة (لكنه لن يُحذَف).

مثال عن دالة

function replacer(key, value) {
  // حذف القيم النصية
  if (typeof value === 'string') {
    return undefined;
  }
  return value;
}

var foo = {foundation: 'Hsoub', model: 'box', week: 45, transport: 'car', month: 7};
JSON.stringify(foo, replacer);
// '{"week":45,"month":7}'

مثال عن مصفوفة

إذا كانت قيمة الوسيط replacer هي مصفوفة، فستُشير المصفوفة إلى أسماء الخاصيات في الكائن التي يجب تضمنيها في سلسلة JSON الناتجة:

JSON.stringify(foo, ['week', 'month']);  
// '{"week":45,"month":7}'

الوسيط space

يمكن أن يُستخدَم الوسيط space للتحكم في الفراغات في السلسلة النصية الناتجة:

JSON.stringify({ a: 2 }, null, ' ');
// '{
//  "a": 2
// }'

يمكن استخدام محرف مسافة الجدولة (tab) لتنسيق السلسلة النصية:

JSON.stringify({ uno: 1, dos: 2 }, null, '\t');
// '{
//     "uno": 1,
//     "dos": 2
// }'

استخدام toJSON()‎

إذا كان للكائن الذي يجري تحويله خاصيةٌ باسم toJSON التي ترتبط بدالة، فستُستخدَم الدالة toJSON()‎ لتخصيص سلوك الدالة JSON.stringify؛ فبدلًا من تحويل الكائن نفسه، ستحوَّل القيمة المُعادة من هذه الدالة. لاحظ أنَّ الدالة JSON.stringify()‎ تستدعي الدالة toJSON مع وسيطٍ وحيد:

  • إذا كان الكائن هو قيمةٌ لخاصية، فسيُمرَّر اسم الخاصية.
  • إذا كان في مصفوفة، فسيُمرَّر الفهرس في المصفوفة كسلسلة نصية.
  • سلسلة نصية فارغة إذا استدعيت الدالة JSON.stringify مباشرةً على الكائن.

مثال:

const bonnie = {
  name: 'Bonnie Washington',
  age: 17,
  class: 'Year 5 Wisdom',
  isMonitor: false,
  toJSON: function(key) {
    // إنشاء نسخة من الكائن لمنع تعديل قيم خاصيات الكائن الحالي
    const cloneObj = { ...this };

    delete cloneObj.age;
    delete cloneObj.isMonitor;
    cloneObj.year = 5;
    cloneObj.class = 'Wisdom';

    if (key) {
      cloneObj.code = key;
    }

    return cloneObj;
  }
}

JSON.stringify(bonnie);
// '{"name":"Bonnie Washington","class":"Wisdom","year":5}'

const students = {bonnie};
JSON.stringify(students);
// '{"bonnie":{"name":"Bonnie Washington","class":"Wisdom","year":5,"code":"bonnie"}}'

const monitorCandidate = [bonnie];
JSON.stringify(monitorCandidate)
// '[{"name":"Bonnie Washington","class":"Wisdom","year":5,"code":"0"}]'

استخدام ناتج JSON.stringify كشيفرة JavaScript

لاحظ أنَّ صيغة JSON ليست مجموعةً فرعيةً من قواعد JavaScript، فلا حاجة في JSON إلى تهريب محرف نهاية السطر ومحرف الفصل بين الفقرات لكن ذلك ضروريٌ في 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"
}

// لا حاجة إلى عبارة catch
eval('(' + jsFriendlyJSONStringify(s) + ')');

// console.log سوف تُظهِر محارف يونيكود
// أما الدالة alert
// فستعرض رمز يونيكود للمحارف
alert(jsFriendlyJSONStringify(s)); // {"a":"\u2028","b":"\u2029"}

دعم المتصفحات

الميزة Chrome Firefox Internet Explorer Opera Safari
الدعم الأساسي نعم 3.5 8 10.5 4

مصادر ومواصفات