你不知道的數組

數組定義

  • 數組是按序次分列的一組值
  • 每一個值都有編號,從0最先
  • 能夠在定義時賦值,也能夠先定義后賦值
  • 任何範例的數據都能夠存入數組

           
       const arr = [
           {a: 1},
           [1, 2, 3],
           function(){}
       ];

數組的實質

  1. 實質上,數組屬於一種特別的對象,它的鍵名是按序次分列的一組整數(0,1,2…)

    typeof [1, 2, 3] //”object”

  2. 數構成員的鍵名是牢固的,因而不用為每一個元素指定鍵名,而對象的每一個成員都必須指定鍵名

    const arr = [‘a’, ‘b’, ‘c’];
    Object.keys(arr) //[‘0’, ‘1’, ‘2’]

JavaScript言語劃定,對象的鍵名一概為字符串

const arr=['a', 'b', 'c'];
arr['0'] //'a'
arr[0] //'a'

之所以能夠用數值讀取,是因為非字符串的鍵名會被轉為字符串

注重:這一點在賦值時也建立!

let a = [];
a[1.00] = 6;
a[1] // 6

“1.00”轉成字符串是“1”

讀取數構成員的要領

  • object.key
  • object[key]

length屬性

  • 該屬性是一個動態的值,即是鍵名中的最大整數加1
  • 該屬性是可寫的,假如工資設置一個小於當前成員個數的值,該數組的成員就會自動削減到length設置的值

       let arr = ['a', 'b', 'c'];
       arr.length // 3
       arr.length = 2;
       arr // ['a', 'b']
    
  • 假如工資設置一個大於當前成員個數時,新增的位置都是空位,讀取新增的位置都邑返回undefined

       let arr = ['a'];
       arr.length = 3;
       arr[1] // undefined
    
  • 數組實質是一種對象,所以能夠為數組增加屬性,但並不影響length屬性的值

       let arr = [];
       arr['p'] = 'abc';
       arr.length // 0
       arr[2.1] = 'abc';
       arr.length // 0
       arr['1'] = 'a';
       arr.length // 2

in運算符

  • 搜檢某個鍵名是不是存在,適用於對象,也適用於數組
  • 鍵名都是字符串,數值會自動轉成字符串

       const arr = ['a', 'b', 'c'];
       2 in arr // true
       '2' in arr // true
       4 in arr // false
    
  • 假如數組的某個位置是空位,in運算符返回false

       let arr = [];
       arr[100] = 'a';
       100 in arr // true
       1 in arr // false

for…in輪迴和數組的遍歷

  • 能夠遍歷對象,也能夠遍曆數組(數組是一種特別對象)

       const arr = [1, 2, 3];
       for(let i in arr) {
           console.log(arr[i]);
       }
       // 1
       // 2
       // 3
    
  • 不僅會遍曆數組一切的数字鍵,還會遍歷非数字鍵

       let arr = [1, 2, 3];
       arr.foo = true;
       for(let key in arr) {
           console.log(key);
       }
       // 0
       // 1
       // 2
       // foo

數組的空位

當數組的某個位置是空元素(兩個逗號之間沒有任何值),我們稱該數組存在空位

const a = [1, , 1];
a.length // 3
  • 數組的空位不影響length屬性
  • 假如末了一個元素背面有逗號,並不會發生空位
  • 數組的空位是能夠讀取的,返回undefined
  • 運用delete刪除一個數構成員,會構成空位,但並不會影響length屬性

       let arr = [1, 2, 3];
       delete arr[1];
       arr[1] // undefined
       ar.length // 3

length屬性不過濾空位

假如是空位,運用數組的forEach要領、for…in構造、Object.keys要領舉行遍歷,空位都邑被跳過

const a = [, , ,];
a.forEach(function (con, key) {
    console.log(key + '.' + con);
})
// 不輸出任何內容

for(let key in a) {
    console.log(key);
}
// 不輸出任何內容

Object.keys(a)
// []

假如是undefined,遍用時不會被跳過

const a = [undefined, undefined, undefined];
a.forEach(function (con, key) {
    console.log(key + '.' + con);
});
// 0.undefined
// 1.undefined
// 2.undefined

for(let key in a) {
    console.log(key);
}
// 0
// 1
// 2

Object.keys(a)
// ['0', '1', '2']

也就是說,空位是數組沒有這個元素,不會被遍歷到,然則undefined示意數組有這個元素,它的值是undefined,所以會被遍歷到

map()

將數組的一切成員順次傳入參數函數,然後把每一次的實行效果構成一個新數組返回

let numbers = [1, 2, 3];
numbers.map(n => n+1); // [2, 3, 4]
console.log(numbers); // [1, 2, 3]

map要領接收一個函數作為參數,該函數挪用時,map要領向它傳入三個參數:當前成員、當前位置、數組自身

[1, 2, 3].map((elem, index, arr) => elem * index );
// [0, 2, 6]

map還能夠接收第二個參數,用來綁定回調函數內部的this變量

const arr = ['a', 'b', 'c'];
[1, 2].map(function(e) {
    return this[e];
}, arr);
// ['b', 'c']

假如數組有空位,map要領的回調函數在這個位置不會實行,會跳過數組的空位,然則不會跳過undefined和null

let f = (n) => 'a';
[1, undefined, 2].map(f) // ['a', 'a', 'a']
[1, null, 2].map(f) // ['a', 'a', 'a']
[1, , 2].map(f) // ['a', , 'a']

forEach()

對數組的一切成員順次實行參數函數,然則不返回值,只用來操縱數據

forEach的用法與map要領一致,參數是一個函數,該函數一樣接收三個參數:當前值、當前位置、全部數組

forEach要領也能夠接收第二個參數,綁定參數函數的this變量

forEach要領也會跳過數組的空位,然則不會跳過undefined和null

假如數組的遍歷是為了獲得返回值,就運用map(),不然就運用forEach()要領

相似數組的對象

假如一個對象的一切鍵名都是正整數或零,並且有length屬性,那末這個對象就很像數組,稱為“相似數組的對象”

const obj = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3,
}
obj[0] // 'a'
obj[1] // 'b'
obj.length // 3
obj.push('d') // TypeError: obj.push is not a function
  • 相似數組的對象的基礎特性是具有length屬性,然則這個length屬性不是動態值,不會跟着成員的變化而變化

    let obj = {

    length: 0,

    };
    obj[3] = ‘d’;
    obj.length // 0
    obj.foo = ‘hhh’;
    obj // {3: “d”, length: 0, foo: “hhh”}

  • 相似數組的對象不具備數組特有的要領

典範的“相似數組的對象”

1、arguments對象

function args() { return arguments }
const arrayLike = args('a', 'b');

arrayLike[0] // 'a'
arrayLike.length // 2
arrayLike instanceof Array // false

2、大多數DOM元素集

const elts = document.getElementsByTagName('p');
elts.length // 3
elts instanceof Array // false

3、字符串

'abc'[1] // 'b'
'abc'.length // 3
'abc' instanceof Array // false

類數組變成真正的數組

slice要領

let arr = Array.proptotype.slice.call(arryLike);

類數組運用數組的要領

經由過程call()把數組的要領放到對象上

function print(value, index) {
    console.log(index + ':' + value);
}
Array.prototype.forEach.call(arrayLike, print);

// 等同於for輪迴
function example() {
    for(let i=0; i< arguments.length; i++) {
        console.log(i + '.' + arguments[i])'
    }
}    

經由過程call(),把forEach()要領放到arrayLike上面挪用

    原文作者:pitaojin
    原文地址: https://segmentfault.com/a/1190000015092537
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞