【问题标题】:this variable undefined when passed into callback function这个变量在传入回调函数时未定义
【发布时间】:2015-09-25 11:42:02
【问题描述】:

我正在尝试通过关注thismozilla website 上的方法在javascript 中采用OOP 方法。当我使用new 关键字实例化我的函数/类时,图形会正确呈现,但是当将此变量传递给回调函数时,它会变为undefined,我想知道是否有解决方法?

这是我的代码:

function lineBasedCharts (renderTo, chartType, deviceID, metricType, refreshCycle, title, subtitle, yAxis, tooltip) {
    this.mRenderTo = renderTo
    this.mRefreshCycle = refreshCycle
    this.mChartType = chartType
    this.mTitle = title
    this.mSubtitle = subtitle
    this.mYAxis = yAxis
    this.mTooltip = tooltip

    ...

    this.chart = new Highcharts.Chart(options, function (ch) {
        //use a callback function off the end of highcharts, for when the chart has fully loaded.
        AddSeries(ch, deviceID, metricType);

        if (ch.series[0].data.length > 0) {
            setTimeout(requestData, this.mRefreshCycle, ch, ch.series[0].data[ch.series[0].data.length - 1].x, deviceID, metricType, this.mRefreshCycle);
        }
    });
}

这就是我实例化对象的方式

var chart = []
chart.push(new lineBasedCharts('lineChart', 'spline', 49, 'TEMP', 30000, 'temp', 'Temp in degrees', 'Temperature (°C)', '°C'))

this.mRefreshCycle在回调函数中使用时似乎变得未定义。

【问题讨论】:

  • this 很可能是指您创建的 Highcharts.chart 对象。创建这个 (_this = this) 的别名并尝试使用 _this.mRefreshCycle
  • @SethMcClaine 所以我会创建一个新变量并将 this.mRefreshCycle 分配给该变量,然后将该变量传递给回调?
  • 添加了更新代码的答案

标签: javascript oop this


【解决方案1】:

正如其他人所建议的那样,我将删除“this”标识符并使​​用传入的参数。无论如何,只要您没有更改 mRefreshCycle 的值稍后。如果您有一个执行此操作的 mutator,那么您需要稍微调整一下。

让 lineBasedChart 成为一个实际的对象怎么样?

var LineBasedChart = function (renderTo, chartType, deviceID, metricType, refreshCycle, title, subtitle, yAxis, tooltip) {
    var self = this;
    this.mRenderTo = renderTo
    this.mRefreshCycle = refreshCycle
    this.mChartType = chartType
    this.mTitle = title
    this.mSubtitle = subtitle
    this.mYAxis = yAxis
    this.mTooltip = tooltip

    ...

    this.chart = new Highcharts.Chart(options, function (ch) {
        //use a callback function off the end of highcharts, for when the chart has fully loaded.
        AddSeries(ch, deviceID, metricType);

        if (ch.series[0].data.length > 0) {
            setTimeout(requestData, self.mRefreshCycle, ch, ch.series[0].data[ch.series[0].data.length - 1].x, deviceID, metricType, self.mRefreshCycle);
        }
    });

    /*Mutator to update refresh cycle value*/
    this.setRefreshCycle = function(refreshCycle) {
        this.mRefreshCycle = refreshCycle;
    }
}

如果您要创建多个对象,这将很有用,例如

var lineBasedChart1 = new LineBasedChart(...)
var lineBasedChart2 = new LineBasedChart(...)

您不一定需要使用可以直接调用属性的 mutator。

lineBasedChart1.mRefreshCycle = 500;

【讨论】:

  • 我计划能够在运行时更改这些值,这就是我这样做的原因。你知道我将如何为这些变量创建变异器
  • 我会创建一个别名,就像赛斯在他的回答中所说的那样
  • 要创建变异器,我是否只使用 lineBasedCharts.prototype.SetRefresh = function(newRefresh){} ?
  • 我已经编辑了我的答案以显示如何更改值并在我的 sn-p 中包含一个别名。
【解决方案2】:

refreshCycle 作为参数传递给setTimeout。使用this 总是很危险,因为它会根据上下文改变含义。

【讨论】:

    【解决方案3】:

    回调函数中“this”的范围可能是“new Highcharts.Chart”,而不是“lineBasedChart”函数。它不知道 mRefreshCycle 是什么,因为它不存在于新创建的对象的范围内。您也许可以删除“this”并利用关闭机制。

    此外,传递给“new Highcharts.Chart()”的“选项”是未定义的。

    从我的手机发送这个。我为缺乏降价而道歉。有机会我会更新答案的格式。

    【讨论】:

      【解决方案4】:

      this 很可能是指您创建的Highcharts.chart 对象。创建this (_this = this) 的别名并尝试使用_this.mRefreshCycle

      function lineBasedCharts (renderTo, chartType, deviceID, metricType, refreshCycle, title, subtitle, yAxis, tooltip) {
          //Add alias for this
          _this = this;
          this.mRenderTo = renderTo
          this.mRefreshCycle = refreshCycle
          this.mChartType = chartType
          this.mTitle = title
          this.mSubtitle = subtitle
          this.mYAxis = yAxis
          this.mTooltip = tooltip
      
          ...
      
          this.chart = new Highcharts.Chart(options, function (ch) {
              //use a callback function off the end of highcharts, for when the chart has fully loaded.
              AddSeries(ch, deviceID, metricType);
      
              if (ch.series[0].data.length > 0) {
                  //change how you refer to mRefreshCycle
                  setTimeout(requestData, _this.mRefreshCycle, ch, ch.series[0].data[ch.series[0].data.length - 1].x, deviceID, metricType, this.mRefreshCycle);
              }
          });
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-20
        • 2020-04-14
        相关资源
        最近更新 更多