你不知道的數組

數組定義

  • 數組是按次序排列的一組值
  • 每一個值都有編號,從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']this

JavaScript語言規定,對象的鍵名一概爲字符串prototype

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

之因此能夠用數值讀取,是由於非字符串的鍵名會被轉爲字符串code

注意:這一點在賦值時也成立!對象

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

「1.00」轉成字符串是「1」ip

讀取數組成員的方法

  • object.key
  • object[key]

length屬性

  • 該屬性是一個動態的值,等於鍵名中的最大整數加1
  • 該屬性是可寫的,若是人爲設置一個小於當前成員個數的值,該數組的成員就會自動減小到length設置的值字符串

    let arr = ['a', 'b', 'c'];
       arr.length // 3
       arr.length = 2;
       arr // ['a', 'b']
  • 若是人爲設置一個大於當前成員個數時,新增的位置都是空位,讀取新增的位置都會返回undefinedget

    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"}

  • 相似數組的對象不具有數組特有的方法

典型的「相似數組的對象」

一、arguments對象

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

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

二、大多數DOM元素集

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

三、字符串

'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上面調用

相關文章
相關標籤/搜索