在循环中创建对象时未执行函数-javascript
在下面的代码中,drawFunc在循环期间不会执行(我可以看到,通过逐步调试,代码只跳到函数的末尾) 函数在“stage.add(layer);”行执行,导致错误 有关于如何解决这个问题的帮助吗在循环中创建对象时未执行函数-javascript,javascript,function,Javascript,Function,在下面的代码中,drawFunc在循环期间不会执行(我可以看到,通过逐步调试,代码只跳到函数的末尾) 函数在“stage.add(layer);”行执行,导致错误 有关于如何解决这个问题的帮助吗 <html> <head> <style> body { margin: 0px; padding: 0px; }
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
canvas {
border: 1px solid #9C9898;
}
</style>
<script type="text/javascript" src="http://www.html5canvastutorials.com/libraries/kinetic-v3.9.7.js"></script>
<script>
window.onload = function() {
// global parameters
var curvatureX = 10;
var curvatureY = 10;
var nodeRadius = 10;
var stage = new Kinetic.Stage({
container: "container",
width: 578,
height: 300
});
var layer = new Kinetic.Layer();
var nodes = [];
for (var i = 0;i<10;i++){
nodes[i] = new Kinetic.Circle({
x: i*20,
y: i*5,
z:1,
radius: nodeRadius,
fill: "blue",
stroke: "black",
strokeWidth: 4
});
layer.add(nodes[i]);
}
var edges = [];
for (var i = 0;i<9;i++){
console.log("just after the for: "+i);
edges[i]= new Kinetic.Shape({
// *** PROBLEMS IS HERE
// *** FOR LOOP SKIPS THE FOLLOWING LINES
drawFunc: function() {
var context = this.getContext();
context.beginPath();
console.log("in the drawing function: "+i);
context.moveTo(nodes[i].getX(), nodes[i].getY());
if ((nodes[i].getY()-nodes[i+1].getY())<0){
context.quadraticCurveTo((nodes[i].getX()+nodes[i+1].getX()+curvatureX)/2, (nodes[i].getY()+nodes[i+1].getY()-curvatureY)/2, nodes[i+1].getX(), nodes[i+1].getY());
}
else{
context.quadraticCurveTo((nodes[i].getX()+nodes[i+1].getX()+curvatureX)/2, (nodes[i].getY()+nodes[i+1].getY()+curvatureY)/2, nodes[i+1].getX(), nodes[i+1].getY());
}
context.lineWidth = 10;
// line color
context.strokeStyle = "black";
context.stroke();
},
// *** LOOP RESUMES HERE
fill: "#00D2FF",
stroke: "black",
strokeWidth: 4
});
layer.add(edges[i]);
}
//*** FUNCTION IS EXECUTED HERE, CAUSING BUG.
stage.add(layer);
var amplitude_1 = 100;
var amplitude_2 = 30;
var period = 2000;
// in ms
var centerX = stage.getWidth() / 2;
var centerY = stage.getHeight() / 2;
stage.onFrame(function(frame) {
for (var i=0;i<nodes.length;i++){
nodes[i].setX(amplitude_1 * i * Math.sin(frame.time * 2 * Math.PI / period) + centerX);
nodes[i].setY(amplitude_2 * i+ 20);
}
layer.draw();
});
stage.start();
};
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
身体{
边际:0px;
填充:0px;
}
帆布{
边框:1px实心#9C9898;
}
window.onload=函数(){
//全局参数
var曲率=10;
var曲率=10;
var nodeRadius=10;
var阶段=新的动力学阶段({
容器:“容器”,
宽度:578,
身高:300
});
var layer=新的动能层();
var节点=[];
对于(var i=0;i您不能使用在函数外部声明的变量,并假设在该函数内部使用的变量值与声明该函数时的值相同
在循环变量的特殊情况下,在调用内部函数时,该变量将具有分配给它的最后一个值
要解决此问题,您必须在新范围内“关闭”外部变量的值,在您的情况下如下所示:
for (var i = 0; i < 9; ++i) {
...
drawFunc: (function(i) { // <------------+
return function() { // |
alert(i); // you can use this "i" here
}
})(i)
}
for(变量i=0;i<9;++i){
...
drawFunc:(function(i){//您将函数定义为对象的一部分,而不是显式调用它,AFAICT,因此它没有理由在循环中执行——因此框架正在调用它。这意味着框架中的某些东西对您的draw函数不满意。我会对“this”引用感到有点紧张,因为JS的“this”语义,如果这不是问题所在,那么它是特定于框架的其他内容。您不包含任何错误信息,因此无法提供帮助。是的,当到达“stage.add(layer);“a error”节点[i+1]未定义。引发此错误的原因是此时指示符i的值为9。尝试执行此函数会引发错误,因为它尝试获取节点[i+1],即节点[10]=>不存在。然后,绘图函数需要将循环“i”括起来值,有很多方法可以做到这一点,包括构建函数而不是简单地定义它。好吧,我不知道怎么做…?搜索SO或谷歌的javascript函数闭包或javascript循环值闭包等,这是一个非常常见的问题。此外,如果你不使用带有用户名的@tag,比如@seinecle,ppl可能永远不会知道这一点thx@Alnitak这很清楚。Just:为什么最后一个(i)位?@seinecle因为这就是“outer”i
的当前值如何传递给iLife的方式。@Altinak太好了,我学到了很多+我让代码工作起来了。非常感谢。