js中可以使用sort进行数组的排序, 比如下面的代码, 我们把json数组分别按年龄升序和降序排列:
var arr = [
{'name':'aben18', age:18},
{'name':'aben21', age:21},
{'name':'aben16', age:16},
{'name':'aben12', age:12},
{'name':'aben23', age:23},
];
//升序排列
arr.sort(function(a,b){
return a.age - b.age;
});
console.log(arr);
//降序排列
arr.sort(function(a,b){
return b.age - a.age;
});
console.log(arr);
但是在使用console.log打印结果时, 出现了意外的结果:
从上面的截图中可以看到, 打印出来的结果是一样的, 都是最终排序后的数据, WAF?
是console.log出问题了? 那我们调整下代码, 在第二次排序之前, for循环打印变量:
var arr = [
{'name':'aben18', age:18},
{'name':'aben21', age:21},
{'name':'aben16', age:16},
{'name':'aben12', age:12},
{'name':'aben23', age:23},
];
//升序排列
arr.sort(function(a,b){
return a.age - b.age;
});
console.log(arr);
//这里增加了for循环打印
for(var k in arr){
console.log(arr[k].name, ',', arr[k].age);
}
//降序排列
arr.sort(function(a,b){
return b.age - a.age;
});
console.log(arr);
执行结果:
结果中显示, 在第一次升序排列后, for循环打印出来的数据是正常的.
maybe是sort处理影响了变量.
我们现在改变打印的变量的类型, 把数组序列化成字符串打印:
var arr = [
{'name':'aben18', age:18},
{'name':'aben21', age:21},
{'name':'aben16', age:16},
{'name':'aben12', age:12},
{'name':'aben23', age:23},
];
//升序排列
arr.sort(function(a,b){
return a.age - b.age;
});
console.log(JSON.stringify(arr));
//降序排列
arr.sort(function(a,b){
return b.age - a.age;
});
console.log(JSON.stringify(arr));
执行结果:
上面的结果, 才是我们期望的样子.
我们先来验证一下console.log有没有问题:
var arr3 = [
{'name':'aben1', age:18},
{'name':'aben2', age:21},
{'name':'aben3', age:16},
];
console.log(arr3);
arr3 = [
{'name':'aben11', age:18},
{'name':'aben12', age:21},
{'name':'aben13', age:16},
];
console.log(arr3);
一切正常. console.log时的变量获取没有问题.
那怀疑的对象就剩 sort 了!
var arr = [
{'name':'aben1', age:18},
{'name':'aben2', age:21},
{'name':'aben3', age:16},
];
console.log(arr);
//升序排列
arr.sort(function(a,b){
return a.age - b.age;
});
console.log(arr);
这该怎么解释呢? 我们的变量都是先定义, 然后再执行操作的, 不存在预编译造成的先后顺序问题
试试简单的一维数组, 会直观的看到不同的效果 (一维数组不需要展开就能看到数据)
var points = [40,100,1,5,25,10];
console.log(points);
显示正常.
然后我们给它排个序:
var points = [40,100,1,5,25,10];
console.log(points);
//升序排列
points.sort(function(a,b){
return a - b;
});
console.log(points);
Oh, my! ......................., 这难道是console.log数据展开显示的bug???
console.log为了方便我们阅读, 会自动按key排序后显示出来.
如果是json字符串, JOSN.parse处理会自动按key排序.
注意:
在 js 中一切实例皆是对象,具体分为 原始类型 和 合成类型 :
-
原始类型 对象指的是 Undefined 、 Null 、Boolean 、Number 和 String ,按值传递。
-
合成类型 对象指的是 array 、 object 以及 function ,按址传递,传递的时候是内存中的地址。
克隆或者拷贝分为2种: 浅度克隆 、 深度克隆 。
-
浅度克隆 :基本类型为值传递,对象仍为引用传递。
-
深度克隆 :所有元素或属性均完全克隆,并于原引用类型完全独立,即,在后面修改对象的属性的时候,原对象不会被修改。