为什么数组不能以适当的方式在JavaScript中存储复合类型?

时间:2017-08-02 19:36:59

标签: javascript arrays web

我有一个能够在一定范围内生成数字的函数。 我创建了一个这样的复合类型:

var cowPosition = {
    x: 0,
    y: 0
};

我还创建了一个数组:

var positionsArray = [];

然后,我继续迭代以使用复合类型填充数组。

所有这些都在一个返回数组的函数内。

这是功能:

function generateCowPositions(numberOfCows){
    var positionsArray = [];
    var cowPosition = {
        x: 0,
        y: 0
    };
    var x,y;

    for (var i = 0; i < numberOfCows; i++) {

        x = randomPosition(0,5);
        y = randomPosition(0,5);

        x = x * 80;
        y = y * 80;

        cowPosition.x = x;
        cowPosition.y = y;
        positionsArray[i] = cowPosition;
    }
    return positionsArray;

}

当我运行它时,它用最后两个生成的坐标填充整个数组。

5 个答案:

答案 0 :(得分:3)

没有&#34;复合型&#34;在JavaScript中。你所指的是一个对象。

您遇到的问题是对象是通过引用传递的,而不是通过值传递的。这意味着如果将对象存储到名为#include <iostream> #include <type_traits> template <typename T> struct uminus : std::integral_constant<typename T::value_type, - T::value> { }; template <typename T1, typename T2> struct add : std::integral_constant<typename T1::value_type, T1::value + T2::value> { }; template <int I> struct i : std::integral_constant<int, I> { }; int main () { constexpr auto val = add<i<5>, uminus<i<3>>>::value; std::cout << val << std::endl; // print 2 } 的变量中并在某个函数中对其进行修改,则/home/rijad/buildroot-2017.05.2/output/host/usr/bin/fakeroot -- /home/rijad/buildroot-2017.05.2/output/build/_fakeroot.fs fakeroot, while creating message channels: Function not implemented This may be due to a lack of SYSV IPC support. fakeroot: error while starting the `faked' daemon. kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec] fs/ext2/ext2.mk:42: recipe for target '/home/rijad/buildroot-2017.05.2/output/images/rootfs.ext2' failed make[1]: *** [/home/rijad/buildroot-2017.05.2/output/images/rootfs.ext2] Error 1 Makefile:79: recipe for target '_all' failed make: *** [_all] Error 2 中存储的值也将被修改。

您需要做的是:

&#13;
&#13;
a
&#13;
&#13;
&#13;

答案 1 :(得分:0)

因为代码中只有setDateFormat的一个实例。因此,循环的每次迭代只会更改一个对象,并且在循环结束时,您可以简单地保留最后一次迭代的结果。

答案 2 :(得分:0)

数组中的每个索引都指向完全相同的对象,即cowPosition

我不确定你想要100%完成什么,但你应该在每次迭代时创建一个新对象。不需要在对象中初始化x和y。

简单地说:

&#13;
&#13;
if (!snapchat.getKey().equalsIgnoreCase("Order")) {}
&#13;
&#13;
&#13;

答案 3 :(得分:0)

JavaScript是一种面向对象的语言,其中对象通过引用传递,而不是按值传递。我怀疑你正在考虑C和C ++,其中struct / class值默认由function generateCowPositions(numberOfCows){ var positionsArray = []; var cowPosition = {} var x,y; for (var i = 0; i < cantidadVacas; i++) { x = randomPosition(0,5); y = randomPosition(0,5); x = x * 80; y = y * 80; cowPosition.x = x; cowPosition.y = y; positionsArray[i]= Object.assign({}, cowPosition); } return positionsArray; }运算符完整地复制。在JavaScript中,它更接近于C#和Java,其中对象/非基元类型的副本被复制。

答案 4 :(得分:0)

javascript中的对象作为引用传递。

positionsArray[i] = cowPosition;positionsArray[i]设置为对cowPosition对象的引用。

循环之后,所有数组元素都引用相同的cowPosition对象。因此,由于数组的每个循环都会更改基础cowPosition对象,因此所有数组元素似乎都具有相同的xy位置。

这个问题的一个简单解决方案是浅层复制循环中的cowPosition对象,这样每个数组元素引用差异position对象并更改底层cowPosition对象对positionsArray内的浅拷贝没有影响,如下所示:

positionsArray[i] = JSON.parse(JSON.stringify(cowPosition));

这可以通过将对象转换为字符串并使用javascript的本机JSON实现再次返回来实现。