function jsonStringify(object, spaces, depth) {
  if(typeof spaces == 'undefined') return _stringify(object);  // primitive types

  depth = depth || 1;
  var space = spaces * depth
    , str = isArray(object) ? '[' : '{'
    , end = isArray(object) ? ']' : '}'
    , length = object.length || exports.keys(object).length
    , repeat = function(s, n) { return new Array(n).join(s); }; // `.repeat()` polyfill

  function _stringify(val) {
    switch (exports.type(val)) {
      case 'null':
      case 'undefined':
        val = '[' + val + ']';
        break;
      case 'array':
      case 'object':
        val = jsonStringify(val, spaces, depth + 1);
        break;
      case 'boolean':
      case 'regexp':
      case 'number':
        val = val === 0 && (1/val) === -Infinity // `-0`
          ? '-0'
          : val.toString();
        break;
      case 'date':
        val = '[Date: ' + val.toISOString() + ']';
        break;
      case 'buffer':
        var json = val.toJSON();
        // Based on the toJSON result
        json = json.data && json.type ? json.data : json;
        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';
        break;
      default:
        val = (val == '[Function]' || val == '[Circular]')
          ? val
          : '"' + val + '"'; //string
    }
    return val;
  }

  for(var i in object) {
    if(!object.hasOwnProperty(i)) continue;        // not my business
    --length;
    str += '\n ' + repeat(' ', space)
      + (isArray(object) ? '' : '"' + i + '": ') // key
      +  _stringify(object[i])                   // value
      + (length ? ',' : '');                     // comma
  }

  return str + (str.length != 1                    // [], {}
    ? '\n' + repeat(' ', --space) + end
    : end);
}
@description
like JSON.stringify but more sense.
@param {Object}  object
@param {Number=} spaces
@param {number=} depth
@returns {*}
@private