Safe Stringify
This code follows links once and only once, so, there should be no circular references.
Note that large objects should NOT be output to the console, as this will be super slow.
Assign the safeStringify to a variable and save it to a file using console.save below.
See the sample usage at the end of this article.
var safeStringify = function(obj, replacer, indent) { var printedObjects = []; var printedObjectKeys = []; function is_scalar(obj){return (/string|number|boolean/).test(typeof obj);} function printOnceReplacer(key, value) { if (value === null || value === undefined || is_scalar(value)) return value; if (printedObjects.length > 10000) { return 'object too long'; } // try to find the current object in "printedObjects" var printedObjIndex = false; printedObjects.forEach(function(obj, index) { if (obj === value) { printedObjIndex = index; } }); // handle root case if (key == '') { //root element printedObjects.push(obj); printedObjectKeys.push("root"); return value; } // hadle case previously found reference case else if (printedObjIndex + "" != "false" && typeof (value) == "object") { if (printedObjectKeys[printedObjIndex] == "root") { return "(pointer to root)"; } else { return "(see " + ((!!value && !!value.constructor) ? value.constructor.name.toLowerCase() : typeof (value)) + " with key " + printedObjectKeys[printedObjIndex] + ")"; } } // hanle newly found reference case, and calling the replacer else { var qualifiedKey = key || "(empty key)"; printedObjects.push(value); printedObjectKeys.push(qualifiedKey); if (replacer) { return replacer(key, value); } else { return value; } } } return JSON.stringify(obj, printOnceReplacer, indent); };ref: modified from http://stackoverflow.com/a/17773553/279393
console.save
(function(console){ console.save = function(data, filename){ if(!data) { console.error('Console.save: No data') return; } if(!filename) filename = 'console.json' if(typeof data === "object"){ data = JSON.stringify(data, undefined, 4) } var blob = new Blob([data], {type: 'text/json'}), e = document.createEvent('MouseEvents'), a = document.createElement('a') a.download = filename a.href = window.URL.createObjectURL(blob) a.dataset.downloadurl = ['text/json', a.download, a.href].join(':') e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null) a.dispatchEvent(e) } })(console)ref: http://bgrins.github.io/devtools-snippets/#console-save
Simple Usage
var BNes = safeStringify(myVariableToStringify, undefined, 4); console.save(BNes);
More Complex Usage
var BNes = safeStringify(myVariableToStringify, (k, v) => { let replacements = {"_parent": "[CIRCULAR]", "domElem": "[DOM ELEMENT]"}; // Replace references to HTML elements with a string if (v && v.constructor) { let cn = v.constructor.name.toLowerCase(); if (cn.indexOf("element") === cn.length - 7 && cn.indexOf("html") !== -1) return "HTML ELEMENT"; } if (replacements[k] !== undefined) return replacements[k]; else return v; }, 4); console.save(BNes);