简体   繁体   English

传递给回调函数时,此变量未定义

[英]this variable undefined when passed into callback function

I am trying to take an OOP approach in javascript by following this and the one on the mozilla website . 我想通过遵循此方法mozilla网站上的方法,尝试使用javascript中的OOP方法。 When I instantiate my function/class with the new keyword the graph renders correctly, however when a this variable is passed into a callback function it becomes undefined , I was wondering if there was a way around this? 当我使用new关键字实例化函数/类时,图形将正确呈现,但是当将此变量传递给回调函数时,它变为undefined ,我想知道是否有解决方法?

Here is my code: 这是我的代码:

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);
        }
    });
}

and this is how I instantiate my object 这就是我实例化对象的方式

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

this.mRefreshCycle seems to be become undefined when used in the callback function. 在回调函数中使用this.mRefreshCycle似乎变得不确定。

Pass refreshCycle as argument to setTimeout instead. refreshCycle作为参数传递给setTimeout It is always dangerous to use this since it changes meaning dependent upon context. 它始终是危险的,使用this ,因为它而改变含义取决于上下文。

this is most likely referring to your created Highcharts.chart object. this很可能是指您创建的Highcharts.chart对象。 Create an alias of this (_this = this) and try use _this.mRefreshCycle 创建一个别名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);
        }
    });
}

The scope of 'this' within the callback function is likely the "new Highcharts.Chart", not the "lineBasedChart" function. 回调函数中'this'的范围可能是“ new Highcharts.Chart”,而不是“ lineBasedChart”函数。 It has no idea what mRefreshCycle is because it does not exist within the scope of the newly created object. 它不知道什么是mRefreshCycle,因为它不存在于新创建对象的范围内。 You might be able to just remove the 'this' and take advantage of the closure mechanism. 您也许可以删除“ this”并利用关闭机制。

Also, the "options" being passed to the "new Highcharts.Chart()" are undefined. 另外,传递给“新Highcharts.Chart()”的“选项”是未定义的。

Sending this from my phone. 从我的手机发送。 I apologize for lack of markdown. 对于缺少减价,我深表歉意。 I will update the format of answer when I get a chance. 如果有机会,我将更新答案的格式。

As others have suggested, I would remove the "this" identifier and use the parameter that is being passed in. They're the same value at this point anyway, as long as you haven't changed the value of mRefreshCycle at a later time. 正如其他人所建议的那样,我将删除“ this”标识符并使​​用传递的参数。无论如何,这时它们都是相同的值,只要您以后没有更改mRefreshCycle的值即可。 。 If you have a mutator that does this then you will need to tweak this slightly. 如果您有执行此操作的增变器,则需要对此进行一些微调。

How about making lineBasedChart an actual object? 如何使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;
    }
}

This would be useful if you're creating multiple objects eg 如果要创建多个对象,这将很有用,例如

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

You don't necessarily need to use a mutator you could just call on the property directly. 您不一定需要使用增变子,您可以直接调用该属性。

lineBasedChart1.mRefreshCycle = 500;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM