(property, object, callback, properties, whitespace, indentation, stack)
| 431 | // Internal: Recursively serializes an object. Implements the |
| 432 | // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations. |
| 433 | var serialize = function (property, object, callback, properties, whitespace, indentation, stack) { |
| 434 | var value, type, className, results, element, index, length, prefix, result; |
| 435 | attempt(function () { |
| 436 | // Necessary for host object support. |
| 437 | value = object[property]; |
| 438 | }); |
| 439 | if (typeof value == "object" && value) { |
| 440 | if (value.getUTCFullYear && getClass.call(value) == dateClass && value.toJSON === Date.prototype.toJSON) { |
| 441 | value = serializeDate(value); |
| 442 | } else if (typeof value.toJSON == "function") { |
| 443 | value = value.toJSON(property); |
| 444 | } |
| 445 | } |
| 446 | if (callback) { |
| 447 | // If a replacement function was provided, call it to obtain the value |
| 448 | // for serialization. |
| 449 | value = callback.call(object, property, value); |
| 450 | } |
| 451 | // Exit early if value is `undefined` or `null`. |
| 452 | if (value == undefined) { |
| 453 | return value === undefined ? value : "null"; |
| 454 | } |
| 455 | type = typeof value; |
| 456 | // Only call `getClass` if the value is an object. |
| 457 | if (type == "object") { |
| 458 | className = getClass.call(value); |
| 459 | } |
| 460 | switch (className || type) { |
| 461 | case "boolean": |
| 462 | case booleanClass: |
| 463 | // Booleans are represented literally. |
| 464 | return "" + value; |
| 465 | case "number": |
| 466 | case numberClass: |
| 467 | // JSON numbers must be finite. `Infinity` and `NaN` are serialized as |
| 468 | // `"null"`. |
| 469 | return value > -1 / 0 && value < 1 / 0 ? "" + value : "null"; |
| 470 | case "string": |
| 471 | case stringClass: |
| 472 | // Strings are double-quoted and escaped. |
| 473 | return quote("" + value); |
| 474 | } |
| 475 | // Recursively serialize objects and arrays. |
| 476 | if (typeof value == "object") { |
| 477 | // Check for cyclic structures. This is a linear search; performance |
| 478 | // is inversely proportional to the number of unique nested objects. |
| 479 | for (length = stack.length; length--;) { |
| 480 | if (stack[length] === value) { |
| 481 | // Cyclic structures cannot be serialized by `JSON.stringify`. |
| 482 | throw TypeError(); |
| 483 | } |
| 484 | } |
| 485 | // Add the object to the stack of traversed objects. |
| 486 | stack.push(value); |
| 487 | results = []; |
| 488 | // Save the current indentation level and indent one additional level. |
| 489 | prefix = indentation; |
| 490 | indentation += whitespace; |
no test coverage detected