Handling Functions and Undefined in JavaScript JSON
When converting JavaScript data into a JSON string using
JSON.stringify(), functions and undefined
values receive special treatment because they are not valid data types
in the JSON standard. Depending on where these values exist—whether
inside an object, an array, or passed as standalone values—JavaScript
either omits them, replaces them with null, or returns
undefined. This article explains the exact serialization
rules for functions and undefined values in JavaScript and
demonstrates how to customize this behavior.
Default Serialization Behavior
The JSON format only supports strings, numbers, booleans, objects,
arrays, and null. When JSON.stringify()
encounters functions or undefined, it applies the following
rules:
1. Inside Objects (Omitted)
When a function or undefined value is a property value
within an object, JSON.stringify() omits the key-value pair
completely.
const user = {
name: "Alice",
age: undefined,
greet: function() { return "Hello"; }
};
console.log(JSON.stringify(user));
// Output: {"name":"Alice"}2. Inside Arrays (Converted to
null)
When a function or undefined is an element inside an
array, it is converted into null to preserve the index
positions of the other elements.
const list = ["apple", undefined, function() { return 42; }, "banana"];
console.log(JSON.stringify(list));
// Output: ["apple",null,null,"banana"]3. As Standalone Values
(Returns undefined)
When passed directly as a single value (not inside an object or
array), both functions and undefined return
undefined rather than a string.
console.log(JSON.stringify(undefined));
// Output: undefined
console.log(JSON.stringify(() => {}));
// Output: undefinedWhy JSON Discards Functions and Undefined
JSON (JavaScript Object Notation) is a language-agnostic data
interchange format. While inspired by JavaScript syntax, JSON does not
allow executable code (functions) for security and cross-language
compatibility reasons. Similarly, undefined is a
JavaScript-specific primitive that does not exist in standard JSON; JSON
uses null to represent the intentional absence of a
value.
Customizing Serialization
If you need to preserve, modify, or log functions and
undefined values during serialization, you can use the
built-in customization options of JSON.stringify().
Using a Replacer Function
The replacer parameter allows you to inspect and
transform values before they are serialized:
const data = {
status: undefined,
log: function() { console.log("running"); }
};
const jsonString = JSON.stringify(data, (key, value) => {
if (typeof value === "function") {
return value.toString(); // Serialize function as a string
}
if (value === undefined) {
return null; // Convert undefined to null explicitly
}
return value;
});
console.log(jsonString);
// Output: {"status":null,"log":"function() { console.log(\"running\"); }"}Using the toJSON()
Method
If an object contains a toJSON() method,
JSON.stringify() calls that method and serializes the
returned value instead of the original object:
const profile = {
username: "johndoe",
getRole: () => "admin",
toJSON() {
return {
username: this.username,
role: this.getRole()
};
}
};
console.log(JSON.stringify(profile));
// Output: {"username":"johndoe","role":"admin"}