JSON转对象时如何优雅地更改属性?**
在JavaScript开发中,将JSON字符串转换为JavaScript对象是一个非常常见的操作,我们可以使用 JSON.parse() 方法轻松完成这一转换,在实际应用中,我们往往需要在转换过程中或转换后对对象的属性进行一些更改,比如重命名属性、修改属性值、过滤不需要的属性,或者添加新的计算属性,本文将详细介绍几种在JSON转对象时或转换后更改属性的方法,帮助你更灵活地处理数据。
基础回顾:JSON.parse()
简单回顾一下 JSON.parse() 的基本用法:
const jsonString = '{"name": "Alice", "age": 30, "city": "New York"}';
const obj = JSON.parse(jsonString);
console.log(obj); // { name: 'Alice', age: 30, city: 'New York' }
JSON.parse() 会将一个JSON字符串转换为一个对应的JavaScript对象,默认情况下,属性名会被转换为字符串,属性值会根据JSON中的类型进行转换(字符串、数字、布尔值、null、数组或对象)。
转换后直接修改属性
最直接的方式是在 JSON.parse() 转换完成后,像操作普通JavaScript对象一样修改其属性。
修改属性值:
const jsonString = '{"name": "Alice", "age": 30, "city": "New York"}';
const obj = JSON.parse(jsonString);
obj.age = 31; // 修改已有属性的值
obj.country = "USA"; // 添加新属性
console.log(obj); // { name: 'Alice', age: 31, city: 'New York', country: 'USA' }
删除属性:
使用 delete 操作符:
const jsonString = '{"name": "Alice", "age": 30, "city": "New York"}';
const obj = JSON.parse(jsonString);
delete obj.age; // 删除age属性
console.log(obj); // { name: 'Alice', city: 'New York' }
重命名属性:
重命名属性没有直接的语法,通常需要创建一个新属性,然后删除旧属性:
const jsonString = '{"name": "Alice", "age": 30, "city": "New York"}';
const obj = JSON.parse(jsonString);
obj.fullName = obj.name; // 创建新属性
delete obj.name; // 删除旧属性
console.log(obj); // { age: 30, city: 'New York', fullName: 'Alice' }
优点: 简单直观,易于理解和实现。 缺点: 如果对象结构复杂或需要修改多个属性,这种方式可能会显得冗长。
使用 JSON.parse() 的第二个参数:reviver 函数
JSON.parse() 方法还接受一个可选的第二个参数 reviver,这是一个函数,解析器会遍历每个键值对,并调用 reviver 函数,允许我们在对象构建过程中修改或过滤属性。
reviver 函数的签名是 function(key, value),
key是当前属性名(对于根对象,这个值是空字符串 )。value是当前属性的值。
reviver 函数返回 undefined,则该属性会被从最终对象中移除,否则,返回的值将替换原来的属性值。
修改特定属性的值:
const jsonString = '{"name": "Alice", "age": 30, "city": "New York"}';
const obj = JSON.parse(jsonString, (key, value) => {
if (key === 'age') {
return value + 1; // 年龄加1
}
return value; // 其他属性保持不变
});
console.log(obj); // { name: 'Alice', age: 31, city: 'New York' }
重命名属性(在reviver中):
在reviver中重命名属性需要一些技巧,因为我们是逐级处理的,通常可以先处理子对象,然后处理父对象。
const jsonString = '{"firstName": "Alice", "lastName": "Smith", "age": 30}';
const obj = JSON.parse(jsonString, (key, value) => {
if (key === 'firstName') {
// 先不返回,等lastName处理完一起处理
return { _firstName: value, _lastName: undefined }; // 这不是最佳实践,reviver更适合值修改
}
if (key === 'lastName') {
// 这种方式在reviver中直接构造新对象比较复杂
// 更简单的方式是标记,然后在顶层处理
return { _lastName: value };
}
return value;
});
// 上面的reviver实现起来比较绕,更实用的reviver场景如下:
const betterReviver = (key, value) => {
// 假设我们想将firstName和lastName合并为fullName
if (key === '' && typeof value === 'object' && value !== null && value._firstName !== undefined) {
return {
fullName: `${value._firstName} ${value._lastName}`,
age: value.age
};
}
if (key === 'firstName') return { _firstName: value, _lastName: undefined, age: undefined }; // 这只是示例,实际reviver设计需要更周全
if (key === 'lastName') return { _lastName: value, _firstName: undefined, age: undefined };
return value;
};
// 更清晰的重命名reviver示例(适用于特定结构):
const clearReviver = (key, value) => {
if (key === 'firstName') {
// 我们不能直接在这里重命名为fullName,因为lastName还没来
// 所以返回一个临时对象或标记,然后在顶层处理
return { __temp__: { firstName: value } };
}
if (key === 'lastName') {
return { __temp__: { lastName: value } };
}
if (key === '' && typeof value === 'object' && value !== null && value.__temp__) {
return {
fullName: `${value.__temp__.firstName} ${value.__temp__.lastName}`,
age: value.age // 假设age在顶层
};
}
return value;
};
// 注意:上面的reviver只是为了演示,实际中如果需要复杂转换,可能不如转换后处理方便
// 一个更实用的reviver例子:过滤掉特定属性
const filterReviver = (key, value) => {
if (key === 'age') { // 假设我们不要age属性
return undefined;
}
return value;
};
const filteredObj = JSON.parse(jsonString, filterReviver);
console.log(filteredObj); // { firstName: 'Alice', lastName: 'Smith' }
过滤掉不需要的属性:
如上例所示,在reviver中返回 undefined 即可过滤掉该属性。
优点: 在解析过程中进行修改,可以减少中间对象的创建,对于大型JSON或需要严格过滤的场景可能更高效。 缺点: reviver函数的逻辑可能比较复杂,特别是需要处理嵌套对象或重命名属性时,代码可读性可能下降。
转换后使用对象方法进行批量修改
当需要对对象进行较复杂的属性修改、重命名或转换时,转换后使用专门的对象处理方法(如 Object.keys(), Object.entries(), Array.prototype.map(), reduce() 等)会更加清晰和灵活。
使用 Object.entries() 和 Object.fromEntries():
这种方法非常适合重命名属性或基于现有属性创建新属性。
const jsonString = '{"firstName": "Alice", "lastName": "Smith", "age": 30}';
const obj = JSON.parse(jsonString);
const newObj = Object.fromEntries(
Object.entries(obj).map(([key, value]) => {
if (key === 'firstName') {
return ['name', value]; // 重命名 firstName 为 name
}
if (key === 'lastName') {
return ['surname', value]; // 重命名 lastName 为 surname
}
if (key === 'age') {
return ['ageInYears', value + 1]; // 修改值并重命名
}
return [key, value]; // 其他属性保持不变
})
);
console.log(newObj); // { name: 'Alice', surname: 'Smith', ageInYears: 31 }
使用 reduce():
reduce() 方法也非常适合这种转换场景。
const jsonString = '{"firstName": "Alice", "lastName": "Smith", "age": 30}';
const obj = JSON.parse(jsonString);
const newObjReduced = Object.entries(obj).reduce((accumulator, [key, value]) => {
switch (key) {
case 'firstName':
accumulator.name = value;
break;
case 'lastName':
accumulator.surname = value;
break;
case 'age':
accumulator.ageInYears = value;
break;
default:
accumulator[key] = value;
}
return accumulator;
}, {});
console.log(new


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