变量,数组和for循环不按照应有的方式运行

时间:2014-12-24 11:55:24

标签: javascript

我正在制作一个数学库,因为0.1 + 0.2不是= 0.30000000000004。但我遇到了一个非常奇怪的问题

我有一个数组:

var array = [1,2,3,".",4,5,6];

我想把它分成两部分,所以我......

var part1 = array;
var part2 = array;

然后......

for (var i = 4; i < 7; i++) {
  part1[i] = 0;
};

所以现在part1 =

[1,2,3,".",0,0,0]

应该如此,但后来我遇到了这个问题。我之后...

for (i = 2; i > -1; i--) {
  part2[i] = 0;
};

Part1,part2和array now =

[0,0,0,".",0,0,0]

这不应该发生,part2应该=

[0,0,0,".",4,5,6]

但它没有

???

3 个答案:

答案 0 :(得分:2)

这是因为part1part2(显然array}变量都指向相同的内存地址,它存储相同的信息,因此如果你编辑任何一个三个数组中的更改将在所有数组中可见,因为您正在修改由三个不同变量表示的相同值。

要避免这种情况,你应该&#34;复制&#34;使用slice()或其他内容的数组,如for循环,但slice是我最喜欢的方法,也是最快输入的,所以你的代码将成为:

var part1 = array.slice();
var part2 = array.slice();

现在你可以做任何你想做的事情,数组将被视为不同的变量。

快速举例:

a = [1,2]
> [1, 2]
b = a.slice()
> [1, 2]
b[0] = 2
2
b
> [2, 2]
a
> [1, 2]

复制数组的最快方法:

如果您正在寻找紧固方法(因为有几种不同的方法可以复制数组),那么您应该检查 this benchmark test ,然后运行测试。最好的解决方案并不总是相同的,所以将来它可能会发生变化,具体取决于JS实现和您当前的浏览器版本,尽管slice()slice(0)concat()通常比其他方法更快。

答案 1 :(得分:1)

您必须复制数组:

var part1 = array.concat();// it is possible to use array.slice() too.
var part2 = array.concat();

如果没有,则始终修改同一个对象,因为part1和part2将引用数组变量。

另一方面,我不建议你构建自己的数学库只是为了解决JS中的浮点问题。 Have you read similar questions?

答案 2 :(得分:0)

您的代码中出现的问题是您没有创建阵列的克隆:arraypart1part2都指向同一个数组。您可以创建part1 = array.slice(0)

之类的副本

不是编写自己的数学库来解决浮点舍入错误,而是可以在math.js中使用BigNumbers:

// configure math.js to use BigNumbers by default
math.config({
  number: 'bignumber', // Default type of number: 'number' (default) or 'bignumber'
  precision: 64        // Number of significant digits for BigNumbers
});

// evaluate an expression
math.eval('0.1 + 0.2'); // BigNumber, 0.3

请参阅BigNumbers上的文档:http://mathjs.org/docs/datatypes/bignumbers.html