一、有时候在实际环境中我们需要做数组的排序比如:升序或者降序。
Array为我们提供了sort()方法,但是这个方法只是字符串的比较的,无论你数组的数据是Number类型还是字符串,都讲用使用方法toString()方法转换成字符串,然后进行比较,而字符串之间的比较是通过字符的ascii码来进行比较。
这种情况会出现:[2,15] 运行sort()方法之后,获取的顺序为[15,2]并不是我们想要的结果(通过首字符一次进行比较,如果比较出来大小不在进行比较,1的ascii 是49,而2是50 所以2排在前面),Array给我们提供一个sort中,为我们提供传入比较函数来进行比较。
书写规则:传入sort函数的内的参数函数,需要有两个参数。这个两个参数进行比较,val1>val2 返回1,反之返回1,相等返回0,这是升序。
需要注意:传入比较函数的参数,默认是2个参数,分别是比较的相邻的2个数组的2个参数。
升序:
1 <script type="text/javascript"> 2 var testArr=[1,4,2,3] 3 function comparNum(val1,val2){ 4 if(val1>val2){ 5 return 1; 6 }else if (val1<val2){ 7 return -1 8 }else{ 9 return 0 10 } 11 } 12 testArr.sort(comparNum); 13 console.log(testArr); 14 </script>
反序:
如果想要反序的数组则需要 讲上面的返回值进行修改。
1 <script type="text/javascript"> 2 var testArr=[1,4,2,3] 3 function comparNum(val1,val2){ 4 if(val1>val2){ 5 return -1; 6 }else if (val1<val2){ 7 return 1; 8 }else{ 9 return 0 10 } 11 } 12 testArr.sort(comparNum); 13 console.log(testArr); 14 </script>
如上是数组内的元素的是非对象进行比较。如果是对象我们可以进行如下比较:通过返回的函数的方式来写我们的比较函数,代码如下:
1 <script> 2 function compareObj(properName) { 3 return function (obj1,obj2) { 4 var value1=obj1[properName]; 5 debugger; 6 var value2=obj2[properName]; 7 debugger; 8 if(value1>value2){ 9 debugger; 10 return 1 11 }else if(value1<value2){ 12 debugger; 13 return -2 14 }else{ 15 return 0 16 } 17 } 18 } 19 20 var temArray= [{name: "Zachary", age: 28}, {name: "Nicholas", age: 29}]; 21 temArray.sort(compareObj('name')); 22 console.log(temArray); 23 temArray.sort(compareObj('age')); 24 console.log(temArray); 25 </script>
因为array.sort的方法进行排序,不会返回副本是直接修改我们的数组。而我们查看方式是通过console.log方式查看,这种方式查看的有个问题,因为我们输出的引用类型。所以大家会出现一个问题,就是前后排序的结果是一样的。
这是为什么呢?
这涉及到控制台输出问题,这时候你会有个疑问! 难道console.log是异步?NO NO
这是控制台的特性决定,我们做个试验,如下代码:
1 var temObj={name:'tom'}; 2 temObj.name='peter'; 3 console.log(temObj); 4 temObj.name='ok'; 5 console.log(temObj);
你看到的结果是改变,但是我们点击对象的时候却变成如下:
这是为什么呢?
这是因为我们在console.log()输出的时候输出的快照,当我们点击展开对象的时候,会从内存读取该值,实际上这个值已经被改变到最后的值,所以出现了都是'ok'情况,所以我们上面的例子的错误信息也是因为这种导致。
在一些资料中是这样解释控制台行为:
1 某些浏览器的console.log(..) 并不会把传入的内容立即输出。出现这种情况的主要原因是,在许多程序(不只是JavaScript)中,I/O 是非常低速的阻塞部分。所以,(从页面/UI 的角度来说)浏览器在后台异步处理控制台I/O 能够提高性能,这时用户甚至可能根本意识不到其发生。