一个js初学者啦~想要记录一下遇到的小问题。也但愿和你们交流。javascript
Array#sort方法在没有指定参数的状况下,是执行的是字符串的比较。以下列代码java
[0,-1,-2].sort();//=>[-1,-2,0]
和咱们预想的并不一致啊,既不是从小到大也不是从大到小。这是由于javascript的sort方法是将数字转换成字符串再检查。即先检查负号,而后1<2,故排列为-1,-2,0,和咱们预期的并不同。正确的写法以下(即须要传入一个用于比较的函数):数组
[-1,-2,0].sort(function(x,y){ return x-y;//从小到大 //return y-x; //从大到小 //或者是 return x<=y; })
Array.reduce()是能够传入两个参数,用于处理每一项的函数和迭代的初始值(可选)。基础的用法通常是用于求数组的和,这也是javascript高级程序设计书中的例子:函数
var values = [1,2,3,4,5]; var sum = values.reduce( function(prev,cur,index,array){ return prev+cur; }); console.log(sum);//15
其实也能够在reduce函数的第二个参数上加一个迭代初始值0,这里应该是默认是0了。迭代过程以下:测试
prev=1,cur = 2,而后prev+cur=3,返回结果。设计
返回值存入prev,接着进行第二次迭代。code
接着进行下一次迭代直至迭代完。递归
返回迭代结束后的结果。ip
这是javascript高级程序设计上面介绍的。然而我写了一个测试的代码。字符串
function reduceFunc(arr){ arr.reduce(function(prev,cur,index,array){ console.log(arguments); return prev+cur; },0); }
就是增长了一句打印每次迭代参数,并且initialValue给定了0的值。发现第一次的prev是0,但是第一个值应该是1对不对。javascript高级程序设计(第三版)中98页写道“第一次迭代发生在数组的第二项上,所以第一个参数是数组的第一项,第二个参数就是数组的第二项”。因此是书本有错吗?不尽然。我查到MSDN关于reduce的介绍。是这样解释这个问题的:
第一次执行回调函数时:
若是向 reduce 方法提供 initialValue:
prev 参数为 initialValue。
cur 参数是数组中的第一个元素的值。
若是未提供 initialValue:
prev 参数是数组中的第一个元素的值。
cur 参数是数组中的第二个元素的值。
通常状况下迭代的初始值不须要写,也就是
reduce(function(){ // });
这样用便可,可是若是存储每次迭代结果的是一个数组的话就不能这样啦。今天看到一个比较高级一点的用法。就是迭代结果是数组,先贴代码
var str = "name,age,hair\n Merble,35,red\nBob ,64, blonde"; function lameCSV(str){ return str.split("\n").reduce(function(table,row,index,array){ console.log(index); table.push(row.split(",").map(function(c){ return c.trim(); }) ); return table; }, []); }
代码大体就是实现一个把字符串解析成数组的形式。这里prev写的是table。若是说没有倒数第二行设置为空数组的话,table.push()是会报错的。由于如上文所说,若是不指定迭代初始值的话,第一次迭代prev(也就是table)的取值是1。显然1是没有Push方法的。
再来具体说说这个函数。
1. row每次分割以后返回trim()以后的值,table再将其push进去。 2. 接着返回table数组做为新一轮的迭代初值。进行下一行的迭代。 3. 而后reduce函数内的return语句会把table迭代结束的结果返回出来。函数运行结束。
reduce的每一次递归必需要有返回值,不然会出错
var arr = [1,2,3,4]; function Process(prev,cur){ if(prev!=3){ return prev+cur; } } arr.reduce(Process);//NaN
这一点map也有类似性质
function mapFunc(value){ if(value!=2){return value;} } arr.map(mapFunc);//undefined