http://jsfiddle.net/goldrunt/jGL84/42/
这是来自JS fiddle 的第84行。通过取消注释线141-146,可以将3种不同的效果应用于球。 “弹跳”效果按其应有的方式起作用,但“asplode”效果却不起作用。我应该在asplode函数中包括“缩小”函数吗?

// balls shrink and disappear if they touch
var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }
    function asplode(p) {
        setInterval(shrink(p),100);
        balls.splice(p, 1);
    }
}

最佳答案

您的代码有一些问题。

首先,在您的定义中:

var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }

    function asplode(p) {
         setInterval(shrink(p),100);
        balls.splice(p, 1);
    }
}
asplodeshrink内的作用域内是本地的,因此在尝试调用它的update中的代码不可访问。 JavaScript范围是基于函数的,因此update无法看到asplode,因为它不在shrink内。 (In your console,您将看到类似Uncaught ReferenceError: asplode is not defined的错误。)

您可能首先尝试将asplode移到shrink之外:
var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }
}

function asplode(p) {
     setInterval(shrink(p),100);
     balls.splice(p, 1);
}

但是,您的代码还有其他几个问题,不在此问题范围内:
  • setInterval需要一个函数。 setInterval(shrink(p), 100)使setInterval获得立即调用的shrink(p)的返回值。你可能想要
    setInterval(function() { shrink(p) }, 100)
    
  • 您的代码for (var i = 0; i < 100; i++) { p.radius -= 1; }可能不执行您认为的操作。这将立即执行递减操作100次,然后直观地显示结果。如果要以每个新大小重新渲染球,则需要在单独的计时回调(例如setInterval操作)中执行每个单独的递减操作。
  • .splice需要数字索引,而不是对象。您可以使用indexOf获得对象的数字索引:
    balls.splice(balls.indexOf(p), 1);
    
  • 在您的时间间隔首次运行时,balls.splice语句已经发生(确切地说,它发生在大约100毫秒之前)。我认为那不是您想要的。相反,您应该具有一个递减函数,该函数会被setInterval反复调用,并最终在balls.splice(p,1)之后执行p.radius == 0
  • 09-13 09:43