2016-11-21

JavaScript 5 新增了 9 個 Array Methods

JavaScript 正式的名稱為 EcmaScript(以下稱 ES),在 ES 5 時新增了 9 個 Array 相關的 method:
  • forEach
  • map
  • filter
  • every
  • some
  • reduce
  • reduceRight
  • indexOf
  • lastIndexOf

這些新 method 有一些共通點:

  • 可以傳入兩個參數,第一個為必要的 function,第二個為非必要的 calling context。
    • 會依序對 Array 裡每個值呼叫該 function。
    • 如果 Array 裡有空格,則會跳過不執行傳入的 function。
    • 會傳入三個參數到該 function 裡。
      • Array 裡輪到的值
      • 輪到值在 Array 裡的 index
      • 整個 Array:唯一可以修改 Array 的地方
    • function 回傳的值會「影響」Array method 回傳的值,但不是每個 method 都會有回傳值。
    • calling context 就是作為第一個 function 參數的執行主體,也就是 function 裡 this 指向的物件。
  • 這些 Array method 原則上不會修改 Array 內容,除非是對第一個傳入參數 function 裡的第三個參數(整個 Array,上面紅字處)進行操作。
  • 這些共通點,大部分 method 都有,但不是每個都有。

forEach

原則上會掃過 Array 中每個值,沒有回傳值,所以傳入的 function 也不需要回傳,常用來「掃過」每個值,可以用來加總或者找東西。

傳入標準三個參數:值、index與 Array。

不會修改 Array 內容,除非上述紅字的例外。

forEach 沒有像 break 那樣提早中斷迴圈的機制,只能在 function 裡丟出 error,然後再用 try-catch 把整個 forEach 包起來,以免中斷後續程式的進行。
var array = [1, 2, 3, 4];

// 加總
var sum = 0;
array.forEach(function(value, index, array) {
  sum += value;
});
console.log(array + ' > ' + sum); // 1,2,3,4 > 10

// 修改原 Array
array.forEach(function(value, index, array) {
  array[index] = value * value; // 平方
});
console.log(array); // [1, 4, 9, 16]

map

會掃過 Array 中每個值。

function 必須要回傳,回傳值組成新的 Array,作為 map 的回傳。

傳入標準三個參數:值、index與 Array。

不會修改 Array 內容,除非上述紅字的例外。

若原 Array 裡有空格,回傳的 Array 也會有一樣的空格、一樣的 Array 長度。
var array = [1, 2, 3, 4];

// 建立新 Array
var new_array = array.map(function(value, index, array) {
 return value * value; // 平方
});
console.log(new_array); // [1, 4, 9, 16]

filter

會掃過 Array 中每個值。

function 必須要回傳布林值,或者可以轉為布林值的值,以決定該值是否要加入新的 Array,作為 filter 的回傳。

傳入標準三個參數:值、index與 Array。

跳過 Array 中的空格,因此回傳的 Array 一定是緊實的,可以用 filter 來緊實 Array。
var array = [1, , 3, 4];

// 緊實 Array
var new_array = array.filter(function(value, index, array) {
return true; // 所以值都要,只會剔除空格
});
console.log(new_array); // [1, 3, 4]
或者進一步用來過濾無效的值(undefined 或 null)。
var array = [ 1, , 3, null, 4, undefined ];

// 緊實 Array
var new_array = array.filter(function(value, index, array) {
  return value !== undefined && value !== null; // 過濾無效的值
});
console.log(new_array); // [1, 3, 4]

every 與 some

可能不會掃過 Array 中每個值。

傳入標準三個參數:值、index與 Array。

function 必須回傳布林值,或者可以轉為布林值的值。

不會修改 Array 內容,除非上述紅字的例外。

every只有在每個值的 function 都回傳 true 時才會回傳 true。

而 some 只要有一個值的 function 回傳 true 就會回傳 true。

every 只有在每個值的 function 都回傳 true 時才會掃過所有值,不然在一遇到 false 就結束了。

而 some 則是在每個值的 funcion 都回傳 false 時才會掃過所有值,不然在一遇到 true 就結束了。

對於空 Array 來說,every 回傳 true,some 回傳 false。
var array = [ 1, 2, 3, 4 ];

// 檢查陣列
var valid = array.every(function(value, index, array) {
  return value !== undefined && value !== null; // 檢查無效的值
});
console.log(valid); // true,全部都是有效的值

// 檢查偶數陣列
var valid = array.every(function(value, index, array) {
  return value % 2 === 0; // 檢查偶數
});
console.log(valid); // false,不是所有數值都是偶數

array = [ 1, , 3, null, 4, undefined ];

//檢查陣列
var valid = array.every(function(value, index, array) {
  return value !== undefined && value !== null; // 檢查無效的值
});
console.log(valid); // false,至少有一個無效的值
var array = [ 1, 2, 3, 4 ];

// 檢查偶數陣列
var valid = array.some(function(value, index, array) {
  return value % 2 === 0; // 檢查偶數
});
console.log(valid); // true,至少有一個是偶數

// 檢查數值陣列
var valid = array.some(isNaN); // 是否有非數值
console.log(valid); // false,全部都是數值

reduce 與 reduceRight

掃過 Array 中每個值。

只會回傳一個值,常用來找最大值或者最小值。

第二個參數不是 calling context,而是初始值。

也不是傳入標準的三個參數(值、index與 Array)到 function 裡,而是傳入兩個參數。

如果有設定初始值:

  • 第一次呼叫時,傳入 function 的參數為初始值與 Array 裡的第一個值
  • 第二次呼叫時,傳入第一次呼叫 function 的回傳值與 Array 裡的第二個值
  • 以下類推,直到 Array 最後一個值
如果沒有設定初始值:

  • 第一次呼叫時,傳入 function 的參數為 Array 裡的第一個與第二個值
  • 第二次呼叫時,傳入第一次呼叫 function 的回傳值與 Array 裡的第三個值
  • 以下類推,直到 Array 最後一個值
var array = [ 1, 2, 3, 4 ];

var sum = array.reduce(function(x, y) {
  return x + y; // 加總
}, 0);
console.log(sum); // 10,其實在加總的情況下,可以不用傳入第二個參數 0

var product = array.reduce(function(x, y) {
  return x * y; // 階乘
}, 1);
console.log(product); // 24,其實在階乘的情況下,可以不用傳入第二個參數 1

var max = array.reduce(function(x, y) {
  return x > y ? x : y; // max
}, 1);
console.log(max); // 4
如果是空 Array,而且沒有傳入初始值,那會丟出錯誤。

如果 Array 只有一個值,然後沒有傳入初始值,那就是回傳 Array 的唯一的值。

如果是空 Array,但是有傳入初始值,那就是回傳初始值。

reduceRight 的行為與 reduce 完全相同,只有一個例外,就是掃描 Array 裡的值時,不是從第一個掃到最後一個,而是從最後一個掃到第一個。

由於 reduce 與 reduceRight 不能傳入 calling context,如果有需要指定 this,可以用 Javascript 原本的作法 bind。

reduce 與 reduceRight 不只可以用來做數值的計算,只要是接收兩個參數,然後回傳一個參數的 function 都可以丟到 reduce 與 reduceRight 裡。

indexOf 與 lastIndexOf

看起來很熟悉的 method,怎麼會是新加的呢?原來之前的 indexOf 與 lastIndexOf 是 String 的 method,這一次是 Array 的。

傳入的參數和之前的 method 非常的不一樣,第一個參數是要找的值,第二個參數是開始尋找的 Array Index,回傳的是找到的 index。

若未指定第二個參數,indexOf 預設為 0,lastIndexOf 預設為 Array.length - 1。

第二個參數可以用負值,用法同 splice,-1 表示最後一個 Array 值。

---
---
---

沒有留言:

張貼留言