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

Vue2升级Vue3后无法为对象分配JavaScript函数问题求助

循环中创建的函数无法赋值给对象?其实是JSON序列化的锅

近期把Vue2项目升级到Vue3,同时将Node版本从v10.15.3-x64升级到v18.16.0-x64,遇到一个奇怪的问题:循环里创建的函数bar能在循环内调用,也能通过外部变量ff调用,但赋值给api_calls对象后,用JSON.stringify打印时看不到函数,甚至直接打印api_calls[name]显示undefined。

代码示例

export function generate_api_calls(app_name) {
  let api_calls = {}

  api_calls['cameraFeed'] = `http://${hostname}:${camera_port}${CAMERA_FEED_URL}`

  let ff
  let items = [1, 2, 3, 4]
  for (let i in items) {
    let name = items[i]
    function bar(j) {
      logger.info(`bar ${j}`)
    };

    bar(i)
    ff = bar
    api_calls[name] = bar;
    logger.info(`generate_api_calls api ${name} ${JSON.stringify(api_calls)}`)
    logger.info(`generate_api_calls api ${JSON.stringify(api_calls[name])}`)
  }
  ff('00');
 
  logger.info(`generate_api_calls 5 ${JSON.stringify(api_calls)}`)
  return api_calls
}

运行日志

2023-05-30_17:39:24.582-gui.vue.app-INFO: bar 0
2023-05-30_17:39:24.582-gui.vue.app-INFO: generate_api_calls api 1 {"cameraFeed":"http://localhost:5051/camera/feed"}
2023-05-30_17:39:24.583-gui.vue.app-INFO: generate_api_calls api undefined
2023-05-30_17:39:24.583-gui.vue.app-INFO: bar 1
2023-05-30_17:39:24.584-gui.vue.app-INFO: generate_api_calls api 2 {"cameraFeed":"http://localhost:5051/camera/feed"}
2023-05-30_17:39:24.584-gui.vue.app-INFO: generate_api_calls api undefined
2023-05-30_17:39:24.585-gui.vue.app-INFO: bar 2
2023-05-30_17:39:24.585-gui.vue.app-INFO: generate_api_calls api 3 {"cameraFeed":"http://localhost:5051/camera/feed"}
2023-05-30_17:39:24.586-gui.vue.app-INFO: generate_api_calls api undefined
2023-05-30_17:39:24.586-gui.vue.app-INFO: bar 3
2023-05-30_17:39:24.587-gui.vue.app-INFO: generate_api_calls api 4 {"cameraFeed":"http://localhost:5051/camera/feed"}
2023-05-30_17:39:24.587-gui.vue.app-INFO: generate_api_calls api undefined
2023-05-30_17:39:24.588-gui.vue.app-INFO: bar 00
2023-05-30_17:39:24.588-gui.vue.app-INFO: generate_api_calls 5 {"cameraFeed":"http://localhost:5051/camera/feed"}

核心原因

JSON的规范只允许序列化原始值(字符串、数字、布尔、null)、对象和数组,函数不属于可序列化的内容。所以:

  • 用JSON.stringify(api_calls)时,所有函数类型的属性会被直接忽略,导致日志里看不到;
  • 用JSON.stringify(api_calls[name])时,传入的是函数,会直接返回undefined,这就是日志显示undefined的原因。

但实际上,函数已经成功赋值给api_calls对象——你能通过ff调用函数,说明bar本身是有效的,只是日志打印方式不对,让你误以为没赋值成功。

验证与解决方法

  1. 换打印方式验证:不要用JSON.stringify,直接打印对象或函数本身:
    // 直接打印对象(Node环境会显示函数)
    logger.info(`generate_api_calls api ${name}`, api_calls)
    // 打印函数的文本内容
    logger.info(`generate_api_calls api ${api_calls[name].toString()}`)
    
  2. 直接调用函数验证:在循环里添加api_calls[name](i),看是否能正常输出日志,确认函数已赋值。
  3. 循环写法优化:遍历数组更推荐用for...of或forEach,避免for...in可能的索引问题:
    items.forEach((name, i) => {
      function bar(j) {
        logger.info(`bar ${j}`)
      }
      bar(i)
      ff = bar
      api_calls[name] = bar
      // 验证调用
      api_calls[name](i)
    })
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 13:13:19