You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript如何根据传入数据更新三层嵌套对象的值?

智能家居设备状态更新问题解决

问题背景

现有如下设备状态对象:

{
    "room_1": {
        "fan": "on",
        "fan_state": 0,
        "light1": "on",
        "light2": "on",
        "light3": "off",
        "light4": "on"
    },
    "room_2": {
        "fan": "on",
        "fan_state": 2,
        "light1": "off",
        "light2": "on",
        "light3": "on",
        "light4": "off"
    },
    "room_3": {
        "fan": "on",
        "fan_state": 2,
        "light1": "off",
        "light2": "on",
        "light3": "on",
        "light4": "off"
    },
    "room_4": {
        "fan": "on",
        "fan_state": 3,
        "light1": "off",
        "light2": "off",
        "light3": "off",
        "light4": "on"
    }
}

需要根据传入的JSON字符串格式数据更新该对象,比如传入数据:

{"room_1":{"light1":"off"}}

但原有代码无法完成更新,以下是失败的代码:

var jsonRequest=flow.get('post_msg') || {};
var jsonObj = JSON.parse(jsonRequest);
//var jsonObj = jsonRequest;
var js_keys = Object.keys(jsonObj);
//node.warn(jsonRequest);
node.warn("jsonObj " + jsonObj + "  and " + Object.keys(jsonObj) + " type " + typeof (jsonObj));
var oldJSON= msg.payload;
var newJSON = oldJSON;
node.error("1 oldJSON_ payload_newjson " + JSON.stringify(oldJSON) );

for (var key in newJSON){
    node.error("for ok: " + key + " " + JSON.stringify(jsonObj[key]) + "" + JSON.stringify(newJSON[key]) + " io " + Object.keys(JSON.parse(jsonObj)) + " val  " + JSON.stringify(Object.values(JSON.parse(jsonObj)) ) );

    if (key == Object.keys(jsonObj)+"" ){
node.warn("true");
    }
        node.error("1ppp " + JSON.stringify(newJSON[key]) );
        

       for (var key2 in newJSON[key]){
            node.error("2ppp " + jsonObj + " ok " + JSON.stringify(newJSON[key] )); 
            //if (key2 == Object.keys(JSON.parse(jsonObj) ) ) {

              //  newJSON[key][key2] = JSON.parse(jsonObj[key][key2]);
            //}
        }
    //}

}

//newJSON.room_1.light1 ="off" ;
msg.payload=newJSON ;
var msg_keys = Object.keys(jsonObj);
node.error(msg_keys);
msg.room_no = msg_keys.toString();
msg.inputs =jsonRequest;
//msg.flags= oldJSON.flags;
return  msg;

问题代码分析

  1. 无效的键匹配逻辑:key == Object.keys(jsonObj)+"" 会将数组转为逗号分隔的字符串,仅当更新数据只有一个键时可能偶然匹配,逻辑本质错误,且遍历原始对象所有房间完全没必要。
  2. 重复解析错误:多次执行JSON.parse(jsonObj),但jsonObj已经是解析后的对象,重复解析会抛出异常。
  3. 冗余循环:遍历原始对象的所有房间和设备,没有针对性地处理更新数据中的目标键。

修复后的代码

// 获取传入的更新请求字符串
var jsonRequest = flow.get('post_msg') || '{}';
// 解析为JSON对象
var updateData = JSON.parse(jsonRequest);

// 获取原始设备状态对象
var deviceState = msg.payload;

// 遍历更新数据中的每个房间
for (const roomKey in updateData) {
    // 检查原始对象中是否存在该房间,避免无意义操作
    if (deviceState[roomKey]) {
        // 遍历该房间内需要更新的设备
        for (const deviceKey in updateData[roomKey]) {
            // 直接更新对应设备状态
            deviceState[roomKey][deviceKey] = updateData[roomKey][deviceKey];
        }
    }
}

// 设置返回的设备状态
msg.payload = deviceState;
// 记录更新的房间号和原始请求内容
msg.room_no = Object.keys(updateData).toString();
msg.inputs = jsonRequest;

return msg;

关键说明

  • 精准遍历:仅遍历更新数据中的房间和设备,避免无意义的循环,提升执行效率。
  • 避免重复解析:仅对传入的字符串执行一次JSON.parse,后续直接操作对象,避免异常。
  • 安全检查:先判断原始对象中是否存在目标房间,避免因更新数据包含不存在的房间导致错误。

内容的提问来源于stack exchange,提问作者Shariq Azim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:25:32