在Javascript中创建一个新对象

时间:2012-01-05 11:51:48

标签: javascript arrays object

我有这个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的累积数量。

3 个答案:

答案 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区分大小写(sS是两个不同的变量)。

为避免将来出现此类问题,您可以考虑使用最新版本的ECM提供的strict mode,即ECMAScript第5版。在严格模式中,您不再拥有horror of implicit globals。分配给不可解析的引用会导致错误。

为此,您需要在所有代码周围使用范围函数,并将"use strict";放在其顶部,如下所示:

(function() {
    "use strict";

    var currentShape = new Shape();

    function handleMouseDown() {
        // ...
    }

    function handleMouseMove() {
        // ...
    }

    // ...

})();

完全向后兼容与不支持新严格模式的JavaScript引擎,因此它不会给旧浏览器带来麻烦(你只是没有得到的好处严格模式)。

这也有一个优点,就是你不会将任何全局变量引入已经拥挤的全局变量空间。您的范围函数中的函数共享currentShape,但它和handleMouseDownhandleMouseMove都不是全局的。

这样做的一个副作用是,从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);
}

使用该代码,虽然每次调用currentShape都会设置为新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);
}