js 你不知道的 Array

1、在類數組對象上覆用通用的數組方法

類數組有:arguments, NodeList, 字符串javascript

什麼是類數組? 兩個條件java

  1. 具備 length 屬性數組

  2. length 屬性大於該對象的最大索引瀏覽器

好比:函數

var arrayLike = { 0: "a", 1: "b", 2: "c", length: 3};
  var result = Array.prototype.map.call(arrayLike, function(s) {
    return s.toUpperCase();
  });//["A", "B", "C"]

幾乎全部的數組方法都是通用的(forEach,slice,map ...) 除了 concat。測試

由於 concat 在鏈接時,會檢查其參數的 [[Class]] 屬性。this

一些方法,好比 join,僅僅讀取他們被調用的對象的長度和數值屬性。 另外,像 reverse 同樣,要求對象的數值屬性和長度屬性是可變的;所以,這些方法不能在像 String 這樣的對象上被調用,String不容許它的長度屬性和synthesized的數值屬性被設置。prototype

function namesColumn() {
    return ['Names'].concat(arguments);
  }
  namesColumn("alice", "arale");//["Names", {0: "alice", 1: "arale"}]

  //解決辦法:應先使用 slice 將 arguments 轉爲數組
  function namesColumn() {
    return ['Names'].concat([].slice.call(arguments));
  }

2、數組優先使用 for 循環,而不是 for in 循環。

for in 更多的是用於 遍歷對象,可是 它也會去檢查 對象的原型。設計

若是瀏覽器支持 for of (ES6)的話,最好是使用它,它不會去遍歷原型。code


3、迭代優於循環

一個緣由是,迭代能夠消除不必的 終止條件任何數組索引

好比:

for (var i = 0; n = players.length; i < n; i++) {
    players[i].score++;
  }

  //使用迭代
  players.forEach(function(p){
    p.score++;
  });

例1: 對數組每個元素操做後生成一個新的數組

//得到全部輸入框去除多餘空格後的值
  var trimmed = input.map(function(s) {
    return s.trim()
  })

例2: 獲取價格在特定區間的列表

listings.filter(function(listing) {
    return listing.price >= min && listing.price <= max
  })

固然這都是 ES5 的方法,咱們也能夠本身寫一個。

function takeWhile(a, pred) {
    var result = []
    for (var i = 0; n = a.length; i < n; i++) {
      if (!pred(a[i], i)) {
       break
      }
      result[i] = a[i]
    }
    return result
  }

  var prefix = takeWhile([1, 2, 4, 8, 16, 32], function(n) {
    return n < 10
  }) // [1, 2, 4, 8]

把它加在 Array 上

Array.prototype.takeWhile = function(pred) {
    var result = []
    for (var i = 0; n = this.length; i < n; i++) {
      if (!pred(this[i], i)) {
        break
      }
      result[i] = this[i]
    }
    return result
  }

  [1, 2, 4, 8, 16, 32].takeWhile(function(n) {
    return n < 10
  }) // [1, 2, 4, 8]

循環僅一點優於迭代: 控制流操做 如 break 和 continue

ES5 中 只有 some 和 every 能夠提早終止循環, 但設計他們的本意不是用來提早終止循環。

// some 一旦回調產生了一個真值,則當即返回,不會執行其他的元素
[1, 10, 100].some(function(x) { return x > 5 }) //true
[1, 10, 100].some(function(x) { return x < 0 }) //false
// every 相反, 一旦產生假值,則當即返回,不會執行其他元素
[1, 2, 3, 4, 5].every(function(x) { return x > 0 }) //true
[1, 2, 3, 4, 5].every(function(x) { return x < 3 }) //false

這種行爲能夠用來實現 forEach 提早終止循環的變種時派上用場

function takeWhile(a, pred) {
    var result = [];
    a.every(function(x, i) {
      if (!pred(x)) {
        return false //break
      }
      result[i] = x;
      return true; //continue
    })
    return result
  }

4、數組方法分類

1. Mutator 方法

這些方法能夠改變數組自身

  • pop : 移除數組的最後一個元素,返回值是被刪除的元素。

  • push : 在數組的末尾添加一個或者多個元素,返回值是新的數組的長度。

  • reverse : 顛倒數組中元素的順序,原先第一個元素如今變成最後一個,一樣原先的最後一個元素變成了如今的第一個,也就是數組的索引起生了變化。

  • shift : 刪除數組的第一個元素,返回值是刪除的元素

  • sort : 對數組中的元素進行排序

  • splice : 添加或刪除數組中的一個或多個元素。

  • unshift : (將廢棄)添加一個或者多個元素在數組的開頭,返回值是新的數組的長度。


2. Accessor 方法

這些方法不改變數組自身

  • concat : 返回一個包含此數組和其餘數組和/或值的結合的新數組

  • indexOf : 返回第一個與給定參數相等的數組元素的索引,沒有找到則返回-1

  • join : 將全部的數組元素鏈接成一個字符串

  • lastIndexOf : 返回在數組中搜索到的與給定參數相等的元素的最後(最大)索引

  • slice : 返回數組中的一段。

  • toString : 返回表明該數組及其元素的字符,重寫Object.toString 過程.

  • valueOf : 重寫Object.valueOf過程。


3. 循環(迭代) 方法
  • filter : 對數組中的每個元素調用參數中指定的過濾函數,並將對於過濾函數返回值爲true的那些數組元素集合爲新的數組返回。

  • forEach : 對數組的每個元素依次調用參數中指定的函數。

  • every : 若是數組中每個元素都知足參數中提供的測試函數,則返回真

  • map : 建立一個新數組,新數組中含有,分別對於原來數組的每個元素調用一個給定函數的結果

  • some : 若是數組中至少有一個元素知足參數函數的測試,則返回true。

相關文章
相關標籤/搜索