js學習過程當中的小問題

一個js初學者啦~想要記錄一下遇到的小問題。也但願和你們交流。javascript

1.Array#sort

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;
})

2.關於reduce的用法

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了。迭代過程以下:測試

  1. prev=1,cur = 2,而後prev+cur=3,返回結果。設計

  2. 返回值存入prev,接着進行第二次迭代。code

  3. 接着進行下一次迭代直至迭代完。遞歸

  4. 返回迭代結束後的結果。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的介紹。是這樣解釋這個問題的:
第一次執行回調函數時:

  1. 若是向 reduce 方法提供 initialValue:
    prev 參數爲 initialValue。
    cur 參數是數組中的第一個元素的值。

  2. 若是未提供 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
相關文章
相關標籤/搜索