JSON.isRawJSON()

Tests whether a value is a marker object produced by JSON.rawJSON().

Signature
JSON.isRawJSON(value)
  • Added in JavaScript ES2025

Parameters

ParameterTypeDescription
$valueanyThe value to test. Any value is accepted, including primitives, null, and undefined.

Return value

booleantrue if the value was created by JSON.rawJSON(), false for every other value.

Changelog

  • PHP ES2025Introduced alongside JSON.rawJSON() as part of the JSON source-text access proposal. Baseline newly available March 2025.

JSON.isRawJSON() answers one question: is this object the special marker that JSON.rawJSON() produces? It never throws and it never coerces — any value can be passed, and anything that is not a genuine raw JSON object returns false.

Reach for it when you are writing a serializer of your own. JSON.stringify() already understands these markers internally, so application code rarely needs the test. But a YAML emitter, a query-string builder, a logging formatter, or a schema validator that walks a data structure will otherwise see the marker as a plain object and emit {"rawJSON":"123"} or, because the object is frozen with a null prototype, something even less useful. Checking first lets you splice in value.rawJSON the same way the built-in does.

Why the identity check matters

The test looks for an internal slot, not for a property. An ordinary object literal that happens to have a rawJSON key returns false, and so does a copy made with spread or structuredClone(). That is deliberate: it means untrusted data cannot smuggle arbitrary text into a serializer's output by naming a field rawJSON.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Add verbatim-number support to a custom YAML, CSV, or log formatter.
  • Skip validation or transformation for values that are already finished JSON text.
  • Assert in a test that a helper returned a real marker rather than a look-alike object.

Frequently asked questions

When would I ever call JSON.isRawJSON()?

Only when you write code that walks a data structure and produces text itself — a custom serializer, formatter, or validator. JSON.stringify() handles raw JSON markers without any help from you.

Why does my object with a rawJSON property return false?

The check tests for an internal marker installed by JSON.rawJSON(), not for a property name, so no hand-built object can pass it. This prevents parsed user input from injecting unescaped text into a serializer's output.

Does JSON.isRawJSON() throw on null or undefined?

No — it accepts any value and simply returns false for anything that is not a raw JSON object, so no typeof guard is needed before calling it.

More examples

Teaching a custom serializer about raw values

The raw check has to come before the typeof "object" branch, otherwise the marker is walked like a normal object. With it in place the id is written out with all twenty digits instead of being rounded or wrapped in braces.

Example · javascript
function toYaml(value, indent = "") {
  if (JSON.isRawJSON(value)) return value.rawJSON;
  if (typeof value !== "object" || value === null) return JSON.stringify(value);
  const inner = `${indent}  `;
  return Object.entries(value)
    .map(([k, v]) => {
      const text = toYaml(v, inner);
      return text.includes("\n") ? `${k}:\n${inner}${text}` : `${k}: ${text}`;
    })
    .join(`\n${indent}`);
}

console.log(toYaml({ name: "Josh", userId: JSON.rawJSON("12345678901234567890") }));

Look-alikes are rejected

The forged object matches the real one on every observable feature — frozen, null prototype, one rawJSON property — yet returns false, because the test reads an internal slot. Stringify agrees: the real marker emits 1.50, the forgery emits a nested object.

Example · javascript
const raw = JSON.rawJSON("1.50");
const fake = Object.freeze(Object.assign(Object.create(null), { rawJSON: "1.50" }));

console.log(JSON.isRawJSON(raw), JSON.isRawJSON(fake));
console.log(JSON.stringify({ v: raw }));
console.log(JSON.stringify({ v: fake }));
console.log(Object.getPrototypeOf(raw), Object.keys(raw));

Feature detection

On an engine without the feature the fallback emits the id as a quoted string, which at least preserves the digits. Both functions ship together, so testing one is enough in practice, but checking both is cheap.

Example · javascript
const hasRawJSON =
  typeof JSON.rawJSON === "function" && typeof JSON.isRawJSON === "function";

console.log("raw JSON support:", hasRawJSON);

const exactNumber = (digits) =>
  hasRawJSON ? JSON.rawJSON(digits) : digits;

console.log(JSON.stringify({ id: exactNumber("12345678901234567890") }));

Discussion

  • Be the first to comment on this lesson.