我有这个Class / Object:
function Shape(){
this.xArray = new Array();
this.yArray = new Array();
this.selectedColor;
}
在我的代码中,我不断创建对象并将它们添加到另一个数组中。像这样:
var shapes = new Array();
var current = new Shape();
function onmousemove(e){
current = new Shape(); // won't create a new ojbect!!
current.xArray.push(e.pageX, e.pageY);
......
shapes.push(current);
}
问题是我不断获得相同的对象,即使我创建了一个新形状。我是javascript的新手,我不确定这是否正确。
更新: 这是我的代码没有编辑:
function handleMouseDown(e)
{
currentshape = new Shape();
showMessage(currentShape.xArray.length);
currentShape.xArray.push(e.clientX- this.offsetLeft);
currentShape.yArray.push(e.clientY- this.offsetTop);
shapes.push(currentShape);
draw();
mouseDownFlag = true;
}
function handleMouseMove(e)
{
if(mouseDownFlag)
{
currentShape.xArray.push(e.clientX- this.offsetLeft);
currentShape.yArray.push(e.clientY- this.offsetTop);
draw();
}
}
showMessage函数只是改变一个div来显示结果 我不断从各种形状中获得xArray的累积数量。
答案 0 :(得分:3)
原谅我,但......为什么这样做?
恕我直言,最好有像
这样的东西function Shape(xx, yy, sc) {
this.x = xx;
this.y = yy;
this.selectedColor = sc;
}
var shapes = [];
function onmousemove(e) {
var cur = new Shape(e.pageX, e.pageY, "???");
shapes.push(cur);
}
但是在你的代码中(使用你的Shape对象)我觉得有一点问题(至少有一个不需要的数组):
var shapes= new Shape();
function onmousemove(e){
shapes.xArray.push(e.pageX); // Push the X
shapes.yArray.push(e.pageY); // push the Y
}
所以你只有一个形状数组,它包含2个数组(一个用于Xs,一个用于Ys)
答案 1 :(得分:3)
<强>更新强>
错误是handleMouseDown
中的这一行:
currentshape = new Shape();
您已使用currentshape
,而非currentShape
(使用大写字母S)。这会创建一个单独且无关的implicit global,而不是更新currentShape
,因为JavaScript区分大小写(s
和S
是两个不同的变量)。
为避免将来出现此类问题,您可以考虑使用最新版本的ECM提供的strict mode,即ECMAScript第5版。在严格模式中,您不再拥有horror of implicit globals。分配给不可解析的引用会导致错误。
为此,您需要在所有代码周围使用范围函数,并将"use strict";
放在其顶部,如下所示:
(function() {
"use strict";
var currentShape = new Shape();
function handleMouseDown() {
// ...
}
function handleMouseMove() {
// ...
}
// ...
})();
完全向后兼容与不支持新严格模式的JavaScript引擎,因此它不会给旧浏览器带来麻烦(你只是没有得到的好处严格模式)。
这也有一个优点,就是你不会将任何全局变量引入已经拥挤的全局变量空间。您的范围函数中的函数共享currentShape
,但它和handleMouseDown
或handleMouseMove
都不是全局的。
这样做的一个副作用是,从HTML标记中通过onXYZ
属性创建的事件处理程序引用的函数必须是全局的,因此如果您的所有函数都不是全局函数,则不能使用它们了;您使用addEventListener
/ attachEvent
来连接事件处理程序。无论如何,这通常是一个好主意,但是如果你绝对必须使用onXYZ
处理程序,你可以通过将选定的函数全局变量分配给window
上的属性来实现。 window.handleMouseMove = handleMouseMove;
(live example)。但是,一般情况下,最好避免使用任何全局变量并使用事件处理程序的addEventListener
/ attachEvent
(又称“DOM2”样式)。
在您发布真实代码之前的旧答案:
如果代码确实是引用的,那么每次调用Shape
时都会创建一个新的onmousemove
对象。
我怀疑您可能已经删除了实际导致问题的代码,在简化时将其添加到您的问题中。例如:
var shapes = new Array();
var current = new Shape();
var foo = current; // <<==== New code
function onmousemove(e){
current = new Shape();
current.xArray.push(e.pageX, e.pageY);
......
shapes.push(current);
}
使用该代码,虽然每次调用current
时Shape
都会设置为新onmousemove
,但foo
将始终指向初始 Shape
,因为变量foo
和变量current
之间没有持久的联系; current
可以获得新值而不会影响foo
所持有的值。
因此,如果您的真实代码具有类似的功能(将current
传递给函数,将其分配给另一个变量或其他任何变量),那就是问题。
答案 2 :(得分:1)
当前是一个全局变量。 只是尝试在函数内创建一个堆栈变量。
function onmousemove(e){
var temp = new Shape(); // won't create a new ojbect!!
temp.xArray.push(e.pageX, e.pageY);
......
shapes.push(temp);
}