[英]function not executed when creating objects in a loop - javascript
在以下代碼中,drawFunc在循環期間未執行(我可以看到,通過逐步調試,代碼僅跳至函數的末尾)。
該函數在“ stage.add(layer);”行執行,從而導致錯誤。
任何有關如何解決此問題的幫助?
<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>
您不能使用在函數外部聲明的變量,並且不能假定該變量在該函數內部使用時的值與聲明該函數時的值相同。
在循環變量的特定情況下,在調用內部函數時,該變量將被分配有最后一個值。
要解決此問題,您必須在新的作用域內“關閉”外部變量的值,在這種情況下,應如下所示:
for (var i = 0; i < 9; ++i) {
...
drawFunc: (function(i) { // <------------+
return function() { // |
alert(i); // you can use this "i" here
}
})(i)
}
現在,外觀異常的構造中有一個立即調用的函數表達式 ,該函數表達式已傳遞給循環變量i
,但現在在其作用域中具有該變量的本地綁定副本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.