ho fatto quello che ho inizialmente temuto che dovrò do: ho preso il codice di Crockford e l'ho modificato per i miei bisogni.Ora si costruisce JSON ma gestisce
- cicli
oggetti
- troppo profonde
- troppo lunghi array
- eccezioni (di accesso che non possono essere legalmente accessibili)
Nel caso qualcuno ne ha bisogno , Ho creato un repository GitHub: JSON.prune on GitHub
Questo è il codice:
// JSON.pruned : a function to stringify any object without overflow
// example : var json = JSON.pruned({a:'e', c:[1,2,{d:{e:42, f:'deep'}}]})
// two additional optional parameters :
// - the maximal depth (default : 6)
// - the maximal length of arrays (default : 50)
// GitHub : https://github.com/Canop/JSON.prune
// This is based on Douglas Crockford's code (https://github.com/douglascrockford/JSON-js/blob/master/json2.js)
(function() {
'use strict';
var DEFAULT_MAX_DEPTH = 6;
var DEFAULT_ARRAY_MAX_LENGTH = 50;
var seen; // Same variable used for all stringifications
Date.prototype.toPrunedJSON = Date.prototype.toJSON;
String.prototype.toPrunedJSON = String.prototype.toJSON;
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
};
function quote(string) {
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string'
? c
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
function str(key, holder, depthDecr, arrayMaxLength) {
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
partial,
value = holder[key];
if (value && typeof value === 'object' && typeof value.toPrunedJSON === 'function') {
value = value.toPrunedJSON(key);
}
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
return String(value);
case 'object':
if (!value) {
return 'null';
}
if (depthDecr<=0 || seen.indexOf(value)!==-1) {
return '"-pruned-"';
}
seen.push(value);
partial = [];
if (Object.prototype.toString.apply(value) === '[object Array]') {
length = Math.min(value.length, arrayMaxLength);
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value, depthDecr-1, arrayMaxLength) || 'null';
}
v = partial.length === 0
? '[]'
: '[' + partial.join(',') + ']';
return v;
}
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
try {
v = str(k, value, depthDecr-1, arrayMaxLength);
if (v) partial.push(quote(k) + ':' + v);
} catch (e) {
// this try/catch due to some "Accessing selectionEnd on an input element that cannot have a selection." on Chrome
}
}
}
v = partial.length === 0
? '{}'
: '{' + partial.join(',') + '}';
return v;
}
}
JSON.pruned = function (value, depthDecr, arrayMaxLength) {
seen = [];
depthDecr = depthDecr || DEFAULT_MAX_DEPTH;
arrayMaxLength = arrayMaxLength || DEFAULT_ARRAY_MAX_LENGTH;
return str('', {'': value}, depthDecr, arrayMaxLength);
};
}());
Un esempio di cosa si può fare:
var json = JSON.pruned(window);
Nota: Contrariamente al codice in questa risposta, il GitHub repository viene aggiornata quando necessario (documentazione, la compatibilità, utilizzare come modulo commonjs o nodo, serializzazioni specifiche, ecc.). È una buona idea partire dal repository se hai bisogno di questa funzione di eliminazione.
Cosa si intende per "oggetto molto profondo"? Ci sono davvero oggetti che vanno (senza "proprietà ricorsive") oltre le dimensioni dello stack? – Bergi
sì: 'window' per esempio. È possibile che ci sia un bug nel mio codice e che il vero problema sia la ricorsività, dato che 'window' è sia ricorsiva che profonda (è per questo che ho dato il mio codice). –
Hm, sto ricevendo una 'memoria esaurita '(heap) quando provo il tuo script su' window': -/ – Bergi