Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么赢了';我的计时器不能增加数字吗?_Javascript - Fatal编程技术网

Javascript 为什么赢了';我的计时器不能增加数字吗?

Javascript 为什么赢了';我的计时器不能增加数字吗?,javascript,Javascript,我最近学习了javascript。我在用它做实验。现在,我试着做一个简单的计时器。代码如下: <html> <head> <script type="text/javascript"> function start(obj) { var t = setTimeout("increment(obj)", 1000); } function increment(obj) { obj.inne

我最近学习了javascript。我在用它做实验。现在,我试着做一个简单的计时器。代码如下:

<html>
<head>
<script type="text/javascript">
    function start(obj)
    {
        var t = setTimeout("increment(obj)", 1000);
    }

    function increment(obj)
    {
        obj.innerHTML = parseInt(obj.innerHTML) + 1;
        start(obj);
    }
</script>
</head>

<body>

<p onclick="start(this)">0</p>

</body>
</html>

功能启动(obj)
{
var t=设置超时(“增量(obj)”,1000;
}
功能增量(obj)
{
obj.innerHTML=parseInt(obj.innerHTML)+1;
启动(obj);
}

0

的内容应每秒递增1。有人知道这为什么不起作用吗?

问题(或者至少是我看到的第一个问题)是,您正在将字符串“increment(obj)”传递给
setTimeout()
方法,但是
obj
仅在
start()
方法中定义。直到超时触发,您传递的字符串才被实际计算,此时没有
obj
变量在范围内

有几种不同的方法可以解决这个问题。一种是将闭包传递给
setTimeout()
,而不是JavaScript字符串,如:

function start(obj) {
    var nextIncrement = function() {
        increment(obj);
    };
    var t = setTimeout(nextIncrement, 1000);
} 
另一个(尽管不太可取)选项是将
obj
提升到全局范围,如:

function start(obj) {
    window.obj = obj;
    var t = setTimeout("increment(obj)", 1000);
}
但是,一般来说,应该避免将字符串传递给
setTimeout
(还应该避免不必要地将内容放入全局范围)。正如您所看到的,它可能会导致范围解析问题,对于任何非平凡的操作,它也会使代码的可维护性大大降低。如果可能,总是希望传递函数闭包

此外,以下代码行是:

您应该始终为
parseInt
提供基数参数,以避免出现诸如
011
之类的值错误(该值为9,而不是11,因为由于前导的
0
在base-8中求值)。您只需执行以下操作即可避免这些怪癖:

parseInt(obj.innerHTML, 10)
…强制执行base-10解析

无论如何,这里的工作示例:

问题(或者至少是我看到的第一个问题)是您正在将字符串“increment(obj)”传递给
setTimeout()
方法,但是
obj
仅在
start()
方法中定义。直到超时触发,您传递的字符串才被实际计算,此时没有
obj
变量在范围内

有几种不同的方法可以解决这个问题。一种是将闭包传递给
setTimeout()
,而不是JavaScript字符串,如:

function start(obj) {
    var nextIncrement = function() {
        increment(obj);
    };
    var t = setTimeout(nextIncrement, 1000);
} 
另一个(尽管不太可取)选项是将
obj
提升到全局范围,如:

function start(obj) {
    window.obj = obj;
    var t = setTimeout("increment(obj)", 1000);
}
但是,一般来说,应该避免将字符串传递给
setTimeout
(还应该避免不必要地将内容放入全局范围)。正如您所看到的,它可能会导致范围解析问题,对于任何非平凡的操作,它也会使代码的可维护性大大降低。如果可能,总是希望传递函数闭包

此外,以下代码行是:

您应该始终为
parseInt
提供基数参数,以避免出现诸如
011
之类的值错误(该值为9,而不是11,因为由于前导的
0
在base-8中求值)。您只需执行以下操作即可避免这些怪癖:

parseInt(obj.innerHTML, 10)
…强制执行base-10解析


无论如何,这里的工作示例是:

,因为传递到
setTimeout
的字符串是在全局范围内计算的,而不是在函数内的范围内,因此不引用
obj
对象

决不能将字符串传递给
setTimeout
。而是向其传递函数引用:

function start(obj)
{
    var t = setTimeout(function() {
                increment(obj);
            }, 1000);
}

function increment(obj)
{
    obj.innerHTML = parseInt(obj.innerHTML) + 1;
    start(obj);
}

我们传递给
setTimeout
的函数是一个闭包,这意味着它对定义它的范围内的项有一个持久的引用。因此,一秒钟后,当计时器机制调用它时,它仍然可以访问
start
函数的
obj
参数,即使
start
函数早就返回了。更多信息:

因为传递到
setTimeout
中的字符串是在全局范围内计算的,而不是函数中的范围,因此不引用
obj
对象

决不能将字符串传递给
setTimeout
。而是向其传递函数引用:

function start(obj)
{
    var t = setTimeout(function() {
                increment(obj);
            }, 1000);
}

function increment(obj)
{
    obj.innerHTML = parseInt(obj.innerHTML) + 1;
    start(obj);
}

我们传递给
setTimeout
的函数是一个闭包,这意味着它对定义它的范围内的项有一个持久的引用。因此,一秒钟后,当计时器机制调用它时,它仍然可以访问
start
函数的
obj
参数,即使
start
函数早就返回了。更多信息:

问题在于这行代码:

    var t = setTimeout("increment(obj)", 1000);
obj
是功能范围内的标识符——它只能在
start
功能中访问。将字符串传递给
setTimeout
时,将在全局范围内对其进行计算。这意味着
obj
变量不可用,因此不增加任何内容

您应该传递一个函数对象,因为这将创建一个闭包,并且可以访问您的变量:

function start(obj)
{
    setTimeout(function() {
        increment(obj);
    }, 1000);
}

请注意,我已经删除了不必要的
var t=
,因为您没有对计时器标识符执行任何操作。

问题在于这行代码:

    var t = setTimeout("increment(obj)", 1000);
obj
是功能范围内的标识符——它只能在
start
功能中访问。将字符串传递给
setTimeout
时,将在全局范围内对其进行计算。这意味着
obj
变量不可用,因此不增加任何内容

您应该传递一个函数对象,因为这将创建一个闭包,并且可以访问您的变量:

function start(obj)
{
    setTimeout(function() {
        increment(obj);
    }, 1000);
}

请注意,我已经删除了不必要的
var t=
,因为您没有使用计时器标识符执行任何操作。

我已经将您的代码复制到jsFidle并添加了一个工作示例。看见 原始版本中的问题是gl中未定义变量obj