我对javascript代码中发生的事情感到非常困惑。我正在尝试编写一个函数,该函数将创建一个随机点数组。然而,当我在循环内记录数组(其功能是向数组添加点),然后在循环外再次记录时,我会打印出两个不同的数组。
第一个,如随机X,Y点的列表所预测的,但第二个日志只包含最后输入的X,Y点将。
function Pick()
{
var numPoints = 4 * Math.floor(4+Math.random()*5);
var chosen_pts = [];
var lastPt;
for(var i = 0;i<numPoints;i++)
{
if(chosen_pts.length==0)
{
var temp = new Point(Math.floor(Math.random()*250),Math.floor(Math.random()*250));
var newPt = pickClose(temp);
chosen_pts.push(newPt);
lastPt = newPt;
}
else{
var newPt = pickClose(lastPt);
chosen_pts.push(newPt);
}
console.log(chosen_pts[i]); //LINE 106
}
console.log("noutside of the loop:")
for(var i = 0;i<numPoints;i++)
{
console.log(chosen_pts[i]); //LINE 111
}
}
参见控制台照片控制台阵列1控制台阵列2
编辑:
function pickClose(lastPt)
{
var x = lastPt["X"];
var y = lastPt["Y"];
var dx = 0;
var dy = 0;
var rand = Math.floor(1+Math.random()*100);
if(rand<50){
dx = 1+Math.floor(Math.random()*10);
dy = 1+Math.floor(Math.random()*10);
if( (dx+dy)%3==0 ){
dx*=-1;
}
}
else if(rand<80)
{
dx = 1+Math.floor(Math.random()*25);
dy = 1+Math.floor(Math.random()*25);
if( (dx+dy)%3==0 ){
dy*=-1;
}
}
else{
dx = 1+Math.floor(Math.random()*60);
dy = 1+Math.floor(Math.random()*60);
if( (dx+dy)%4==0 ){
dx*=-1;
dy*=-1;
}
}
if( (x+dx) < 500&& (x+dx) >=0 )
lastPt["X"]+=dx;
else
lastPt["X"]-=dx;
if( (y+dy) < 500&& (y+dy) >=0 )
lastPt["Y"]+=dy;
else
lastPt["Y"]-=dy;
return lastPt;
}
看起来很乱,但本质上我想要一个不同的值范围来根据初始随机数随机选择(dx,dy)。
pickClose
函数始终返回传递的元素。javascript中的对象通过引用传递,因此您稍后对该对象所做的任何更改也将应用于对已存储对象的所有其他引用。
澄清:
var point1 = new Point(1, 2);
var point2 = pickClose(point1);
// inside pickClose, parameter lastPt = point1:
lastPt["X"] += dx; // <- this also alters point1!
lastPt["Y"] += dy; // <- this also alters point1!
因此,如果你想在函数中返回一个新的Point
(而不是更改传递的),你必须创建一个新的对象来更改并返回:
var newX = x, newY = y;
// instead of:
lastPt["X"]+=dx;
// do:
newX += dx;
// then, at the bottom, instead of
return lastPt;
// create a new instance
return new Point(newX, newY);
您的pickClose函数将lastPt作为引用,因此您正在修改数组中已经存在的Point并再次添加它。
试着把103号线改成:
var newPt = pickClose(new Point(lastPt.X, lastPt.Y));