【问题标题】:Access global variables in setInterval()在 setInterval() 中访问全局变量
【发布时间】:2013-11-25 22:14:16
【问题描述】:

我有一个生成一些随机数字的函数,在该函数中我调用了 setInterval() 因为我需要这些数字每 2 秒刷新一次。

function genSine(val1, val2) {

    var freq = 0.1; // angular frequency

    var coords = function(x, y) {
        var amplitude = Math.floor((Math.random()*10)+1);
        var phase = Math.floor((Math.random()*20)+1);
        return {
            x : Math.sin(freq * (val1 + phase) * amplitude) + Math.floor((Math.random()*100)+1),
            y : Math.sin(freq * (val2 + phase) * amplitude) + Math.floor((Math.random()*100)+1)
        };
    }

    setInterval(function() {
        current = coords(50, 50);
        console.log('Val 1: ' + current.x);
        console.log('Val 2: ' + current.y);
    }, 2000);
}

genSine(10, 20);

这一切都很好,值按预期更新,但我的目标是在 setInterval() 函数中更新两个全局变量(我们称之为 val1/val2)。看来我有一个范围问题,因为这些变量在函数内无法访问,我无法从该函数外部访问“当前”变量。我知道我在这里遗漏了一些东西,它是什么?

小提琴:http://jsfiddle.net/niczak/4uNen/1/

【问题讨论】:

标签: javascript jquery


【解决方案1】:

您只需要在全局范围内定义var current = {};,并确保不要在任何其他范围内定义var currentcurrent=[whatever]; 没问题,只要没有var

编辑:我不确定你做了什么,但我用这段代码修复了你的小提琴:

var current;
function genSine(val1, val2) {

    var freq = 0.1; // angular frequency

   var coords = function(x, y) {
        var amplitude = Math.floor((Math.random()*10)+10);
        var phase = Math.floor((Math.random()*20)+10);
        return {
            x : Math.sin(freq * (val1 + phase) * amplitude) + Math.floor((Math.random()*100)+1),
            y : Math.sin(freq * (val2 + phase) * amplitude) + Math.floor((Math.random()*100)+1)
        };
    }

    setInterval(function() {
        current = coords(50, 50);
        console.log(current);
        $(".display").html(JSON.stringify(current));
    }, 500);
}

genSine(10, 20);

setInterval(function() {
    $(".display2").html("d2:"+JSON.stringify(current));
}, 200);

【讨论】:

  • 我继续做了,但现在 current 总是 = {},所以 current.x 总是未定义。我会继续修补的,谢谢你的快速回复!
  • @NicholasKreidberg:嗯。它对我来说很好。检查我在上面编辑的代码。
  • 感谢您的详细帖子。出于某种原因,它在第一次尝试时不会触发,但之后会起作用,但这是一个不同的问题。标记为解决方案!
【解决方案2】:

您的current 在该范围内很好,是您的coords 函数不在正确的范围内。将其与 freq 变量一起放在全局范围内:

var freq = 0.1; // angular frequency
var coords = function (x, y) {
    var amplitude = Math.floor((Math.random() * 10) + 1);
    var phase = Math.floor((Math.random() * 20) + 1);
    return {
        x: Math.sin(freq * (val1 + phase) * amplitude) + Math.floor((Math.random() * 100) + 1),
        y: Math.sin(freq * (val2 + phase) * amplitude) + Math.floor((Math.random() * 100) + 1)
    };
}

function genSine(val1, val2) {

    setInterval(function () {
        current = coords(50, 50);
        console.log('Val 1: ' + current.x);
        console.log('Val 2: ' + current.y);
    }, 2000);
}

genSine(10, 20);

【讨论】:

  • “你的current 在那个范围内没问题”——不,不是。它是一个隐含的全局。那是不好的做法。将该代码置于严格模式并观察它的崩溃。
  • 为什么?它仅在 setInterval 函数中使用。
  • 弄乱全局空间总是不好的,但隐式全局变量本身就是一件事情,因为即使对代码进行范围界定也无法解决它。没有var,任何变量都不应该被声明。您冒着破坏其他代码以及使您的代码难以维护和调试的风险。这是一个小脚本——但它总是以小脚本开头。
  • 如果您不相信 var 真的能产生如此大的影响,这里有一个关于该特定主题的有趣故事:blog.safeshepherd.com/23
【解决方案3】:

在打字稿中我做了以下代码。在下面的代码中,我为 _this 分配了 this

的值
export class HomeComponent implements OnInit {
  lat: number = 22.008515;
  setMarker(){
   console.log('Inside setMarker Lat : '+this.lat); // 22.008515
    var _this = this;
    setInterval(function() {
     console.log('Inside setInterval this.lat : '+this.lat); // undefined
     console.log('Inside setInterval _this.lat : '+_this.lat); // 22.008515
    }, 8000)
  }
}

【讨论】:

    猜你喜欢
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-29
    相关资源
    最近更新 更多