如何基于递归重写JSON.stringify,区分场景处理函数等特殊值
Hey there! Let's work through fixing your recursive stringifyJSON function to handle all those edge cases properly. The main hurdle you're hitting is that your recursive calls don't have context about whether they're inside an array or an object—so we need to pass that info along as an extra parameter to make the right decisions for each scenario.
Key Fixes & Explanations
First, we'll add an optional isInArray parameter to track the current context. Then we'll handle the special types (functions, Symbol, undefined) with logic tailored to their environment:
- If the value is passed alone (not in an array/object), return
undefined - If the value is in an array, return
'null'(to match JSON's behavior for these types in arrays) - If the value is in an object, we'll use a temporary marker to skip adding that key-value pair entirely
Here's the revised code with these changes:
var stringifyJSON = function (obj, isInArray = false) { // Handle special types: function, Symbol, undefined if (typeof obj === 'function' || typeof obj === 'symbol' || obj === undefined) { if (isInArray) { // In arrays, replace these values with JSON null return 'null'; } else if (typeof obj === 'function' || obj === undefined) { // When passed as the top-level value, return undefined return undefined; } // For object values, return a marker to skip this key-value pair return '__SKIP__'; } /*********CHECK FOR PRIMITIVE TYPES**********/ if (typeof obj === 'number' || typeof obj === 'boolean' || obj === null) { return '' + obj; } else if (typeof obj === 'string') { return '"' + obj + '"'; } else if (Array.isArray(obj)) { // Recurse into array elements, mark context as "in array" const arrVals = obj.map(el => stringifyJSON(el, true)); return '[' + arrVals.join(',') + ']'; } else if (typeof obj === 'object' && obj !== null) { // Handle plain objects const keyValuePairs = []; for (const key in obj) { // Only process own enumerable properties if (Object.prototype.hasOwnProperty.call(obj, key)) { const processedValue = stringifyJSON(obj[key]); // Skip pairs where the value was a function/Symbol/undefined if (processedValue !== '__SKIP__') { keyValuePairs.push(`"${key}":${processedValue}`); } } } return '{' + keyValuePairs.join(',') + '}'; } };
Test Cases to Verify Behavior
Let's check a few scenarios to make sure it works as expected:
- Top-level function:
stringifyJSON(() => {})→ returnsundefined - Array with special values:
stringifyJSON([1, undefined, Symbol('test'), function(){}])→ returns"[1,null,null,null]" - Object with special values:
stringifyJSON({name: "Alice", age: undefined, greet: function(){}, id: Symbol('user')})→ returns"{"name":"Alice"}" - Nested structure:
stringifyJSON({items: [5, function(){}], meta: {skip: undefined, keep: true}})→ returns"{"items":[5,null],"meta":{"keep":true}}"
内容的提问来源于stack exchange,提问作者Andrea D_
相关产品推荐
相关产品推荐

