JavaScript面試題總結系列(三)

3. JavaScript數組

3.1 數組經常使用方法

  • map: 遍歷數組,返回回調函數返回值組成的新數組,不改變原數組
  • forEach:沒法break,能夠用try/catch中throw new Error來中止
  • filter:過濾
  • some:有一項返回true,則總體爲true
  • every:有一項返回false,則總體爲false
  • join:經過指定鏈接符生成字符串
  • push / pop:末尾推入和彈出,改變原數組, 返回推入/彈出項
  • unshift / shift:頭部推入和彈出,改變原數組,返回操做項
  • sort(fn) / reverse:排序與反轉,改變原數組
  • concat:鏈接數組,不影響原數組, 淺拷貝
  • slice(start, end):返回截斷後的新數組,不改變原數組
  • splice(start, number, value):返回刪除元素組成的數組,value爲插入項,改變原數組
  • indexOf / lastIndexOf(value, fromIndex):查找數組項,返回對應的下標
  • reduce / reduceRight(fn(prev, cur), defaultPrev):兩兩執行,prev 爲上次化簡函數的return值,cur爲當前值(從第二項開始)

3.2 判斷數組

  • instanceof 方法
    • instanceof 運算符是用來判斷一個對象的原型鏈中是否是能找到類型的 prototypejavascript

      var arr = [];
      arr instanceof Array; // true
  • constructor 方法

    constructor屬性返回對建立此對象的數組函數的引用,就是返回對象相對應的構造函數html

    var arr = [];
    arr.constructor == Array; // true
  • isArray() 方法
    var a = new Array(123);
    var b = new Date();
    console.log(Array.isArray(a)); // true
    console.log(Array.isArray(b)); // false
  • Object.prototype.toString.call()

    這個在以前講判斷數據類型的文章裏說過,這裏再也不贅述。java

3.3 數組的遍歷

  • map和forEach的區別
    • map具備返回值,返回一個新的數組,不修改原數組;
      forEach沒有返回值,直接修改原數組
    • 從性能上來講,forEach的性能要略好於map。
      測試例子請狠狠點擊這裏
  • JavaScript數組和對象的遍歷方式,以及幾種方式的比較
    一般咱們會用循環的方式來遍歷數組。可是循環是 致使js 性能問題的緣由之一。通常咱們會採用下幾種方式來進行數組的遍歷
    • for in循環
    • for循環
    • forEach算法

      • 這裏的 forEach回調中兩個參數分別爲 value,index
      • forEach 沒法遍歷對象
      • IE不支持該方法;Firefox 和 chrome 支持
      • forEach 沒法使用 break,continue 跳出循環,且使用 return 是跳過本次循環
    • 這兩種方法應該很是常見且使用很頻繁。但實際上,這兩種方法都存在性能問題
    • 在方式一中,for-in須要分析出array的每一個屬性,這個操做性能開銷很大。用在 key 已知的數組上是很是不划算的。因此儘可能不要用for-in,除非你不清楚要處理哪些屬性,例如 JSON對象這樣的狀況
    • 在方式2中,循環每進行一次,就要檢查一下數組長度。讀取屬性(數組長度)要比讀局部變量慢,尤爲是當 array 裏存放的都是 DOM 元素,由於每次讀取都會掃描一遍頁面上的選擇器相關元素,速度會大大下降
    • ES6新增的 for of 循環。for in循環一般用來遍歷對象的Key,for of一般用來遍歷對象的Value。

3.4 數組去重

  • 利用雙重循環去判斷。聲明一個空數組,而後遍歷原數組,從原數組第一個元素開始往新的數組中放,若是沒有該值,則push進去,不然跳過,最後返回新數組。實現數組去重。
  • 使用ES的Set集合。

Set集合的特性之一是其集合中沒有重複的元素,所以能夠利用這一特性來實現數組去重的目的。舉例:chrome

var array2 = [...new Set([1,2,3,3,3,4,5])];
console.log(array2); // Array(5) [ 1, 2, 3, 4, 5 ]

3.5 數組亂序

  • 思路:使用sort()排序,或者使用洗牌算法。
  • 實現:
    • 建立一個數組
    let arr = Array(100000).fill(0).map((item, index) => index + 1);
      1. 直接利用sort進行排序,有漏洞,大部分元素位置沒有移動
    arr.sort((a, b) => (Math.random() > 0.5 ? -1 : 1));
    console.log(arr);
      1. 經典洗牌算法實現
    function shuffle(array) { 
        let arrayLength = array.length,   
            randomIndex, //隨機數   
            tempItem; //臨時存儲元素  
        for (let i = arrayLength - 1; i >= 0; i--) {    
            randomIndex = Math.floor(Math.random() * (i + 1));    
            tempItem = array[randomIndex];    
            array[randomIndex] = array[i];    
            array[i] = tempItem;  
        }  
        return array;
    }
    console.log(shuffle(arr));

3.6 數組的扁平化(數組降維/多維轉一維)

3.6.1 概念

數組的扁平化是指將一個多爲數組變爲一維數組。例如:
[1, [2, 3, [4, 5]]] ------> [1, 2, 3, 4, 5]

3.6.2 實現

  • ES10 數組新特性: Array.prototype.flat()方法

    flat()方法按照一個能夠指定的嵌套深度的參數來遞歸遍歷數組,並將全部元素以及遍歷到的子數組裏面的元素合併返回一個新數組。數組

    var arr = [true, function(){}, [{}, [2]]];
    var newArr = arr.flat(2);
    console.log(newArr); //  [true, ƒ, {…}, 2]
  • 遞歸。以下:
    function flatten(arr) {
        var res = [];
        arr.map(item => {
            if(Array.isArray(item)) {
                res = res.concat(flatten(item));
            } else {
                res.push(item);
            }
        });
        return res;
    }
  • 擴展運算符
    function flatten(arr) {
        while(arr.some(item=>Array.isArray(item))) {
            arr = [].concat(...arr);
        }
        return arr;
    }
  • reduce

    使用數組的reduce方法,遍歷數組中的每個項,若是某一項是數組,則繼續遍歷,不然concat(鏈接數組);
    舉例:dom

    function flatten(arr) {  
        return arr.reduce((result, item)=> {
            return result.concat(Array.isArray(item) ? flatten(item) : item);
        }, []);
    }
    var arr = [false, function(){}, [{}, [2]]];
    var arr2 = [1, [2,3],4,[5,[6,7]]];
    var newArr = flatten(arr); 
    var newArr2 = flatten(arr2);
    console.log(newArr); // [false, ƒ, {…}, 2]
    console.log(newArr2); // [1, 2, 3, 4, 5, 6, 7]

3.6.3 總結

實現數組扁平化的方法有不少,可是最核心的一點就是,遍歷數組,拿到數組的每一項,若是是數組,再繼續遍歷,直到每一項再也不是數組則中止。而後將這些項放到一個新的數組,最後將這個數組返回。數組降維,或者多維轉一維都和數組扁平化是一個道理。jsp


參考連接:
http://blog.poetries.top/FE-Interview-Questions/review/#_23-%E6%95%B0%E7%BB%84-array
http://www.javashuo.com/article/p-vgoowifc-cd.html
http://www.javashuo.com/article/p-vianslyj-cr.html https://juejin.im/post/5d391d336fb9a07ebe750343 http://www.javashuo.com/article/p-eergvfdv-h.html
http://www.javashuo.com/article/p-hlfxwuty-hq.html https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
相關文章
相關標籤/搜索