从 JSON 中提取数据的多种方法:一篇搞定 JavaScript 取值
在现代 Web 开发中,JSON(JavaScript Object Notation)已成为数据交换的事实标准,无论是从 API 获取响应,还是读取配置文件,我们都会频繁地与 JSON 打交道,一个核心且常见的操作就是:如何从 JSON 对象中取出我们需要的值?
本文将系统地介绍在 JavaScript 中从 JSON 数据取值的各种方法,从最基础的点/方括号表示法,到更现代、更安全的可选链和空值合并操作符,并附上清晰的代码示例。
第一步:理解 JSON 和 JavaScript 对象
要明确一个关键点:JSON 本质上是一个字符串,而 JavaScript 对象是内存中的数据结构,当我们从服务器接收到 JSON 数据时,它通常是一个字符串,我们必须先将其转换为 JavaScript 对象,才能进行取值操作。
这个转换过程通过 JSON.parse() 方法完成。
// 这是一个 JSON 格式的字符串
const jsonString = '{"name": "张三", "age": 30, "city": "北京"}';
// 使用 JSON.parse() 将其转换为 JavaScript 对象
const userObject = JSON.parse(jsonString);
console.log(userObject);
// 输出: { name: '张三', age: 30, city: '北京' }
console.log(typeof userObject); // 输出: object
从现在开始,我们将在这个 userObject 上进行所有取值操作。
点表示法(Dot Notation)
这是最直观、最常用的取值方法,它就像访问一个对象的属性一样,通过 对象.属性名 的方式来获取值。
优点: 简洁、易读。
限制: 只适用于属性名是合法的 JavaScript 标识符(不包含空格、连字符,且不以数字开头)的情况。
const userObject = { name: "张三", age: 30, city: "北京" };
// 获取 name 属性
const userName = userObject.name;
console.log(userName); // 输出: 张三
// 获取 age 属性
const userAge = userObject.age;
console.log(userAge); // 输出: 30
方括号表示法(Bracket Notation)
当属性名包含特殊字符(如空格、连字符)、是变量,或者不是合法的标识符时,点表示法就会失效,这时,我们就需要使用方括号表示法。
语法: 对象["属性名"]
优点: 灵活性极高,可以处理任何形式的属性名。
const userObject = {
"full name": "李四",
"user-age": 25,
"1st_login": "2023-01-01"
};
// 属性名包含空格,必须使用方括号
const fullName = userObject["full name"];
console.log(fullName); // 输出: 李四
// 属性名包含连字符,必须使用方括号
const userAge = userObject["user-age"];
console.log(userAge); // 输出: 25
// 属性名以数字开头,必须使用方括号
const firstLogin = userObject["1st_login"];
console.log(firstLogin); // 输出: 2023-01-01
动态取值: 方括号最大的优势在于,可以使用变量来动态指定属性名。
const userObject = { name: "王五", age: 40 };
const dynamicKey = "name";
const dynamicValue = userObject[dynamicKey];
console.log(dynamicValue); // 输出: 王五
可选链操作符(?.)—— 现代 JavaScript 的利器
假设我们要从一个深层嵌套的对象中取值,传统的做法是:
const company = {
name: "ABC 科技",
address: {
city: "上海",
details: {
street: "张江高科技园区",
zipCode: "201204"
}
}
};
const zipCode = company.address.details.zipCode; // 正常工作
console.log(zipCode); // 输出: 201204
const country = company.address.country; // country 属性不存在
console.log(country); // 输出: undefined
// 如果一个中间环节是 undefined,就会报错!
const phone = company.address.phone.number; // TypeError: Cannot read properties of undefined (reading 'number')
为了解决这种深层访问时可能出现的 TypeError,ES2020 引入了可选链操作符()。
它的作用是:如果操作符左侧的表达式是 null 或 undefined,表达式会立即“短路”并返回 undefined,而不会继续执行右侧的访问。
const company = {
name: "ABC 科技",
address: {
city: "上海",
details: {
street: "张江高科技园区",
zipCode: "201204"
}
}
};
// 安全地访问深层属性
const country = company.address?.country;
console.log(country); // 输出: undefined,不会报错
const phone = company.address?.phone?.number;
console.log(phone); // 输出: undefined,不会报错
// 如果路径存在,则正常返回值
const street = company.address?.details?.street;
console.log(street); // 输出: 张江高科技园区
使用场景: 当你不能确定对象或其深层属性是否存在时,可选链是最佳选择,能有效避免烦人的 TypeError。
空值合并操作符(??)—— 处理默认值
有时,我们不仅需要安全地取值,还需要在取到 null 或 undefined 时提供一个默认值,这就是空值合并操作符()的用武之地。
它的作用是:如果左侧的值是 null 或 undefined,则返回右侧的默认值;否则,返回左侧的值。
const userSettings = {
theme: null,
fontSize: undefined,
notifications: "enabled"
};
// theme 是 null 或 undefined,则使用 'dark'
const theme = userSettings.theme ?? 'dark';
console.log(theme); // 输出: dark
// fontSize 是 null 或 undefined,则使用 16
const fontSize = userSettings.fontSize ?? 16;
console.log(fontSize); // 输出: 16
// notifications 的值不是 null 或 undefined,所以返回原值
const notifications = userSettings.notifications ?? 'disabled';
console.log(notifications); // 输出: enabled
与 的区别: 很多人会混淆 和逻辑或 ,关键区别在于 会检查所有“假值”(falsy,如 0, , false, null, undefined),而 只关心 null 和 undefined。
const width = 0; // 使用 ||,0 被视为假值,会返回默认值 const widthWithOr = width || 100; console.log(widthWithOr); // 输出: 100 // 使用 ??,0 是一个有效值,不会被替换 const widthWithNullish = width ?? 100; console.log(widthWithNullish); // 输出: 0
总结与最佳实践
| 方法 | 语法 | 优点 | 缺点/注意事项 |
|---|---|---|---|
| 点表示法 | obj.prop |
简洁、易读 | 属性名必须是合法标识符 |
| 方括号表示法 | obj["prop"] |
灵活,可处理特殊字符和动态取值 | 语法稍长,引号容易遗漏 |
| 可选链 (?.) | obj?.prop |
安全访问深层属性,避免 TypeError |
需要现代浏览器或构建工具支持(Babel) |
| 空值合并 (??) | val ?? default |
为 null/undefined 提供默认值 |
与 行为不同,需注意区分 |
最佳实践建议:
- 始终先解析 JSON:
JSON.parse()是从 JSON 字符串到 JS 对象的桥梁。 - 优先使用点表示法: 在属性名确定且合法的情况下,首选点表示法,因为它最清晰。
- 复杂属性名用方括号: 当属性名包含特殊字符或需要动态访问时,毫不犹豫地使用方括号。
- 拥抱现代语法: 在新项目中,大胆使用可选链 和空值合并 ,它们能让你的代码更健壮、更优雅,减少
if判断的嵌套。 - 组合使用: 这些方法可以完美组合,安全地获取一个可能不存在的深层属性,并为其提供默认值:
const config = {



还没有评论,来说两句吧...