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

求助:Uncaught TypeError: Cannot read property 'open' of undefined错误排查

解决Cannot read property 'open' of undefined的问题

嘿,我帮你排查了下代码,这个错误主要来自两个关键问题,咱们一步步来解决:

1. 构造函数里调用find()的时机错了

你看你的Sensors构造函数,先调用了this.find(),然后才去创建this.port对象。这就导致当find()执行的时候,this.port还没被赋值,完全是undefined,自然调用this.port.open()就报错了。

修正方法:把this.find()移到this.port初始化之后:

function Sensors(com) {
  this.address = com;
  // 先初始化port对象
  this.port = new sp(com, {
    baudrate: 9600,
    autoOpen: false
  });
  // 再调用find方法
  this.find();
}

2. 回调函数里的this指向混乱

在find方法的各种回调(比如open的回调、data事件的回调)里,默认的this并不是你的Sensors实例——普通函数回调里的this会指向调用它的上下文,比如port.open的回调里this是port对象,而data事件的回调里this可能是全局的window对象。这会导致后续你想访问this.port的时候出问题。

解决办法有两种,选你顺手的就行:

方法一:用箭头函数(最推荐)

箭头函数会继承外层作用域的this,也就是你的Sensors实例,这样就不会乱了:

Sensors.prototype.find = function() {
  console.log("ran");
  this.port.open((err) => {
    if (err) {
      return console.log('Error opening port: ', err.message);
    }
    this.port.write('i' + String.fromCharCode(13), (err) => {
      if (err) {
        return console.log('Error on write: ', err.message);
      }
      console.log('message written');
    });
    this.port.on('data', (data) => {
      var sensorData = data;
      var splitString = sensorData.toString().split(',');
      console.log(splitString[1]);
      if (sensorData.length > 0) {
        if (splitString[1] === 'pH' || splitString[1] === 'EC' || splitString[1] === 'RTD') {
          console.log(splitString[1]);
        }
        this.port.close((err) => {
          console.log('port closed', err);
        });
      }
    });
  });
};

方法二:提前把this存成变量

在find方法开头把实例的this存到一个变量(比如self),然后所有回调里都用self代替this:

Sensors.prototype.find = function() {
  console.log("ran");
  const self = this; // 保存当前实例的引用
  self.port.open(function(err) {
    if (err) {
      return console.log('Error opening port: ', err.message);
    }
    self.port.write('i' + String.fromCharCode(13), function(err) {
      if (err) {
        return console.log('Error on write: ', err.message);
      }
      console.log('message written');
    });
    self.port.on('data', function(data) {
      var sensorData = data;
      var splitString = sensorData.toString().split(',');
      console.log(splitString[1]);
      if (sensorData.length > 0) {
        if (splitString[1] === 'pH' || splitString[1] === 'EC' || splitString[1] === 'RTD') {
          console.log(splitString[1]);
        }
        self.port.close(function(err) {
          console.log('port closed', err);
        });
      }
    });
  });
};

3. 额外的小坑:重复调用find()

在findSensors函数里,你创建sensor实例之后又调用了一次sensor.find(),但其实构造函数里已经调用过find()了,这会导致端口被重复打开,建议把这行重复的调用删掉。另外这里建议用let声明循环变量i,避免全局变量污染:

function findSensors() {
  sp.list(function(err, ports) {
    for (let i = 0; i < ports.length; i++) {
      var sensor = new Sensors(ports[i].comName);
      // 删掉下面这行,构造函数里已经调用过find()了
      // sensor.find();
    }
  });
}

把这些修改做完,你的代码应该就能正常运行,不会再出现那个错误啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:13:44