JavaScript 函数调用上下文具有有效参数,但函数无法获取它们

JavaScript function call context has valid parameters, but function doesn't get them

提问人:jc0022 提问时间:2/19/2023 最后编辑:jc0022 更新时间:2/19/2023 访问量:48

问:

在使用回调的自定义事件处理设置中,回调的调用上下文显示回调参数的有效值,但在单步执行函数后,参数值未定义。

如果重要的话,这是在使用 React 的 Electron 渲染器进程内部。

在普通 JavaScript 对象中,调试器显示回调报告行上所有内容的预期上下文值。SerialPortEvent.Opened

// file: serialPort.js (no imports)
class SerialPortEvent {
  Discovered = 0
  Opened = 1
  Closed = 2
  DataReceived = 3
  Error = 4
}

class SerialPortSpec {
...
  addEventListener(listener) {
    this.listeners.push(listener)
  }

  open(baudRate) {
    const baudRateInt = parseInt(baudRate, 10)

    window.serialport.open(this.portInfo.path, baudRateInt)
      .then(binding => {
        this.baudRate = baudRateInt
        this.binding = binding

        // Here, the debugger shows all locals are as expected

        this.listeners.forEach(listener => listener(SerialPortEvent.Opened))
      }).catch(reason => {
        this.listeners.forEach(listener => listener(SerialPortEvent.Error, reason))
      })
  }
...
}

...

module.exports = { SerialPortEventHub, SerialPortSpec, SerialPortEvent }

但是,在回调函数“portEventHandler”的开头,一个“单步执行”之后,参数值为 。我很想知道为什么!谢谢。undefined

// file SerialPortUI.jsx

import React from 'react'
import { SerialPortEventHub, SerialPortEvent, SerialPortSpec } from './serialPort'
import './serialportui.css'

class SerialPortPanel extends React.Component {
...
  portEventHandler(eventType, ...data) {
    // Here, eventType is undefined. This file does import SerialPortEvent.
    switch (eventType) {
      ...
    }
  }
...
}
JavaScript 函数 回调

评论

0赞 Unmitigated 2/19/2023
你在哪里打电话?addEventListener
0赞 jc0022 2/19/2023
@Unmitigated它在 SerialPortPanel 的 componentDidMount() 函数中被调用。在调试 SerialPortSpec 实例的侦听器列表时,对它的引用是可见的。
0赞 adsy 2/19/2023
根据我的经验,这通常与循环依赖关系有关。向我们展示 SerialPortEvent 的定义位置,以及它的导出方式。还要包括它在代码中的导入方式。如果您将其包含在包含上述代码的其中一个文件中,则如果这些文件也相互导入,则可能表明存在问题。
0赞 jc0022 2/19/2023
@adsy谢谢,我编辑了这篇文章,以澄清数据模型文件没有导入相关的 React 文件。我首先按照传统模式编写了原版数据模型,但我相信如果没有弄清楚,我的下一步将是将该状态合并到 React 类中。

答:

1赞 Bergi 2/19/2023 #1
class SerialPortEvent {
  Discovered = 0
  Opened = 1
  Closed = 2
  DataReceived = 3
  Error = 4
}

这不是一个正确的枚举声明。类字段将在实例上创建,您在代码中访问的静态类属性确实是 。这就是被调用函数接收到的值。SerialPortEvent.Openedundefined

相反,您需要使用具有属性的对象:

const SerialPortEvent = {
  Discovered: 0,
  Opened: 1,
  Closed: 2,
  DataReceived: 3,
  Error: 4,
};

如果你从不实例化语法,就永远不要使用语法(使用)!classnew

评论

0赞 adsy 2/19/2023
他也可以在 TS 中使用,这几乎是唯一在 TS 中具有运行时的东西enum
0赞 Bergi 2/19/2023
@adsy 是的,我原本打算在评论中提出可能混淆的建议,但这个问题没有用 TypeScript 标记classenum
0赞 adsy 2/20/2023
啊,是的,没错,出于某种原因,当那里没有 TS 时,我的大脑将其解析为 TS。