国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript數(shù)組的十八般武藝

bergwhite / 1163人閱讀

摘要:返回值返回數(shù)組新的長度。可選整數(shù),表示要移除的數(shù)組元素的個數(shù)。返回值由被刪除的元素組成的一個數(shù)組。新增語法參數(shù)用來填充數(shù)組元素的值。

維護了一個持續(xù)更新的github筆記,可以去看看,誠意之作(本來就是寫給自己看的……)鏈接地址:Front-End-Basics

此篇文章的地址:JavaScript的數(shù)組

基礎(chǔ)筆記的github地址:https://github.com/qiqihaobenben/Front-End-Basics ,可以watch,也可以star。

正文開始

數(shù)組
數(shù)組是值的有序集合,每個值叫做一個元素,而每個元素在數(shù)組中有一個位置,以數(shù)字表示,稱為索引。

JavaScript數(shù)組的索引是基于零的32位數(shù)值,第一個元素索引為0,數(shù)組最大能容納4294967295(即2^32-1)個元素。

JavaScript數(shù)組是動態(tài)的,根據(jù)需要它們會增長或縮減,并且在創(chuàng)建數(shù)組時無需聲明一個固定的大小或者在數(shù)組大小變化時無需重新分配空間。

JavaScript數(shù)組可能是稀疏的,數(shù)組元素的索引不一定要連續(xù)的,它們之間可以有空缺。

每個JavaScript數(shù)組都有一個length屬性,針對非稀疏數(shù)組,該屬性就是數(shù)組元素的個數(shù)。針對稀疏數(shù)組,length比所有元素的索引都要大。

創(chuàng)建數(shù)組 1、最簡單的方法是使用數(shù)組直接量(字面量)創(chuàng)建數(shù)組。
var empty = [];     //沒有元素的數(shù)組
var arr = [1.1, true, "a",];    //3個不同類型的元素和結(jié)尾的逗號

數(shù)組直接量中的值也不一定必須是常量,它們可以是任意的表達式:

var number = 1;
var list = [number, number+1, number+2];

如果省略數(shù)組直接量中的某個值,省略的元素用empty表示(就是沒有這個元素),訪問的話會返回undefined。

var count = [1,,3];     // 數(shù)組打印出來是(3) [1, empty, 3], count[1] === undefined是true。
var undefs = [,,];      // 數(shù)組直接量語法允許有可選的結(jié)尾的逗號,顧[,,]只有兩個元素而非三個,undefs.length 是 2
2、構(gòu)造函數(shù)Array()創(chuàng)建數(shù)組

調(diào)用時沒有參數(shù),等同于[],創(chuàng)建一個沒有任何元素的空數(shù)組

var arr = new Array();

調(diào)用時有一個數(shù)值參數(shù),它指定長度

var arr = new Array(10)     // (10) [empty × 10]

顯式指定兩個或者多個數(shù)組元素或者數(shù)組元素的一個非數(shù)值元素

var arr = new Array(1,2,3,"one");
3、ES6的一些方法

(1)Array.of() 返回由所有參數(shù)組成的數(shù)組,不考慮參數(shù)的數(shù)量或類型,如果沒有參數(shù)就返回一個空數(shù)組 (ES6新增)

參數(shù):

elementN 任意個參數(shù),將按順序成為返回數(shù)組中的元素。

注意:

of() 可以解決上述構(gòu)造器因參數(shù)個數(shù)不同,導(dǎo)致的行為有差異的問題(參數(shù)只有一個數(shù)值時,構(gòu)造函數(shù)會把它當(dāng)成數(shù)組的長度)。

Array.of(1,2,3); // [1,2,3]
Array.of(1,{a:1},null,undefined) // [1, {a:1}, null, undefined]

// 只有一個數(shù)值參數(shù)時
let B = new Array(3);   // (3) [empty × 3]
let C = Array.of(3);    // [3]

返回值: 新的 Array 實例。


(2)Array.from()從一個類數(shù)組或可迭代對象中創(chuàng)建一個新的數(shù)組 (ES6新增)

參數(shù):

第一個參數(shù):想要轉(zhuǎn)換成數(shù)組的類數(shù)組或可迭代對象

第二個參數(shù)(可選):回調(diào)函數(shù),類似數(shù)組的map方法,對每個元素進行處理,將處理后的值放入返回的數(shù)組。

第三個參數(shù)(可選):綁定回調(diào)函數(shù)的this對象

// 有l(wèi)ength屬性的類數(shù)組
Array.from({length:5},(v,i) => i)     //[0, 1, 2, 3, 4]

// 部署了Iterator接口的數(shù)據(jù)結(jié)構(gòu) 比如:字符串、Set、NodeList對象
Array.from("hello")    // ["h","e","l","l","o"]
Array.from(new Set(["a","b"]))   // ["a","b"]

// 傳入一個數(shù)組生成的是一個新的數(shù)組,引用不同,修改新數(shù)組不會改變原數(shù)組
let arr1 = [1,2,3]
let arr2 = Array.from(arr);
arr2[1] = 4;
console.log(arr1,arr2)
//[1, 2, 3] [1, 4, 3]

返回值: 新的 Array 實例。

知識點

//數(shù)組合并去重
function combine(){
    let arr = [].concat.apply([], arguments);  //沒有去重復(fù)的新數(shù)組,之后用Set數(shù)據(jù)結(jié)構(gòu)的特性來去重
    return Array.from(new Set(arr));
}

var m = [1, 2, 2], n = [2,3,3];
console.log(combine(m,n));


數(shù)組方法

1、會改變原數(shù)組的方法 1. push() 方法在數(shù)組的尾部添加一個或多個元素,并返回數(shù)組的長度

參數(shù): item1, item2, ..., itemX ,要添加到數(shù)組末尾的元素

let arr = [1,2,3];
let length = arr.push("末尾1","末尾2");     // 返回數(shù)組長度
console.log(arr,length)
// [1, 2, 3, "末尾1", "末尾2"] 5

返回值: 數(shù)組的長度


2. pop() 方法刪除數(shù)組的最后一個元素,減小數(shù)組長度并返回它刪除的值

參數(shù):無

//組合使用push()和pop()能夠用JavaScript數(shù)組實現(xiàn)先進后出的棧
let stack = [];
stack.push(1,2) // 返回長度2,這時stack的值是[1,2]
stack.pop()     // 返回刪除的值2,這時stack的值是[1]

返回值: 從數(shù)組中刪除的元素(當(dāng)數(shù)組為空時返回undefined)。


3. unshift() 方法在數(shù)組的頭部添加一個或多個元素,并將已存在的元素移動到更高索引的位置來獲得足夠的空間,最后返回數(shù)組新的長度

參數(shù): item1, item2, ..., itemX ,要添加到數(shù)組開頭的元素

let arr = [3,4,5];
let length = arr.unshift(1,2);  // 返回長度是5
console.log(arr, length)
//[1, 2, 3, 4, 5] 5

注意: 當(dāng)調(diào)用unshift()添加多個參數(shù)時,參數(shù)時一次性插入的,而非一次一個地插入。就像是上例添加1和2,他們插入到數(shù)組中的順序跟參數(shù)列表中的順序一致,而不是[2,1,3,4,5]。

返回值: 返回數(shù)組新的長度。


4. shift() 方法刪除數(shù)組的第一個元素并將其返回,然后把所有隨后的元素下移一個位置來填補數(shù)組頭部的空缺,返回值是刪除的元素

參數(shù): 無。

let arr = [1,2,3];
let item = arr.shift(); // 返回刪除的值1
console.log(arr, item)
// [2, 3] 1

返回值: 從數(shù)組中刪除的元素; 如果數(shù)組為空則返回undefined 。


5. splice() 方法是在數(shù)組中插入或刪除元素的通用方法

語法
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

參數(shù):

start?

指定修改的開始位置(從0計數(shù))。如果超出了數(shù)組的長度,則從數(shù)組末尾開始添加內(nèi)容;如果是負(fù)值,則表示從數(shù)組末位開始的第幾位(從-1計數(shù));若只使用start參數(shù)而不使用deleteCount、item,如:array.splice(start) ,表示刪除[start,end]的元素。

deleteCount (可選)

整數(shù),表示要移除的數(shù)組元素的個數(shù)。如果 deleteCount 是 0,則不移除元素。這種情況下,至少應(yīng)添加一個新元素。如果 deleteCount 大于start 之后的元素的總數(shù),則從 start 后面的元素都將被刪除(含第 start 位)。
如果deleteCount被省略,則其相當(dāng)于(arr.length - start)。

item1, item2, ... (可選)

要添加進數(shù)組的元素,從start 位置開始。如果不指定,則 splice() 將只刪除數(shù)組元素。

返回值: 由被刪除的元素組成的一個數(shù)組。如果只刪除了一個元素,則返回只包含一個元素的數(shù)組。如果沒有刪除元素,則返回空數(shù)組。

// start不超過數(shù)組長度(以下操作是連續(xù)的)
let arr = [1,2,3,4,5];
arr.splice(2)   // arr是[1,2],返回值是[3,4,5]
arr.splice(1,1) // arr是[1],返回值是[2]
arr.splice(0,3) // arr是[],返回值是[1],因為此時數(shù)組從第0位開始不夠3位,所以是刪除從0開始到最后的所有元素。

// start大于數(shù)組長度(以下操作是連續(xù)的)
let arr = [1,2,3,4,5];
arr.splice(5)   // arr是[1,2,3,4,5],返回值是[]
arr.splice(5,3,6) // arr是[1,2,3,4,5,6],返回值是[]
arr.splice(5,3,7) // arr是[1,2,3,4,5,7] 返回值是[6]

// start是負(fù)數(shù)(以下操作是連續(xù)的)
let arr = [1,2,3,4,5];
arr.splice(-3,2); // arr是[1,2,5], 返回值是[3,4]
arr.splice(-4); // arr是[],返回值是[1,2,5]

// 插入數(shù)組時,是插入數(shù)組本身,而不是數(shù)組元素
let arr = [1,4,5];
arr.splice(1,0,[2,3])   // arr是[1,[2,3],4,5],返回值是[]


6. sort() 方法將數(shù)組中的元素排序并返回排序后的數(shù)組

參數(shù):

compareFunction (可選) 用來指定按某種順序進行排列的函數(shù)。如果省略,元素按照轉(zhuǎn)換為的字符串的各個字符的Unicode位點進行排序。
如果指明了 compareFunction ,那么數(shù)組會按照調(diào)用該函數(shù)的返回值排序。即 a 和 b 是兩個將要被比較的元素:

如果 compareFunction(a, b) 小于 0 ,那么 a 會被排列到 b 之前;

如果 compareFunction(a, b) 等于 0 , a 和 b 的相對位置不變。備注: ECMAScript 標(biāo)準(zhǔn)并不保證這一行為,而且也不是所有瀏覽器都會遵守(例如 Mozilla 在 2003 年之前的版本);

如果 compareFunction(a, b) 大于 0 , b 會被排列到 a 之前。

compareFunction(a, b) 必須總是對相同的輸入返回相同的比較結(jié)果,否則排序的結(jié)果將是不確定的。

var stringArray = ["Blue", "Humpback", "Beluga"];
var numberArray = [40, 1, 5, 200];
function compareNumbers(a, b){
  return a - b;
}
console.log("stringArray:" + stringArray.join());
console.log("Sorted:" + stringArray.sort());

console.log("numberArray:" + numberArray.join());
// 沒有使用比較函數(shù)時,數(shù)字并不會按照我們設(shè)想的那樣排序
console.log("Sorted without a compare function:"+ numberArray.sort());
console.log("Sorted with compareNumbers:"+ numberArray.sort(compareNumbers));

//打印如下
// stringArray: Blue,Humpback,Beluga
// Sorted: Beluga,Blue,Humpback

// numberArray: 40,1,5,200
// Sorted without a compare function: 1,200,40,5
// Sorted with compareNumbers: 1,5,40,200

返回值: 返回排序后的數(shù)組。原數(shù)組已經(jīng)被排序后的數(shù)組代替。


7. reverse() 方法將數(shù)組中的元素顛倒順序,返回逆序的數(shù)組。

參數(shù): 無

let arr = [1,2,3];
arr.reverse()   // arr是[3,2,1],返回值是[3,2,1]

返回值: 返回順序顛倒后的數(shù)組。原數(shù)組已經(jīng)被排序后的數(shù)組代替。


8. copyWithin() 方法淺復(fù)制數(shù)組的一部分到同一數(shù)組中的另一個位置,并返回它,而不修改其大小。 (ES6新增)

語法:
arr.copyWithin(target[, start[, end]])

參數(shù):

target

0 為基底的索引,復(fù)制序列到該位置。如果是負(fù)數(shù),target 將從末尾開始計算。

如果 target 大于等于 arr.length,將會不發(fā)生拷貝。如果 target 在 start 之后,復(fù)制的序列將被修改以符合 arr.length。

start

0 為基底的索引,開始復(fù)制元素的起始位置。如果是負(fù)數(shù),start 將從末尾開始計算。

如果 start 被忽略,copyWithin 將會從0開始復(fù)制。

end

0 為基底的索引,開始復(fù)制元素的結(jié)束位置。copyWithin 將會拷貝到該位置,但不包括 end 這個位置的元素。如果是負(fù)數(shù), end 將從末尾開始計算。

如果 end 被忽略,copyWithin 將會復(fù)制到 arr.length。

返回值: 改變了的數(shù)組。

[1, 2, 3, 4, 5].copyWithin(-2);
// [1, 2, 3, 1, 2]

[1, 2, 3, 4, 5].copyWithin(0, 3);
// [4, 5, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(0, 3, 4);
// [4, 2, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(-2, -3, -1);
// [1, 2, 3, 3, 4]


// copyWithin 函數(shù)是設(shè)計為通用的,其不要求其 this 值必須是一個數(shù)組對象。
[].copyWithin.call({length: 5, 3: 1}, 0, 3);
// {0: 1, 3: 1, length: 5}


9. fill() 方法用一個固定值填充一個數(shù)組中從起始索引到終止索引內(nèi)的全部元素。 (ES6新增)

語法:
arr.fill(value[, start[, end]])

參數(shù):

value 用來填充數(shù)組元素的值。

start (可選) 起始索引,默認(rèn)值為0。

end (可選) 終止索引,默認(rèn)值為 this.length。

如果 start 是個負(fù)數(shù), 則開始索引會被自動計算成為 length+start, 其中 length 是 this 對象的 length 屬性值. 如果 end 是個負(fù)數(shù), 則結(jié)束索引會被自動計算成為 length+end。

返回值: 修改后的數(shù)組

[1, 2, 3].fill(4);               // [4, 4, 4]
[1, 2, 3].fill(4, 1);            // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);         // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1);         // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3);         // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);       // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN);     // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5);         // [1, 2, 3]
Array(3).fill(4);                // [4, 4, 4]

//fill 方法故意被設(shè)計成通用方法, 該方法不要求 this 是數(shù)組對象。
[].fill.call({ length: 3 }, 4);  // {0: 4, 1: 4, 2: 4, length: 3}


2、不改變原數(shù)組的方法 1. slice() 方法返回一個從開始到結(jié)束(不包括結(jié)束)選擇的數(shù)組的一部分淺拷貝到一個新數(shù)組對象。且原始數(shù)組不會被修改。

參數(shù):

begin (可選)

從該索引處開始提取原數(shù)組中的元素(從0開始)。

如果該參數(shù)為負(fù)數(shù),則表示從原數(shù)組中的倒數(shù)第幾個元素開始提取,slice(-2)表示提取原數(shù)組中的倒數(shù)第二個元素到最后一個元素(包含最后一個元素)。

如果省略 begin,則 slice 從索引 0 開始。

end (可選)

在該索引處結(jié)束提取原數(shù)組元素(從0開始)。

slice會提取原數(shù)組中索引從 begin 到 end 的所有元素(包含begin,但不包含end)。
slice(1,4) 提取原數(shù)組中的第二個元素開始直到第四個元素的所有元素 (索引為 1, 2, 3的元素)。

如果該參數(shù)為負(fù)數(shù), 則它表示在原數(shù)組中的倒數(shù)第幾個元素結(jié)束抽取。 slice(-2,-1)表示抽取了原數(shù)組中的倒數(shù)第二個元素到最后一個元素(不包含最后一個元素,也就是只有倒數(shù)第二個元素)。

如果 end 被省略,則slice 會一直提取到原數(shù)組末尾。

如果 end 大于數(shù)組長度,slice 也會一直提取到原數(shù)組末尾

返回值: 一個含有提取元素的新數(shù)組

let arr = [1,2,3,4,5];
let arr1 = arr.slice(1,3); // arr是[1,2,3,4,5], arr1是[2,3]
let arr2 = arr.slice(-2,-1);  // arr是[1,2,3,4,5], arr2是[4]
// 開始位置在結(jié)束位置后面,得到的數(shù)組是空
let arr3 = arr.slice(-2, -3); // arr是[1,2,3,4,5], arr3是[]
let arr4 = arr.slice(2, 1); // arr是[1,2,3,4,5], arr4是[]

//如果元素是個對象引用 (不是實際的對象),slice 會拷貝這個對象引用到新的數(shù)組里。兩個對象引用都引用了同一個對象。如果被引用的對象發(fā)生改變,則新的和原來的數(shù)組中的這個元素也會發(fā)生改變。
let arr = [{name: "xiaoming"}];
let arr1 = arr.slice(); // arr是[{name: xiaoming}],arr1是[{name: "xiaoming"}]
arr1[0].name = "xiaogang"; // arr是[{name: "xiaogang"}],arr1是[{name: "xiaogang"}]

// 對于字符串、數(shù)字及布爾值來說(不是 String、Number 或者 Boolean 對象),slice 會拷貝這些值到新的數(shù)組里。在別的數(shù)組里修改這些字符串或數(shù)字或是布爾值,將不會影響另一個數(shù)組。
let arr = [1,2,3];
let arr1 = arr.slice(); // arr是[1,2,3],arr1是[1,2,3]
arr1[1] = "two"; // arr是[1,2,3],arr1是[1,"two",3]

// 當(dāng)然,如果向兩個數(shù)組任一中添加了新元素(簡單或者引用類型),則另一個不會受到影響。


2. join() 方法將數(shù)組(或一個類數(shù)組對象)中所有元素都轉(zhuǎn)化為字符串并連接在一起,返回最后生成的字符串。

參數(shù):

separator (可選)
指定一個字符串來分隔數(shù)組的每個元素。
如果有(separator),將分隔符轉(zhuǎn)換為字符串。
如果省略(),數(shù)組元素用逗號分隔。默認(rèn)為 ","。
如果separator是空字符串(""),則所有元素之間都沒有任何字符。

let num = [1,2,3];
let str1 = num.join(); // 1,2,3
let str2 = num.join(", ") // 1, 2, 3
let str3 = num.join("") // 123

//所有的數(shù)組元素被轉(zhuǎn)換成字符串,再用一個分隔符將這些字符串連接起來。如果元素是undefined 或者null, 則會轉(zhuǎn)化成空字符串。
let num = [1,null,3];
let str1 = num.join(); // 1,,3

//如果數(shù)組中的元素是數(shù)組,會將里面的數(shù)組也調(diào)用join()
let num = [[1,2],3];
let str1 = num.join("-"); // 1,2-3

// 如果數(shù)組中的元素是對象,對象會被轉(zhuǎn)為[object Object]字符串
let num = [{num: 1},2,3];
let str1 = num.join("-"); // [object Object]-2-3

返回值: 一個所有數(shù)組元素連接的字符串。如果 arr.length 為0,則返回空字符串

知識點

// 扁平化簡單的二維數(shù)組
const arr = [11, [22, 33], [44, 55], 66];
const flatArr = arr.join().split(","); // ["11", "22", "33", "44", "55", "66"]


3. toString() 方法將數(shù)組的每個元素轉(zhuǎn)化為字符串(如有必要將調(diào)用元素的toString()方法)并且輸出用逗號分割的字符串列表。返回一個字符串表示數(shù)組中的元素

參數(shù):

[1,2,3].toString(); // 1,2,3
[1,[2,"c"]].toString(); //1,2,c
// 以上與不使用任何參數(shù)調(diào)用join()方法返回的字符串是一樣的。

// 以下的這個例子要跟下面的toLocaleString對照看
[{a:1},1,new Date()].toString() //"[object Object],1,Sat Jul 07 2018 18:43:45 GMT+0800 (中國標(biāo)準(zhǔn)時間)"

注意: 當(dāng)數(shù)組和字符串操作的時候,js 會調(diào)用這個方法將數(shù)組自動轉(zhuǎn)換成字符串

[1,2,3]+"abc"  //1,2,3abc

返回值: 返回一個字符串表示數(shù)組中的元素

知識點

// 扁平化簡單的二維數(shù)組
const arr = [11, [22, 33], [44, 55], 66];
const flatArr = arr.toString().split(","); // ["11", "22", "33", "44", "55", "66"]


4. toLocaleString() 數(shù)組中的元素將使用各自的 toLocaleString 方法轉(zhuǎn)成字符串,這些字符串將使用一個特定語言環(huán)境的字符串(例如一個逗號 ",")隔開。

參數(shù):(還有待考證,我試了一下沒用,看了一下ECMA的官網(wǎng),確實是標(biāo)注有兩個可選參數(shù)的)

locales (可選) 帶有BCP 47語言標(biāo)記的字符串或字符串?dāng)?shù)組

options (可選) 一個可配置屬性的對象

//數(shù)組中的元素將會使用各自的 toLocaleString 方法:
// Object: Object.prototype.toLocaleString()
// Number: Number.prototype.toLocaleString()
// Date: Date.prototype.toLocaleString()

let prices = ["¥7", 500, 8123, 12];

// 不帶參數(shù)
prices.toLocaleString(); // "¥7,500,8,123,12"

//帶參數(shù)
prices.toLocaleString("ja-JP", { style: "currency", currency: "JPY" }); // "¥7,500,8,123,12"
//MDN上的舉例中說是 "¥7,¥500,¥8,123,¥12",在瀏覽器和Node中驗證了返回的都是 "¥7,500,8,123,12" 啊!

// 以下的這個例子要跟上面的toString對照看
[{a:1},1,new Date()].toLocaleString() //"[object Object],1,2018/7/7 下午6:45:00"

返回值: 表示數(shù)組元素的字符串。


5. concat() 方法用于合并兩個或多個數(shù)組。此方法不會更改現(xiàn)有數(shù)組,而是返回一個新數(shù)組。

它的元素包括調(diào)用concat()的原始數(shù)組的元素和concat()的每個參數(shù),但是要注意,concat()不會遞歸扁平化數(shù)組的數(shù)組,concat()也不會修改調(diào)用的數(shù)組。

參數(shù):

valueN (可選) 將(多個)數(shù)組和/或值連接成新數(shù)組。

[1,2,3].concat([4,5,6],[7,8,9]) // [1, 2, 3, 4, 5, 6, 7, 8, 9]

["a","b","c"].concat(1,[2,3],[[4,5]]) // ["a", "b", "c", 1, 2, 3, [4,5]]

// concat方法不會改變this或任何作為參數(shù)提供的數(shù)組,而是返回一個淺拷貝,所以原始數(shù)組和新數(shù)組都引用相同的對象。 如果引用的對象被修改,新數(shù)組和原始數(shù)組都會變。
let obj = {a: 1};
let arr1 = [2,obj];
let arr2 = [1].concat(arr1);
console.log(arr1,arr2) //[2,{a:1}],[1,2,{a:1}]

//記錄下上面的打印結(jié)果之后修改obj
obj.a = 2;
console.log(arr1,arr2) ////[2,{a:2}],[1,2,{a:2}]

// 說了是淺拷貝,而且原數(shù)組也不改變,那我們就可以用它來實現(xiàn)數(shù)組的淺拷貝功能
let num1 = [1,2,3];
//第一種
let num2 = num1.concat();
//第二種
let num2 = [].concat(num1);
num2[0] = "a";
console.log(num1,num2); // [1, 2, 3] ["a", 2, 3]

返回值: 新的 Array 實例

知識點

// concat 和擴展運算符可以快速扁平化數(shù)組
const arr = [11, [22, 33], [44, 55], 66];
const flatArr = [].concat(...arr); // [11, 22, 33, 44, 55, 66]


6. isArray() 用于確定傳遞的值是否是一個 Array。

參數(shù):

obj 需要檢測的值。

// 下面的函數(shù)調(diào)用都返回 true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
// 這里注意:Array.prototype 也是一個數(shù)組,一個屬性值不是索引的數(shù)組。[constructor: ?, concat: ?, find: ?, findIndex: ?, pop: ?, …]
Array.isArray(Array.prototype);

// 下面的函數(shù)調(diào)用都返回 false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray("Array");
Array.isArray(true);
Array.isArray(false);
Array.isArray({ __proto__: Array.prototype });

返回值: 如果對象是 Array,則為true; 否則為false。

知識點

//判斷數(shù)組的歷程
// step one: 使用constructor
var a = [1];
console.log(a.constructor === Array) // true
// 但是原型的contructor屬性是可以被改寫的,例如在原型繼承的時候,我們都是要把繼承過來的prototype的constructor改寫成我們當(dāng)前的
var a = [1];
a.__proto__.constructor = "1";
console.log(a.constructor === Array) // false

// step two : 使用instanceof
var a = [1];
console.log(a instanceof Array) // true
//但是instanceof不能檢測iframes的數(shù)組
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]

arr instanceof Array; // false

// step three :萬無一失的Object.prototype.toString.call
Array.isArray = function(arg) {
  return Object.prototype.toString.call(arg) === "[object Array]";
};

// step four : Array.isArray()

var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]

Array.isArray(arr);  // true,也可以檢測iframes的數(shù)組


3、數(shù)組遍歷、映射、過濾、檢測、簡化等方法

介紹方法之前,先對這些數(shù)組方法做一個概述:

首先,大多數(shù)方法的第一個參數(shù)接收一個函數(shù),并且對數(shù)組的每個元素(或一些元素)調(diào)用一次該函數(shù)。如果是稀疏數(shù)組,對不存在的元素不調(diào)用該函數(shù)。大多數(shù)情況下,調(diào)用提供的函數(shù)使用三個參數(shù):數(shù)組元素、元素的索引和數(shù)組本身。通常,只需要第一個參數(shù)值,可以忽略后兩個參數(shù)。

大多數(shù)方法,第二個參數(shù)是可選的。如果有第二個參數(shù),則調(diào)用的第一個函數(shù)參數(shù)被看做是第二個參數(shù)的方法,即當(dāng)執(zhí)行第一個函數(shù)參數(shù)時用作this的值(參考對象)。

方法的返回值很重要,不同的方法處理返回值的方式也不一樣。

下面這些方法運行時的規(guī)則:

對于空數(shù)組是不會執(zhí)行回調(diào)函數(shù)的

對于已在迭代過程中刪除的元素,或者空元素會跳過回調(diào)函數(shù)

遍歷次數(shù)在第一次循環(huán)前就會確定,再添加到數(shù)組中的元素不會被遍歷。

如果已經(jīng)存在的值被改變,則傳遞給 callback 的值是遍歷到他們那一刻的值。

已刪除的項不會被遍歷到。如果已訪問的元素在迭代時被刪除了(例如使用 shift()) ,之后的元素將被跳過


1. forEach() 方法從頭到尾遍歷數(shù)組,為每個元素調(diào)用指定的函數(shù)。

參數(shù):

callback 為數(shù)組中每個元素執(zhí)行的函數(shù),該函數(shù)接收三個參數(shù):

currentValue(當(dāng)前值) 數(shù)組中正在處理的當(dāng)前元素。

index(索引) 數(shù)組中正在處理的當(dāng)前元素的索引。

array forEach()方法正在操作的數(shù)組。

thisArg (可選) 當(dāng)執(zhí)行回調(diào)函數(shù)時用作this的值(參考對象)。默認(rèn)值為undefined

注意:

forEach無法中途退出循環(huán),只能用return退出本次回調(diào),進行下一次回調(diào),如果要提前終止,可以把forEach方法放在try塊中,并能拋出一個異常,但這種方法是不推薦的。

它與之后會說到的幾個方法不同,總是返回 undefined值,即使你return了一個值。

// 1、 空元素不遍歷,undefined和null是會遍歷的。
let numberArr = [1,2,,3];
numberArr.forEach(function (value,index,array) {
  console.log(value,index,array)
})
//打印信息如下,可見空元素是不會遍歷的
//1 0 [1, 2, empty, 3]
//2 1 [1, 2, empty, 3]
//3 3 [1, 2, empty, 3]

let nullArr = [1,2,null,3];
nullArr.forEach(function (value,index,array) {
  console.log(value,index,array)
})
//打印信息如下,null是會遍歷的
//1 0 (4) [1, 2, null, 3]
//2 1 (4) [1, 2, null, 3]
//null 2 (4) [1, 2, null, 3]
//3 3 (4) [1, 2, null, 3]

//2、已刪除的項不會被遍歷到。如果已訪問的元素在迭代時被刪除了,之后的元素將被跳過
let numberArr = [1,2,3];
numberArr.forEach(function (value,index,array) {
  if(index === 0) {
    delete numberArr[2]; //刪除第三項
    //或者numberArr.pop()
  }
  console.log(value,index,array)
})
//打印信息如下:
// 1 0 (3) [1, 2, empty]
// 2 1 (3) [1, 2, empty]


let numberArr1 = [1,2,3,4];
numberArr1.forEach(function (value,index,array) {
  if(index === 1) {
    numberArr1.shift() //遍歷到第二項的時候,刪除第一項
  }
  console.log(value,index,array)
})
// 打印信息如下,遍歷到第二項的時候,刪除第一項,會跳過第三項
// 1 0 (4) [1, 2, 3, 4]
// 2 1 (3) [2, 3, 4]
// 4 2 (3) [2, 3, 4]

// 3、forEach 遍歷的范圍在第一次調(diào)用 callback 前就會確定。調(diào)用forEach 后添加到數(shù)組中的項不會被 callback 訪問到。如果已經(jīng)存在的值被改變,則傳遞給 callback 的值是 forEach 遍歷到他們那一刻的值。
let arr = [1,2,3];
arr.forEach(function (value,index,array) {
  if(index === 0) {
    arr.push("新增的不會被遍歷到")
    arr[2] = 4;
  }
  console.log(value,index,array)
})
// 1 0 (4) [1, 2, 4, "新增的不會被遍歷到"]
// 2 1 (4) [1, 2, 4, "新增的不會被遍歷到"]
// 4 2 (4) [1, 2, 4, "新增的不會被遍歷到"]

// 4、使用thisArg參數(shù) 和 箭頭函數(shù)使用thisArg
let arr = [1,2,3];
let obj = {arr: "thisArg"}
arr.forEach(function () {
  console.log(this.arr)
},obj)
// 打印三次 "thisArg"

let arr = [1,2,3];
let obj = {arr: "thisArg"}
arr.forEach(() => {
  console.log(this.arr)
},obj)
// 打印三次 undefined

// 5、forEach無法中途退出循環(huán),只能用return退出本次回調(diào),進行下一次回調(diào)
let arr = [1,2,3];
let result = arr.forEach((value) => {
  if(value == 2) {
    return value;
  }
  console.log(value)
})
console.log(result) // undefined ,即使中間return vlaue,也還是undefined
//打印value的值如下,說明return 并不能終止循環(huán)
// 1
// 3

返回值: undefined


2. map() 方法創(chuàng)建一個新數(shù)組,其結(jié)果是該數(shù)組中的每個元素都調(diào)用一個callback函數(shù)后返回的結(jié)果。

參數(shù):(之前說過,大多說方法都會是這樣一些參數(shù))

callback 生成新數(shù)組元素的函數(shù),使用三個參 這個函數(shù)跟forEach()的函數(shù)不同的是,傳遞給map()的函數(shù)應(yīng)該有返回值。

currentValue callback 的第一個參數(shù),數(shù)組中正在處理的當(dāng)前元素。

index callback 的第二個參數(shù),數(shù)組中正在處理的當(dāng)前元素的索引。

array callback 的第三個參數(shù),map 方法被調(diào)用的數(shù)組。

thisArg (可選) 執(zhí)行 callback 函數(shù)時 使用的this 值。

注意: map() 返回的是新數(shù)組,它不修改調(diào)用的數(shù)組。如果是稀疏數(shù)組,返回的也是相同方式的稀疏數(shù)組:它具有相同的長度,相同索引的缺失元素(因為空值不會調(diào)用函數(shù))

let number = [1,2,3];
let doubles = number.map(function (value) {
  return value * 2;
})
console.log(number, doubles)
// [1,2,3] [2,4,6]

返回值: 一個新數(shù)組,每個元素都是回調(diào)函數(shù)的結(jié)果

知識點
不要用 map 代替 forEach,map 會創(chuàng)建一個新的數(shù)組,占用內(nèi)存。如果你不用 map 的返回值,那你就應(yīng)當(dāng)使用 forEach


3. filter() 方法返回的數(shù)組元素是調(diào)用的數(shù)組的一個子集。傳入的函數(shù)時用來邏輯判定的,該函數(shù)返回 true 或 false,如果返回值為true或能轉(zhuǎn)化為true的值,那么傳遞給判斷函數(shù)的元素就是這個子集的成員,它將被添加倒一個作為返回值的數(shù)組中。

參數(shù):

callback 用來測試數(shù)組的每個元素的函數(shù)。調(diào)用時使用參數(shù) (element, index, array)。返回true表示保留該元素(通過測試),false則不保留。它接受三個參數(shù):

element 當(dāng)前在數(shù)組中處理的元素

index(可選) 正在處理元素在數(shù)組中的索引

array(可選)調(diào)用了filter篩選器的數(shù)組

thisArg(可選)可選。執(zhí)行 callback 時的用于 this 的值。

注意:

callback 只會在已經(jīng)賦值的索引上被調(diào)用,對于那些已經(jīng)被刪除或者從未被賦值的索引不會被調(diào)用。也就是說filter()會跳過稀疏數(shù)組中缺少的元素,它的返回數(shù)組總是稠密的,可以用這個方法壓縮稀疏數(shù)組的空缺。

filter 不會改變原數(shù)組,它返回過濾后的新數(shù)組。

let number = [1,2,3,4,5,6];
let small = number.filter((value) => {
  return value < 4;
})
console.log(number,small)
// 打印 [1, 2, 3, 4, 5, 6] [1, 2, 3]


//壓縮稀疏數(shù)組的空缺
let arr = [1,2,3,,5];
let arr1 = arr.filter(() => true);
console.log(arr,arr1)
// 打印 [1, 2, 3, empty, 5] [1, 2, 3, 5]

返回值: 一個新的通過測試的元素的集合的數(shù)組,如果沒有通過測試則返回空數(shù)組。


4. every() 方法測試數(shù)組的所有元素是否都通過了指定函數(shù)的測試。當(dāng)且僅當(dāng)針對數(shù)組中的所有元素調(diào)用判定函數(shù)都返回true,它才返回true。

參數(shù):

callback 用來測試每個元素的函數(shù)。

thisArg 執(zhí)行 callback 時使用的 this 值。

注意:

every 方法為數(shù)組中的每個元素執(zhí)行一次 callback 函數(shù),callback 只會為那些已經(jīng)被賦值的索引調(diào)用。不會為那些被刪除或從來沒被賦值的索引調(diào)用。every 方法在callback第一次返回false后就返回false,然后終止遍歷。但如果callback一直返回true,它將會遍歷整個數(shù)組,最終返回true。

空數(shù)組上調(diào)用every方法,返回 true,因為空數(shù)組沒有元素,所以空數(shù)組中所有元素都符合給定的條件

every 不會改變原數(shù)組

let arr = [12,34,5,23,44];
let num = 0;
let result = arr.every(function (element, index, array) {
  num++;
  return element > 10;
})
console.log(result,num) // 打印 false 3
// 可見發(fā)現(xiàn)5這個小于10的元素后,遍歷立即終止,num為3

let arr = [12,34,,23,44];
let num = 0;
let result = arr.every(function (element, index, array) {
  num++;
  return element > 10;
})
console.log(result,num) // 打印 true 4
// 不會遍歷沒有賦值的索引位置,所以num為4

let result = [].every(function (element, index, array) {
  return element > 10;
})

console.log(result) // 打印 true

返回值: 一個布爾值,當(dāng)所有的元素都符合條件才返回true,否則返回false


5. some() 方法測試數(shù)組中的某些元素是否通過由提供的函數(shù)實現(xiàn)的測試。當(dāng)數(shù)組中至少有一個元素調(diào)用判定函數(shù)返回true,它就返回true,當(dāng)且僅當(dāng)數(shù)組中的所有元素調(diào)用判定函數(shù)都返回false,它才返回false。

參數(shù):

callback 用來測試每個元素的函數(shù)

thisArg 可選 執(zhí)行 callback 時使用的 this 值。

注意:

some 為數(shù)組中的每一個元素執(zhí)行一次 callback 函數(shù),直到找到一個使得 callback 返回一個“真值”,這時,some 將會立即返回 true。否則,some 返回 false。callback 只會在那些”有值“的索引上被調(diào)用,不會在那些被刪除或從來未被賦值的索引上調(diào)用。

some 被調(diào)用時不會改變數(shù)組。

空數(shù)組調(diào)用some,返回false

// 一個簡單的例子說明
function isBiggerThan10(element, index, array) {
  return element > 10;
}

[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true

// 實現(xiàn)一個跟includes方法類似的功能
let arr = [1,2,3];
function include(value) {
  return arr.some((element) => {
    return element === value;
  })
}
include(2) // true
include(4) // false

let result = [].some(function (element, index, array) {
  return element > 10;
})

console.log(result) // 打印 false

返回值: 只要數(shù)組中的任意一個元素在回調(diào)函數(shù)中返回的是真值,就返回true,否則為false


6. reduce() 和 reduceRight() 這兩個方法使用指定的函數(shù)將數(shù)組元素進行組合,生成單個值。這在函數(shù)式編程中是常見的操作,也可以稱為“注入”和“折疊”。reduceRight() 和 reduce() 工作原理是一樣的,不同的是reduceRight() 按照數(shù)組索引從高到低(從右到左)處理數(shù)組,而不是從低到高。

參數(shù):

callback 執(zhí)行數(shù)組中每個值的函數(shù),包含四個參數(shù):

accumulator 累加器累加回調(diào)的返回值; 它是上一次調(diào)用回調(diào)時返回的累積值,或initialValue(如下所示)。

currentValue 數(shù)組中正在處理的元素。

currentIndex (可選) 數(shù)組中正在處理的當(dāng)前元素的索引。 如果提供了initialValue,則索引號為0,否則為索引為1。

array (可選) 調(diào)用reduce的數(shù)組

initialValue (可選) 用作第一個調(diào)用 callback的第一個參數(shù)的值。 如果沒有提供初始值,則將使用數(shù)組中的第一個元素。 在沒有初始值的空數(shù)組上調(diào)用 reduce 將報錯。

注意:

reduce為數(shù)組中的每一個元素依次執(zhí)行callback函數(shù),不包括數(shù)組中被刪除或從未被賦值的元素,回調(diào)函數(shù)第一次執(zhí)行時,accumulator 和currentValue的取值有兩種情況:調(diào)用reduce時提供initialValue,accumulator取值為initialValue,currentValue取數(shù)組中的第一個值;沒有提供 initialValue,accumulator取數(shù)組中的第一個值,currentValue取數(shù)組中的第二個值。即:如果沒有提供initialValue,reduce 會從索引1的地方開始執(zhí)行 callback 方法,跳過第一個索引。如果提供initialValue,從索引0開始。

如果數(shù)組為空且沒有提供initialValue,會拋出TypeError 。如果數(shù)組僅有一個元素(無論位置如何)并且沒有提供initialValue, 或者有提供initialValue但是數(shù)組為空,那么此唯一值將被返回并且callback不會被執(zhí)行

let arr = [1,2,3,4,5];
let sum = arr.reduce((x,y) => x + y,0);
console.log(sum) // 15

// 看一下initialValue傳和不傳的區(qū)別
let arr = [1,2,3,4,5];
arr.reduce(function (accumulator,currentValue,currentIndex,arr) {
  console.log(currentIndex)
  return accumulator + currentValue;
})
// 1,2,3,4,5 沒傳入initialValue,索引是從1開始
arr.reduce(function (accumulator,currentValue,currentIndex,arr) {
  console.log(currentIndex)
  return accumulator + currentValue;
},10)
// 0,1,2,3,4,5 傳入initialValue,索引從0開始

// 應(yīng)用到二維數(shù)組展開
let arr = [[0, 1], [2, 3], [4, 5]].reduce(
  (a, b) => a.concat(b)
);
console.log(arr)
// [0, 1, 2, 3, 4, 5]

返回值: 函數(shù)累計處理的結(jié)果


7. indexof() 方法返回在數(shù)組中可以找到一個給定元素的第一個索引,如果不存在,則返回-1。

參數(shù):

searchElement 要查找的元素

fromIndex (可選)開始查找的位置。
如果該索引值大于或等于數(shù)組長度,意味著不會在數(shù)組里查找,返回-1。

如果該索引值是負(fù)值,代表相對數(shù)組末尾的偏移量,即-1表示從最后一個元素開始查找,-2表示從倒數(shù)第二個元素開始查找,注意的是,這并不改變其查找順序,查找順序仍然是從前向后查詢數(shù)組。

如果該索引值是負(fù)值,其絕對值大于數(shù)組長度,則整個數(shù)組都將會被查詢。其默認(rèn)值為0。

注意: indexOf 使用嚴(yán)格相等(即 ===)比較 searchElement 和數(shù)組中的元素。而且indexOf()不能識別 NaN

let array = [2, 5, 9];
array.indexOf(2)     // 0
array.indexOf(7)     // -1
array.indexOf(9, 2)  // 2
array.indexOf(9, 3)  // -1
array.indexOf(2, -1) // -1
array.indexOf(2, -3) // 0
array.indexOf(2, -4) // 0

let array1 = [1,2,NaN];
array1.indexOf(NaN) // -1

返回值: 首個被找到的元素在數(shù)組中的索引位置; 若沒有找到則返回 -1


8. lastIndexOf() 跟indexOf()查找方向相反,方法返回指定元素在數(shù)組中的最后一個的索引,如果不存在則返回 -1。從數(shù)組的后面向前查找,從 fromIndex 處開始

參數(shù):

searchElement 要查找的元素

fromIndex (可選)開始查找的位置。默認(rèn)為數(shù)組的長度減 1,即整個數(shù)組都被查找。
如果該值大于或等于數(shù)組的長度,則整個數(shù)組會被查找。
如果為負(fù)值,將其視為從數(shù)組末尾向前的偏移。即使該值為負(fù),數(shù)組仍然會被從后向前查找。
如果該值為負(fù)時,其絕對值大于數(shù)組長度,則方法返回 -1,即數(shù)組不會被查找。

注意: lastIndexOf 使用嚴(yán)格相等(即 ===)比較 searchElement 和數(shù)組中的元素。而且lastIndexOf()不能識別 NaN

let array = [2,5,9,2];
array.lastIndexOf(9) // 2
array.lastIndexOf("9") // -1 嚴(yán)格相等
array.lastIndexOf(7) // -1
array.lastIndexOf(2,4) // 3
array.lastIndexOf(2,3) // 3
array.lastIndexOf(2,2) // 0
array.lastIndexOf(2,-1) // 3
array.lastIndexOf(2,-2) // 0
array.lastIndexOf(2,-4) // 0
array.lastIndexOf(2,-5) // -1

返回值: 數(shù)組中最后一個符合元素的索引,如未找到返回-1


9. includes() 方法用來判斷一個數(shù)組是否包含一個指定的值,根據(jù)情況,如果包含則返回 true,否則返回false。 ES7新增

參數(shù):

searchElement 需要查找的元素值。

fromIndex (可選) 從該索引處開始查找 searchElement。默認(rèn)為 0。如果為負(fù)值,則按升序從 array.length + fromIndex 的索引開始搜索。負(fù)值絕對值超過長數(shù)組度,從0開始搜索。

如果fromIndex 大于等于數(shù)組長度 ,則返回 false 。該數(shù)組不會被搜索。

注意:

includes解決了兩個indexOf的問題:

indexOf方法不能識別NaN

indexOf方法檢查是否包含某個值不夠語義化,需要判斷是否不等于-1,表達不夠直觀

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, 3].includes(3, -4); // true
[1, 2, NaN].includes(NaN); // true

返回值: 一個布爾值,根據(jù)情況,如果包含則返回 true,否則返回false。


10. find() 和 findIndex() find 方法返回數(shù)組中滿足提供的測試函數(shù)的第一個元素的值。否則返回 undefined。findIndex 方法返回數(shù)組中滿足提供的測試函數(shù)的第一個元素的索引。否則返回-1。(ES6新增)

參數(shù): 這兩個方法跟其他的方法類似

callback 在數(shù)組每一項上執(zhí)行的函數(shù),接收 3 個參數(shù):

element 當(dāng)前遍歷到的元素。

index 當(dāng)前遍歷到的索引。

array 數(shù)組本身。

thisArg 可選,指定 callback 的 this 參數(shù)。

注意:

這兩個方法對數(shù)組中的每一項元素執(zhí)行一次 callback 函數(shù),直至有一個 callback 返回 true。在稀疏數(shù)組中,即使對于數(shù)組中不存在的條目的索引也會調(diào)用回調(diào)函數(shù)。 這意味著對于稀疏數(shù)組來說,該方法的效率要低于那些只遍歷有值的索引的方法。

當(dāng)找到一個callback判斷為true的元素,find方法會立即返回這個元素的值,否則返回 undefined。findIndex會立即返回該元素的索引。如果回調(diào)從不返回真值,或者數(shù)組的length為0,則findIndex返回-1。

這兩個方法都不會修改所調(diào)用的數(shù)組

// find
let a = [1, 4, -5, 10].find((n) => n < 0); // 返回元素-5
let b = [1, 4, -5, 10,NaN].find((n) => Object.is(NaN, n));  // 返回元素NaN
// findIndex
let a = [1, 4, -5, 10].findIndex((n) => n < 0); // 返回索引2
let b = [1, 4, -5, 10,NaN].findIndex((n) => isNaN(n));  // 返回索引4

// 稀疏數(shù)組
let a =[1,,3,4];
let index = 0;
a.find((n) => {
  console.log(index++) //0,1,2 第二次是empty也會調(diào)用一次,而且返回為true,立即退出 
  return n === 3;
})


返回值:

find 方法,當(dāng)某個元素通過 callback 的測試時,返回數(shù)組中的一個值,否則返回 undefined。

findIndex方法,返回數(shù)組中滿足提供的測試函數(shù)的第一個元素的索引。否則返回-1。

知識點
不要用 find() 代替 some(),通常混用是這種場景,find 返回第一個符合條件的值,直接拿這個值做 if 判斷是否存在,但是這個符合條件的值也有可能恰好為 0。
find 是找到數(shù)組中的值后對其進一步處理,一般用于對象數(shù)組的情況;some 才是檢查存在性;兩者不可混用。


11. keys() 方法返回一個新的Array迭代器,它包含數(shù)組中每個索引的鍵。 (ES6新增) 12. values() 方法返回一個新的Array迭代器,它包含數(shù)組中每個索引的值。 (ES6新增) 13. @@iterator 屬性和 values() 屬性的初始值均為同一個函數(shù)對象。數(shù)組的 iterator 方法,默認(rèn)情況下與 values() 返回值相同,調(diào)用語法是 arr[Symbol.iterator]() (ES6新增) 14. entries() 方法返回一個新的Array迭代器,該對象包含數(shù)組中每個索引的鍵/值對。 (ES6新增)

參數(shù): 都是無。

都是一個新的 Array 迭代器對象。

for (let key of ["a", "b"].keys()) {
  console.log(key);
}
// 0
// 1

for (let value of ["a", "b"].values()) {
  console.log(value);
}
// "a"
// "b"

for (let value of ["a", "b"][Symbol.iterator]()) {
  console.log(value);
}
// "a"
// "b"

for (let [key, value] of ["a", "b"].entries()) {
  console.log(key, value);
}
// 0 "a"
// 1 "b"


擴展幾個概念 1、數(shù)組的索引和對象key有什么關(guān)系?

數(shù)組是對象的特殊形式,使用方括號訪問數(shù)組元素和使用方括號訪問對象屬性一樣。JavaScript將指定的數(shù)字索引值轉(zhuǎn)換成字符串——索引1變成"1"——然后將其作為屬性名來使用。數(shù)組的特別之處在于,當(dāng)使用小于2^32的非負(fù)整數(shù)作為屬性名時數(shù)組會自動維護其length屬性。

// 索引到屬性名的轉(zhuǎn)化
let arr = [1,2,3];
console.log(arr[1]) // 2
console.log(arr["1"]) // 2


所有的數(shù)組都是對象,可以為其創(chuàng)建任意名字的屬性,不過,只有在小于2^32的非負(fù)整數(shù)才是索引,數(shù)組才會根據(jù)需要更新length。事實上數(shù)組的索引僅僅是對象屬性名的一種特殊類型,這意味著JavaScript數(shù)組沒有“越界”錯誤的概念。當(dāng)查詢?nèi)魏螌ο笾胁淮嬖诘膶傩詴r,不會報錯,只會得到undefined

let arr = [];
arr["a"] = 1;
console.log(arr,arr.length) // arr是[a:1] length是0


對于使用負(fù)數(shù)或非整數(shù)的情況,數(shù)值會轉(zhuǎn)換為字符串,字符串作為屬性名來用,當(dāng)時只能當(dāng)做常規(guī)的對象屬性,而非數(shù)組的索引。

let arr = [];
arr[-1.23] = 0;
console.log(arr,arr.length) // arr是[-1.23: 0] length是0


使用非負(fù)整數(shù)的字符串或者一個跟整數(shù)相等的浮點數(shù)時,它就當(dāng)做數(shù)組的索引而非對象屬性。

let arr = [];
arr["100"] = "a";
console.log(arr,arr.length) // arr 是[empty × 100, "a"],length 是101

let arr1 = [];
arr1[1.0000] = "b";
console.log(arr1,arr1.length) // arr 是[empty, "b"],length 是2
2、稀疏數(shù)組
稀疏數(shù)組就是包含從0開始的不連續(xù)索引的數(shù)組。通常數(shù)組的length屬性值代表數(shù)組中元素的個數(shù)。如果數(shù)組是稀疏的,length屬性值大于元素的個數(shù)

足夠稀疏的數(shù)組通常在實現(xiàn)上比稠密的數(shù)組更慢,更耗內(nèi)存,在這樣的數(shù)組中查找元素所用的時間就變得跟常規(guī)對象的查找時間一樣長了,失去了性能的優(yōu)勢。

let a1 = [,,]; // 數(shù)組直接量,該數(shù)組是[empty × 2]
0 in a1 // false: a1在索引0處沒有元素

let a2 = new Array(3); //[empty × 3],該數(shù)組根本沒有元素
0 in a2 // false: a2在索引0處沒有元素

let a3 = [undefined];
0 in a3 // true: a3在索引0處有一個值為undefined的元素

let a4 = [,undefined];
0 in a4 // fasle: a4在索引0處沒有元素
1 in a4 // true: a4在索引1處有一個值為undefined的元素
console.log(a4[0],a4[1]) // undefined undefined,可見數(shù)組訪問返回undefined,可能是稀疏數(shù)組,也可能是數(shù)組元素為undefined
3、類數(shù)組對象
擁有一個數(shù)值length屬性和對應(yīng)非負(fù)整數(shù)屬性的對象看做一種類型的數(shù)組

數(shù)組跟類數(shù)組相比有以下不同:

當(dāng)有新元素添加到數(shù)組中時,自動更新length屬性

設(shè)置length為一個較小值將截斷數(shù)組

從Array.prototype中繼承了一些方法

其類屬性為"Array"

JavaScript 數(shù)組有很多方法特意定義通用,因此他們不僅應(yīng)用在真正的數(shù)組而且在類數(shù)組對象上都能正確工作,JavaScript權(quán)威指南一書說的是:ES5中所有的方法都是通用的,ES3中除了toString()和toLocaleString()意外所有方法也是通用的。

類數(shù)組對象顯然沒有繼承自Array.prototype,所以它們不能直接調(diào)用數(shù)組方法,不過可以間接地使用Function.call方法調(diào)用。

// 類數(shù)組應(yīng)用通用方法
let arrayLike = {0: "name", 1: "age", 2: "address", length: 3 }
Array.prototype.join.call(arrayLike,"*") // "name*age*address"

// 還記得當(dāng)初獲取的DOM元素怎么轉(zhuǎn)化成數(shù)組么?
functon toArray (DOM) {
  return Array.prototype.slice.call(DOM);
}

//對的,這樣也可以的
let htmlCollection = document.getElementsByTagName("h2");
let arr1 = Array.prototype.map.call(htmlCollection,function (ele,index){return ele});
console.log(Array.isArray(arr1)) // true

// 還有這樣
let arrayLike = {0: "name", 1: "age", 2: "address", length: 3 }
let arr2  = Array.prototype.concat.apply([],arrayLike);
console.log(arr) //["name", "age", "address"]

// ES6現(xiàn)在這樣
let arrayLike = {0: "name", 1: "age", 2: "address", length: 3 }
let arr3 = Array.from(arrayLike);
console.log(arr3) // ["name", "age", "address"]
4、 JavaScript數(shù)組的進化——類型化數(shù)組的引入

先說一下普遍意義上的Array,數(shù)組是一串 連續(xù) 的內(nèi)存位置,用來保存某些值。JavaScript 中的數(shù)組是哈希映射,可以使用不同的數(shù)據(jù)結(jié)構(gòu)來實現(xiàn),如鏈表,上一個元素包含下一個元素的引用。這樣其他語言中數(shù)組的取值是根據(jù)內(nèi)存位置進行數(shù)學(xué)計算就能找到,而在JavaScript中就需要遍歷鏈表之類的結(jié)構(gòu),數(shù)組越長,遍歷鏈表跟數(shù)據(jù)計算相比就越慢。

現(xiàn)代 JavaScript 引擎是會給數(shù)組分配連續(xù)內(nèi)存的 —— 如果數(shù)組是同質(zhì)的(所有元素類型相同)。所以在寫代碼時保證數(shù)組同質(zhì),以便 JIT(即時編譯器)能夠使用 c 編譯器式的計算方法讀取元素是一種優(yōu)雅的方式。

不過,一旦你想要在某個同質(zhì)數(shù)組中插入一個其他類型的元素,JIT 將解構(gòu)整個數(shù)組,并按照舊有的方式重新創(chuàng)建。

ES6 增加了 ArrayBuffer, 提供一塊連續(xù)內(nèi)存供我們隨意操作。然而,直接操作內(nèi)存還是太復(fù)雜、偏底層。于是便有了處理 ArrayBuffer 的視圖(View)。

ArrayBuffer 對象用來表示通用的、固定長度的原始二進制數(shù)據(jù)緩沖區(qū)。ArrayBuffer 不能直接操作,而是要通過類型數(shù)組對象或 DataView 對象來操作,它們會將緩沖區(qū)中的數(shù)據(jù)表示為特定的格式,并通過這些格式來讀寫緩沖區(qū)的內(nèi)容。

語法: new ArrayBuffer(length)

參數(shù)
length:要創(chuàng)建的 ArrayBuffer 的大小,單位為字節(jié)。

返回值:一個指定大小的 ArrayBuffer 對象,其內(nèi)容被初始化為 0。

異常:如果 length 大于 Number.MAX_SAFE_INTEGER(>= 2 ** 53)或為負(fù)數(shù),則拋出一個  RangeError  異常。

類型數(shù)組對象 一個TypedArray 對象描述一個底層的二進制數(shù)據(jù)緩存區(qū)的一個類似數(shù)組(array-like)視圖。事實上,沒有名為 TypedArray的全局對象,也沒有一個名為的 TypedArray構(gòu)造函數(shù)。相反,有許多不同的全局對象,下面會列出這些針對特定元素類型的類型化數(shù)組的構(gòu)造函數(shù)。

new TypedArray(); // ES2017中新增
new TypedArray(length);
new TypedArray(typedArray);
new TypedArray(object);
new TypedArray(buffer [, byteOffset [, length]]);

TypedArray()指的是以下的其中之一:

Int8Array();//8位二進制帶符號整數(shù) -2^7~(2^7) - 1,大小1個字節(jié)
Uint8Array();//8位無符號整數(shù) 0~(2^8) - 1,大小1個字節(jié)
Int16Array();//16位二進制帶符號整數(shù) -2^15~(2^15)-1,大小2個字節(jié)
Uint16Array();//16位無符號整數(shù) 0~(2^16) - 1,大小2個字節(jié)
Int32Array();//    32位二進制帶符號整數(shù) -2^31~(2^31)-1,大小4個字節(jié)
Uint32Array();//32位無符號整數(shù) 0~(2^32) - 1,大小4個字節(jié)
Float32Array();//32位IEEE浮點數(shù),大小4個字節(jié)
Float64Array(); //64位IEEE浮點數(shù),大小8個字節(jié)

應(yīng)用:

var buffer = new ArrayBuffer(8);
var view   = new Int32Array(buffer);
view[0] = 100;
console.log(view)// [100,0],一個八個字節(jié),Int32Array一個元素大小是4個字節(jié),所以只能放下兩個元素
參考和鏈接

《JavaScript權(quán)威指南》數(shù)組部分

詳解JS遍歷

給初學(xué)者:JavaScript 中數(shù)組操作注意點

一次掌握 JavaScript ES5 到 ES8 數(shù)組內(nèi)容

【干貨】js 數(shù)組詳細(xì)操作方法及解析合集

【譯】深入 JavaScript 數(shù)組:進化與性能

彩蛋 彩蛋就是關(guān)注奇舞周刊啊,文章寫得好,想讓更多人看到的同學(xué),可以找我投稿啊。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/96660.html

相關(guān)文章

  • python 超好用迭代兵器庫itertools,十八般兵器哪18般?

    摘要:三國時代著名的兵器鑒別家呂虔根據(jù)兵器的特點對漢武帝欽定的十八般兵器重新排列為九長九短。明代五雜俎和清代堅集兩書所載十八般兵器為弓弩槍刀劍矛盾斧鉞戟黃锏撾殳棍叉耙頭錦繩套索白打拳術(shù)。后人稱其為小十八般。 知識點 在古典小說和傳統(tǒng)評話中,常說武藝高強的人是十八般武藝樣樣精通...

    番茄西紅柿 評論0 收藏2637
  • CSS布局十八般武藝都在這里了

    摘要:清單一些說明注意文檔的書寫順序,先寫兩側(cè)欄,再寫主面板,更換后則側(cè)欄會被擠到下一列圣杯布局和雙飛翼布局都會用到。可以通過設(shè)置的屬性或使用雙飛翼布局避免問題。雙飛翼布局不用設(shè)置相對布局,以及對應(yīng)的和值。 本文首發(fā)于知乎專欄:前端指南 CSS布局 布局是CSS中一個重要部分,本文總結(jié)了CSS布局中的常用技巧,包括常用的水平居中、垂直居中方法,以及單列布局、多列布局的多種實現(xiàn)方式(包括傳統(tǒng)的...

    includecmath 評論0 收藏0
  • SAP成都研究院李三郎:SCP Application Router簡介

    摘要:今天的文章來自李貝寧,成都研究院的資深程序猿和架構(gòu)師。是研究院內(nèi)部的教練,也是成都研究院若干內(nèi)部培訓(xùn)課程的講師。而李貝寧,在成都研究院三支分別使用和的開發(fā)團隊里都被任命為架構(gòu)師,技術(shù)的全面性不輸于史大郎。 今天的文章來自李貝寧(Ben),SAP成都研究院的資深程序猿和架構(gòu)師。 作為成都研究院里同時精通Java, JavaScript和ABAP這三門編程語言的數(shù)位同事之一,Ben曾經(jīng)先后...

    summerpxy 評論0 收藏0
  • 基于web接口自動化測試選型

    摘要:基于接口的自動化測試選型近期投入的一個項目需要做核心功能的測試場景自動化,以應(yīng)對部署復(fù)雜和跨系統(tǒng)間的流程驗證。雖然個人來講更熟悉和趁手,但是在接口自動化方面確實支持的更全面。 ...

    AprilJ 評論0 收藏0
  • “云計算”前生今世

    摘要:云計算一詞在從年開始在國內(nèi)興起被譽為科技領(lǐng)域的第四次技術(shù)革命好像不知道云計算都不好意思說自己從事工作那么云計算到底是什么意思就是如果想讓計算能力變強,怎么辦加,加內(nèi)存,加硬盤。云計算一詞在從07年開始在國內(nèi)興起被譽為科技領(lǐng)域的第四次技術(shù)革命(好像不知道云計算都不好意思說自己從事IT工作)那么云計算到底是什么?意思就是如果想讓計算能力變強,怎么辦?加CPU,加內(nèi)存,加硬盤。老板,我身上的孔已經(jīng)...

    姘擱『 評論0 收藏0

發(fā)表評論

0條評論

bergwhite

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<