Tee*_*sic 0 javascript arrays sorting
我已经玩了一段时间了.为什么在运行函数对val b进行排序时val_a会发生变化?我怎么能绕过这个?当我单独运行该功能时,它们可以工作,但是当我将它们一起运行时,某些地方出了问题.
var GLOBALS = {"items":[]};
var val_a;
var val_b;
GLOBALS.items=[
{"thing":"one","val_a":0.5,"val_b":0.2},
{"thing":"two","val_a":0.2,"val_b":0.3},
{"thing":"three","val_a":0.3,"val_b":0.1}];
val_a = GLOBALS.items.sort(function (a, b) {
a=parseFloat(a.val_a);
b=parseFloat(b.val_a);
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
val_b = GLOBALS.items.sort(function (a, b) {
a=parseFloat(a.val_b);
b=parseFloat(b.val_b);
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
console.log("val_a",val_a);
console.log("val_b",val_b);Run Code Online (Sandbox Code Playgroud)
你看到你所看到的是什么原因val_a,val_b只是包含对同一个数组的引用,也引用了它GLOBALS.items.sort更改所有这三个变量所指向的数组的状态.
变量包含值,而不是对象.处理对象(包括数组)时,变量中的值是对象的引用,实际上存在于内存的其他位置.将该引用视为一个数字,告诉JavaScript引擎对象在内存中的其他位置.(更多信息如下.)
如果你想要三个独立的数组(原始的items,然后是一个排序的副本val_a,另一个排序的val_b),你想在排序之前制作一个浅的数组副本,你可以这样做slice:
val_a = GLOBALS.items.slice().sort(...);
Run Code Online (Sandbox Code Playgroud)
关于数组在内存中的其他地方,这是一个更简单的例子:
var a = [42]; // A variable with a reference to an array, which is
// elsewhere in memory
Run Code Online (Sandbox Code Playgroud)
这让我们记忆犹新:
+---------+
a<REF5512>--------->| (array) |
+---------+
| 0: 42 |
+---------+
(这REF5512完全是为了表明引用是一个值.我们永远不会看到原始引用值.)
如果我们这样做:
var b = a; // A copy of that same reference
Run Code Online (Sandbox Code Playgroud)
这让我们记忆犹新:
a<REF5512>---+
| +---------+
+----->| (array) |
| +---------+
b<REF5512>---+ | 0: 42 |
+---------+
如果我们改变数组的状态(例如,通过对它进行排序),那么任何变量都可以看到变化,因为它们都指向同一个数组:
b[0] = 67;
Run Code Online (Sandbox Code Playgroud)
给我们
a<REF5512>---+
| +---------+
+----->| (array) |
| +---------+
b<REF5512>---+ | 0: 67 | State of the array changed
+---------+
slice创建一个新数组,其中包含旧数组中值的副本(只是值; 数组中的对象不会被复制).例如:
b = a.slice();
Run Code Online (Sandbox Code Playgroud)
给我们:
+---------+
a<REF5512>--------->| (array) |
+---------+
| 0: 67 |
+---------+
+---------+
b<REF7341>--------->| (array) |
+---------+
| 0: 67 |
+---------+
注意引用如何b不再与in中相同a.
旁注:您的sort回调可以更简单:
val_a = GLOBALS.items.sort(function (a, b) {
return parseFloat(a.val_a) - parseFloat(b.val_a);
});
Run Code Online (Sandbox Code Playgroud)
该sort回调只是必须返回一个值小于零(它不必是具体-1),大于零(它不必是具体为1),或等于零.