
本教程详细介绍了如何在JavaScript中将具有非标准或通用键的JSON对象数组,精确地映射到自定义类的特定属性。通过利用ES6的解构赋值与属性重命名功能,可以有效地解决键名不匹配的问题,确保数据正确地转换为类实例,从而提高代码的可读性和数据处理的灵活性。
挑战:JSON对象与类属性的不匹配
在前端开发中,我们经常会从后端api或其他数据源接收到json格式的数据。这些数据的键名可能并不总是与我们前端定义的javascript类属性名称完全一致。例如,我们可能收到以下结构的库存数据:
var inputJson = [{ "HS": " ", "__EMPTY": 1, "__EMPTY_1": " Pcs."},{ "HS": " RAS222PCAIBA", "__EMPTY": 1, "__EMPTY_1": " Pcs."},{ "HS": " SRK20CSS-S6/A1.6T", "__EMPTY": -4, "__EMPTY_1": " Pcs."}];
而我们希望将其映射到一个结构化的Stocks类实例中,该类定义如下:
class Stocks { model; // 对应 inputJson 中的 "HS" quantity; // 对应 inputJson 中的 "__EMPTY" type; // 对应 inputJson 中的 "__EMPTY_1" constructor(data) { // 尝试直接赋值,但如果data的键名与类属性不匹配,会导致问题 Object.assign(this, data); }}
如果直接尝试将inputJson中的每个对象传递给Stocks类的构造函数,例如:
var completeStock = [];// 使用 $.each 迭代,也可以是 Array.prototype.forEach$.each(inputJson, function(index, value) { completeStock.push(new Stocks(value));});
这种方法会导致Stocks实例上出现HS、__EMPTY、__EMPTY_1等属性,而不是我们期望的model、quantity、type。这是因为Object.assign(this, data)会直接复制data对象的所有可枚举属性到this上,并不会进行键名转换。
解决方案:利用ES6解构赋值进行属性重命名
为了解决键名不匹配的问题,我们可以利用ES6的解构赋值(Destructuring Assignment)结合属性重命名(Property Renaming)功能。这个特性允许我们在从对象中提取属性值的同时,为其指定新的变量名。
立即学习“Java免费学习笔记(深入)”;
其基本语法是:const { originalKey: newKeyName } = sourceObject;
应用到我们的场景中,我们可以在创建Stocks实例之前,先从原始JSON对象中提取并重命名所需的属性:
// 假设 inputJson 和 Stocks 类已定义var completeStock = [];$.each(inputJson, function(index, value) { // 使用解构赋值,将原始键名映射到目标属性名 const { HS: model, __EMPTY: quantity, __EMPTY_1: type } = value; // 使用重命名后的属性创建新的 Stocks 实例 completeStock.push(new Stocks({ model, quantity, type }));});console.log(completeStock);
这段代码的关键在于 { HS: model, __EMPTY: quantity, __EMPTY_1: type } = value;。它做了以下几件事:
从value对象中查找名为HS的属性,并将其值赋给一个名为model的新变量。类似地,将__EMPTY的值赋给quantity变量。将__EMPTY_1的值赋给type变量。
之后,new Stocks({ model, quantity, type })会使用这些已经正确命名的变量来构造一个对象 { model: ‘…’, quantity: …, type: ‘…’ },再通过Object.assign正确地赋值给Stocks实例的相应属性。
完整示例与代码解析
下面是包含原始数据、类定义和解决方案的完整代码示例:
// 原始JSON数据数组const inputJson = [{ "HS": " ", "__EMPTY": 1, "__EMPTY_1": " Pcs."},{ "HS": " RAS222PCAIBA", "__EMPTY": 1, "__EMPTY_1": " Pcs."},{ "HS": " SRK20CSS-S6/A1.6T", "__EMPTY": -4, "__EMPTY_1": " Pcs."}];// 目标类定义class Stocks { model; quantity; type; constructor(data) { // 这里的 Object.assign 假设传入的 data 对象的键名已经与类属性匹配 Object.assign(this, data); }}// 存储映射后的 Stocks 实例的数组const completeStock = [];// 使用 $.each 迭代 inputJson 数组// 注意:在现代JavaScript中,更推荐使用 Array.prototype.map$.each(inputJson, function(index, value) { // 核心步骤:使用解构赋值和属性重命名,将原始JSON键映射到类属性名 const { HS: model, // 将 value.HS 的值赋给 model 变量 __EMPTY: quantity, // 将 value.__EMPTY 的值赋给 quantity 变量 __EMPTY_1: type // 将 value.__EMPTY_1 的值赋给 type 变量 } = value; // 创建一个新的 Stocks 实例,并传入一个包含正确属性名的对象 completeStock.push(new Stocks({ model, quantity, type }));});console.log(completeStock);/*预期输出示例:[ Stocks { model: ' ', quantity: 1, type: ' Pcs.' }, Stocks { model: ' RAS222PCAIBA', quantity: 1, type: ' Pcs.' }, Stocks { model: ' SRK20CSS-S6/A1.6T', quantity: -4, type: ' Pcs.' }]*/
代码解析:
inputJson: 原始数据源,一个包含多个具有非标准键名对象的数组。Stocks 类: 定义了我们期望的结构,包含model、quantity、type三个属性。constructor中的Object.assign(this, data)假定传入的data对象已经具有正确的键名。$.each(inputJson, function(index, value) { … });: 这是一个迭代inputJson数组的循环。在每次迭代中,value代表数组中的当前JSON对象。const { HS: model, __EMPTY: quantity, __EMPTY_1: type } = value;: 这是实现键名映射的关键。它从当前的value对象中提取HS、__EMPTY、__EMPTY_1这三个属性的值,并将它们分别赋值给新声明的model、quantity、type常量。completeStock.push(new Stocks({ model, quantity, type }));: 在获得正确命名的属性值后,我们创建一个新的匿名对象{ model, quantity, type }(这是ES6的属性值简写语法,等同于{ model: model, quantity: quantity, type: type }),然后将其作为参数传递给Stocks类的构造函数,最终生成一个符合预期的Stocks实例并添加到completeStock数组中。
进阶考量与最佳实践
数据清洗与类型转换: 原始JSON数据可能包含多余的空格(如”HS”: ” RAS222PCAIBA”)或需要特定类型转换(如”__EMPTY”: 1可能需要确保是整数)。在解构赋值后,创建对象前,可以进行这些处理:
const completeStockCleaned = inputJson.map(item => { const { HS: modelRaw, __EMPTY: quantityRaw, __EMPTY_1: typeRaw } = item; return new Stocks({ model: modelRaw ? modelRaw.trim() : '', // 清除空格,处理空值 quantity: parseInt(quantityRaw) || 0, // 转换为整数,提供默认值 type: typeRaw ? typeRaw.trim() : '' });});console.log(completeStockCleaned);
处理缺失键与默认值: 如果原始JSON中某个键可能不存在,解构赋值会将其对应的变量设为undefined。你可以为解构的变量提供默认值:
const { HS: model = '未知型号', __EMPTY: quantity = 0 } = value;
使用Array.prototype.map: 相较于$.each,Array.prototype.map是JavaScript原生的数组迭代方法,它更符合函数式编程范式,并且直接返回一个新数组,代码通常更简洁高效:
const completeStockMap = inputJson.map(item => { const { HS: model, __EMPTY: quantity, __EMPTY_1: type } = item; return new Stocks({ model: model ? model.trim() : '', quantity: parseInt(quantity) || 0, type: type ? type.trim() : '' });});console.log(completeStockMap);
类构造函数的灵活性: 如果映射逻辑复杂,也可以考虑将部分映射逻辑封装到Stocks类的静态方法中,例如Stocks.fromJSON(jsonObject),但这通常在外部键名一致性较高时更适用。对于外部键名频繁不一致的情况,外部解构赋值通常更灵活。
总结
通过本教程,我们学习了如何利用ES6的解构赋值与属性重命名功能,优雅地解决JavaScript中JSON对象键名与目标类属性不匹配的问题。这种方法不仅使代码更加清晰、易读,而且提供了强大的灵活性来处理各种数据格式。结合数据清洗、类型转换和默认值处理,可以构建出健壮且高效的数据映射逻辑,从而提升应用程序的数据处理能力和代码质量。在处理外部API数据或需要将通用数据结构转换为特定领域模型时,解构赋值无疑是一个非常实用的工具。
以上就是利用解构赋值实现JavaScript中JSON对象到类属性的精确映射的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1526163.html
微信扫一扫
支付宝扫一扫