为什么我的值会在数组中变异?

时间:2014-06-24 23:26:22

标签: javascript

我写了一个小测试程序,探索我的问题,它按照我期望的方式工作,打印"四,五,六"。

var foo = function() {
    console.log("just one more test")
    var destination = new Array;
    data = [ "four", "five" , "six" ]
    var parent = [ 0, 1, 2 ];
    var something;
    parent.forEach(function(element) {
        something = data[element];
        destination.push(something);
    })
    destination.forEach(function (thing) {
        console.log(thing);
    })
}
foo();

但是在我的真实代码中,当我把东西推到我的可点击的'数组,所有条目都变异为' clicker'的当前值。变量。我的' scheme_list'中有3个条目,它们正确绘制,但是当我尝试构建要点击的区域时,在循环的每次迭代中#34;在循环中#34;为每个实例打印刚刚推送到数组的值。也就是说,' clicker'已经在循环中更改为clicker的当前值。我试图理解我的真实代码和我的测试代码之间的区别。或者,更重要的是,如何修复我的真实代码。

var layout_color_schemes = function(scheme_list) {

    var canvas = document.getElementById('color_picker_canvas');
    var ctx = canvas.getContext('2d');

    var x_upper_left = 5;
    var y_upper_left = 5;
    var width = 200;
    var height = 30;
    var clickables = new Array;
    var clicker = {};
    clicker.rect = {};
    clicker.rect.width = width;
    clicker.rect.height = height;

    scheme_list.forEach(function(row) {
        var grad = ctx.createLinearGradient(0, 0, 100, 0);
        var cscheme = jQuery.parseJSON(row.json);
        cscheme.forEach(function(color_point) {

            grad.addColorStop(color_point[0], 'rgb(' + color_point[1] + ','
                    + color_point[2] + ',' + color_point[3] + ')');
        })
        ctx.fillStyle = grad;
        ctx.fillRect(x_upper_left, y_upper_left, width, height);

        clicker.rect.x = x_upper_left;
        clicker.rect.y = y_upper_left;
        clicker.scheme = cscheme;
        clicker.name = row.name;
        clickables.push(clicker);
        printf("clickables size = %d", clickables.length)
        for (index = 0; index < clickables.length; ++index) {
            printf("Index is %d", index)
            printf("in the loop %j", clickables[index])
        }
        ctx.fillStyle = 'black'
        ctx.fillText(row.name, x_upper_left + width + 10, 5 + y_upper_left
                + (height / 2));

        y_upper_left = y_upper_left + height + 10;

    });
    clickables.forEach(function(area) {
        printf("before call clickable area = %j", area)
    });

    wire_clickables(clickables);

};

function wire_clickables(clickables) {
    clickables.forEach(function(area) {
        if (area.hasOwnProperty('rect')) {
            printf("wiring a clickable %j", area);

            $("#color_picker_canvas").mousemove(function(e) {
                var inside = false;
                var offsetX = e.pageX - $(this).position().left;
                var offsetY = e.pageY - $(this).position().top;

                if (area && contains(area.rect, offsetX, offsetY)) {
                    document.body.style.cursor = 'pointer'
                }
                else {
                    document.body.style.cursor = 'default'
                }
            })
        }
    })

}

function contains(rect, x, y) {
    return (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y
            + rect.height)
}

1 个答案:

答案 0 :(得分:2)

clicker对象存在于循环之外,因此您所做的就是将相同的引用推送到clickables。相反,您想要推送它的副本。有很多方法可以做到这一点,但在你的情况下,这可能是最简单的方法之一:

替换

clickables.push(clicker);

clickables.push(JSON.parse(JSON.stringify(clicker));

或者,在循环内移动clicker声明和初始化。