第二十五天:高阶方法与 JSON — 数据处理的四大神器
蜗牛往上爬 · 前端工业可视化学习笔记 第 25 篇
for 循环能遍历数组,但 JS 提供了更强大的工具:forEach、map、filter、reduce——四大高阶方法,配合链式调用,几行代码完成复杂的数据清洗。再加 JSON 序列化,这就是工业大屏"数据处理流水线"的全部基础。
目录
一、forEach:遍历
var deviceList = [
{ id: "CNC-001", temp: 65, online: true },
{ id: "AGV-002", temp: 42, online: true },
{ id: "CNC-004", temp: 0, online: false }
];
// 对每个元素执行一次回调
deviceList.forEach(function (device, index) {
console.log((index + 1) + ". " + device.id + ":" + device.temp + "°C");
});
// 1. CNC-001:65°C
// 2. AGV-002:42°C
// 3. CNC-004:0°C
forEach 比 for 循环简洁,但不能 break/continue——需要中途停止时用 for。
二、map:一对一转换
// map:每个元素转换成新元素,返回新数组(原数组不变)
// 场景 1:提取字段
var temps = deviceList.map(function (device) {
return device.temp;
});
// [65, 42, 0]
// 场景 2:格式化数据(大屏渲染前的处理)
var displayList = deviceList.map(function (device) {
return {
label: device.id,
value: device.temp + "°C",
color: device.temp > 60 ? "orange" : "green"
};
});
// [{label:"CNC-001", value:"65°C", color:"orange"}, ...]
三、filter:筛选
// filter:条件为 true 的元素保留,返回新数组
var onlineDevices = deviceList.filter(function (device) {
return device.online === true;
});
// 2 台在线设备
// ⭐ 链式调用:filter + map 组合(数据处理利器)
var onlineIds = deviceList
.filter(function (device) { return device.online; }) // 筛在线的
.map(function (device) { return device.id; }); // 提取 id
// ["CNC-001", "AGV-002"]
四、reduce:聚合
// reduce:把数组"压缩"成一个值
// acc 是累加器,cur 是当前元素,0 是初始值
var total = [65, 42, 38].reduce(function (acc, cur) {
return acc + cur;
}, 0);
// 145
// 场景 1:平均温度
var temps = [65, 42, 38, 55];
var avg = temps.reduce(function (s, t) { return s + t; }, 0) / temps.length;
// 50
// 场景 2:统计各状态的设备数量(初始值是空对象)
var deviceList = [
{ id: "A", status: "运行中" },
{ id: "B", status: "待机" },
{ id: "C", status: "运行中" },
{ id: "D", status: "故障" }
];
var statusCount = deviceList.reduce(function (acc, device) {
acc[device.status] = (acc[device.status] || 0) + 1;
return acc;
}, {});
// { "运行中": 2, "待机": 1, "故障": 1 }
五、四大方法对比
选型口诀:
要"遍历做事" → forEach
要"转换每个元素" → map
要"筛选部分元素" → filter
要"算出一个结果" → reduce
六、JSON 序列化与反序列化
JSON 是前后端数据传输的标准格式。
var deviceList = [
{ id: "CNC-001", temp: 65, online: true },
{ id: "AGV-002", temp: 42, online: true }
];
// ===== 发送数据:对象 → JSON 字符串 =====
var jsonStr = JSON.stringify(deviceList);
// '[{"id":"CNC-001","temp":65,"online":true},...]'
// 格式化输出(调试利器)
var pretty = JSON.stringify(deviceList, null, 2);
// ===== 接收数据:JSON 字符串 → 对象 =====
var parsed = JSON.parse(jsonStr);
console.log(parsed[0].id); // "CNC-001"
JSON 与 JS 对象的区别:
// ✅ 合法 JSON:属性名和字符串都用双引号
{ "id": "CNC-001", "temp": 65 }
// ❌ 非法 JSON(JS 对象可以,JSON 不行)
{ id: "CNC-001" } // 属性名没双引号
{ 'id': 'CNC-001' } // 用了单引号
{ "fn": function(){} } // 值不能是函数
{ "a": 1, } // 结尾不能有逗号
解析必须 try/catch:
function safeParse(jsonStr) {
try {
return JSON.parse(jsonStr);
} catch (error) {
console.error("数据格式错误");
return null;
}
}
七、综合实战:数据清洗流水线
工业大屏的经典流程:原始数据 → filter(去脏)→ map(转换)→ reduce(统计)。
// 模拟传感器原始数据(含脏数据)
var rawData = [
{ device_id: "CNC-001", temperature: "65", ts: 1723968000 },
{ device_id: "AGV-002", temperature: "42", ts: 1723968000 },
{ device_id: "", temperature: "999", ts: 1723968000 }, // 脏:无 id
{ device_id: "ARM-003", temperature: "abc", ts: 1723968000 } // 脏:温度非数字
];
var cleanData = rawData
// 第一步:过滤无效数据
.filter(function (item) {
return item.device_id !== "" && !isNaN(Number(item.temperature));
})
// 第二步:转换成标准格式
.map(function (item) {
return {
id: item.device_id,
temp: Number(item.temperature),
time: new Date(item.ts * 1000).toLocaleString()
};
});
console.table(cleanData);
// 第三步:聚合统计
var avgTemp = cleanData.reduce(function (s, i) { return s + i.temp; }, 0) / cleanData.length;
console.log("平均温度:" + avgTemp); // 53.5
八、总结
🎯 JS 基础的数据处理能力已经齐了。下周学 DOM 和事件——让数据和页面真正连起来,向"设备清单增删改查"小项目冲刺!