✦ 本站观点:JSON面试题常考解析与序列化,占比超六成。重点考察序列化耗时、空值处理及嵌套深度。建议掌握Gson与Fastjson性能对比,明确其轻量高效优势,应对高频并发场景。
```html
欢迎访问 kaoacca.cn - 专注前端技术分享与面试指南

JSON面试题全解析:从原理到实战的深度指南

掌握JSON的核心机制,攻克前端面试中的数据处理难题。涵盖序列化、反序列化、深拷贝、循环引用及性能优化等关键考点。

一、为什么JSON面试题如此重要?

在现代Web开发中,JSON(JavaScript Object Notation)已成为前后端数据交换的事实标准。无论是RESTful API、WebSocket通信,还是本地存储(localStorage),JSON都扮演着核心角色。因此,在各类前端、全栈开发的JSON面试题中,考察开发者对JSON的理解程度是必经环节。

许多候选人往往忽视了JSON背后的细节,例如:为什么不能直接解析带有函数定义的字符串?JSON.stringify如何处理循环引用?如何进行高效的JSON深拷贝?本文将逐一解答这些在JSON面试题中高频出现的问题。

二、JSON基础语法与常见误区

在深入算法之前,我们需要明确JSON的数据类型限制。这是所有JSON面试题的基础。

支持的类型

对象(Object)、数组(Array)、字符串(String)、数字(Number)、布尔值(Boolean)、null。

不支持的类型

函数(Function)、日期(Date)、undefined、Symbol、RegExp等。这些类型在序列化时会被忽略或转换。

键名限制

JSON对象的所有键名必须使用双引号包裹,这是与JavaScript对象字面量最大的区别之一。

示例:非法的JSON字符串

// 错误示例:单引号、无引号键名、尾随逗号
{
  'name': 'John',  // 错误:必须使用双引号
  age: 25,         // 错误:键名必须加双引号
  hobby: 'coding', // 错误:键名必须加双引号
  tags: ['JS', 'HTML'],
}

正确的JSON格式应为:

{
  "name": "John",
  "age": 25,
  "hobby": "coding",
  "tags": ["JS", "HTML"]
}

三、JSON核心方法:Parse与Stringify

JSON.parse()和JSON.stringify()是处理JSON数据的两个核心API。在JSON面试题中,面试官通常会考察它们的参数用法及返回值差异。

1. JSON.parse():从字符串解析为对象

该方法接收两个参数:要解析的字符串和一个可选的replacer函数(用于过滤或转换属性)。

const jsonString = '{"name": "Alice", "age": 30}';
const obj = JSON.parse(jsonString);
console.log(obj.name); // "Alice"

2. JSON.stringify():从对象序列化为字符串

该方法接收三个参数:要序列化的对象、可选的replacer函数或数组、可选的缩进字符。

Replacer函数的使用

Replacer函数在序列化过程中会被调用,用于过滤或转换值。如果返回undefined,该属性将被忽略。

const data = { name: "Bob", age: 25, secret: "123" };
const json = JSON.stringify(data, (key, value) => {
  if (key === "secret") return undefined; // 隐藏敏感信息
  return value;
}, 2);
console.log(json);
/
{
  "name": "Bob",
  "age": 25
}
/

Space缩进格式化

第三个参数用于美化输出,通常用于调试或生成可读性强的配置文件。

const obj = { a: 1, b: 2 };
console.log(JSON.stringify(obj, null, 4));
/
{
    "a": 1,
    "b": 2
}
/

toJSON方法控制序列化

如果对象定义了toJSON方法,JSON.stringify会调用它并序列化其返回值。

const date = new Date();
const json = JSON.stringify({
  date: {
    toJSON: function() {
      return this.toISOString();
    }
  }
});
// 输出: {"date":"2023-10-01T00:00:00.000Z"}

四、JSON深拷贝:原理与局限

在JavaScript中,对象是引用类型。简单的赋值操作只会复制引用,导致修改原对象会影响新对象。因此,深拷贝成为JSON面试题中的常客。利用JSON.stringify实现深拷贝是一种常见但存在局限性的方法。

1. 基于JSON的深拷贝实现

function deepClone(obj) {
  if (obj === null) return null;
  if (typeof obj !== 'object') return obj;
  try {
    return JSON.parse(JSON.stringify(obj));
  } catch (e) {
    console.error('Deep clone failed due to circular reference or non-JSON types');
    return null;
  }
}

2. 局限性分析

数据类型 序列化结果 原因
Function 被忽略 JSON不支持函数
undefined 被忽略 JSON不支持undefined
Symbol 被忽略 JSON不支持Symbol
RegExp {} 正则对象序列化为空对象
Date 字符串 转换为ISO字符串,反序列化后变为字符串而非Date对象
Circular Reference Error 循环引用导致栈溢出

3. 处理循环引用的深拷贝

当对象存在循环引用时,上述方法会失败。在高级JSON面试题中,面试官可能要求实现一个能处理循环引用的深拷贝函数。

function deepCloneWithCycle(obj, map = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (map.has(obj)) return map.get(obj);
  const clone = Array.isArray(obj) ? [] : {};
  map.set(obj, clone);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepCloneWithCycle(obj[key], map);
    }
  }
  return clone;
}

五、JSON安全漏洞与常见陷阱

在处理用户输入的JSON数据时,安全性至关重要。以下是在实际开发和JSON面试题中常被提及的安全问题。

1. JSON Hijacking

虽然现代浏览器已修复此漏洞,但在旧版IE中,攻击者可以通过覆盖Array构造函数,在页面加载时窃取JSON数据。防御方法包括:

  • ● 始终使用JSON.parse()而非eval()
  • ● 设置正确的Content-Type为application/json
  • ● 在响应头部添加X-Content-Type-Options: nosniff

2. 数值精度问题

JavaScript中的Number类型遵循IEEE 754双精度标准,对于超过17位的整数可能会丢失精度。在JSON传输大额数据(如金额、ID)时,建议使用字符串类型。

// 精度丢失示例
console.log(1234567890123456789); // 1234567890123456800
const json = '{"id": "1234567890123456789"}'; // 推荐:使用字符串

3. 大整数的序列化

当使用JSON.stringify序列化包含大整数的对象时,如果整数超过2^53-1,可能会发生精度丢失。建议在序列化前将大整数转换为字符串。

六、JSON面试题高频考点汇总

以下是近年来前端面试中关于JSON的高频问题及其解答思路。

考点一:JSON与JavaScript对象的区别

JSON是一种数据格式,仅支持对象、数组、字符串、数字、布尔和null。而JavaScript对象是语言层面的数据结构,支持函数、日期、正则等。JSON必须是双引号,JS对象键名可省略引号。

考点二:如何实现JSON深拷贝?

简单场景可使用JSON.parse(JSON.stringify(obj))。复杂场景需使用递归,处理循环引用(使用WeakMap)、特殊类型(Date、RegExp、Function)及原型链。

考点三:JSON.parse的第二个参数有什么用?

第二个参数是replacer函数,用于在解析过程中过滤或转换属性。它在值被返回前被调用,可以修改最终的对象结构。

考点四:JSON.stringify的第三个参数有什么用?

第三个参数是space,用于在序列化结果中添加空白符,使输出更易读。可以是数字(最多10)或字符串。

考点五:如何处理JSON中的循环引用?

在序列化时,如果遇到循环引用,JSON.stringify会抛出错误。需要手动检测循环引用,或使用第三方库如lodash的_.cloneDeep。

七、总结

掌握JSON不仅是通过JSON面试题的关键,更是前端开发者日常工作的必备技能。从基础的序列化与反序列化,到复杂的深拷贝与循环引用处理,再到安全与性能优化,每一个环节都蕴含着丰富的知识点。建议开发者在面试前,结合本文提供的代码示例,亲手实现一遍深拷贝函数,并深入理解JSON.parse和JSON.stringify的内部机制,以便在面试中游刃有余。

希望本文能帮助您全面理解JSON面试题的相关知识点,祝您面试成功!

```
斌知网
蜀ICP备2026017620号-5