摘要:返回值返回?cái)?shù)組新的長(zhǎng)度??蛇x整數(shù),表示要移除的數(shù)組元素的個(gè)數(shù)。返回值由被刪除的元素組成的一個(gè)數(shù)組。新增語(yǔ)法參數(shù)用來(lái)填充數(shù)組元素的值。
維護(hù)了一個(gè)持續(xù)更新的github筆記,可以去看看,誠(chéng)意之作(本來(lái)就是寫(xiě)給自己看的……)鏈接地址:Front-End-Basics
此篇文章的地址:JavaScript的數(shù)組
基礎(chǔ)筆記的github地址:https://github.com/qiqihaobenben/Front-End-Basics ,可以watch,也可以star。
正文開(kāi)始
數(shù)組數(shù)組是值的有序集合,每個(gè)值叫做一個(gè)元素,而每個(gè)元素在數(shù)組中有一個(gè)位置,以數(shù)字表示,稱(chēng)為索引。
JavaScript數(shù)組的索引是基于零的32位數(shù)值,第一個(gè)元素索引為0,數(shù)組最大能容納4294967295(即2^32-1)個(gè)元素。
JavaScript數(shù)組是動(dòng)態(tài)的,根據(jù)需要它們會(huì)增長(zhǎng)或縮減,并且在創(chuàng)建數(shù)組時(shí)無(wú)需聲明一個(gè)固定的大小或者在數(shù)組大小變化時(shí)無(wú)需重新分配空間。
JavaScript數(shù)組可能是稀疏的,數(shù)組元素的索引不一定要連續(xù)的,它們之間可以有空缺。
每個(gè)JavaScript數(shù)組都有一個(gè)length屬性,針對(duì)非稀疏數(shù)組,該屬性就是數(shù)組元素的個(gè)數(shù)。針對(duì)稀疏數(shù)組,length比所有元素的索引都要大。
創(chuàng)建數(shù)組 1、最簡(jiǎn)單的方法是使用數(shù)組直接量(字面量)創(chuàng)建數(shù)組。var empty = []; //沒(méi)有元素的數(shù)組 var arr = [1.1, true, "a",]; //3個(gè)不同類(lèi)型的元素和結(jié)尾的逗號(hào)
數(shù)組直接量中的值也不一定必須是常量,它們可以是任意的表達(dá)式:
var number = 1; var list = [number, number+1, number+2];
如果省略數(shù)組直接量中的某個(gè)值,省略的元素用empty表示(就是沒(méi)有這個(gè)元素),訪問(wèn)的話(huà)會(huì)返回undefined。
var count = [1,,3]; // 數(shù)組打印出來(lái)是(3) [1, empty, 3], count[1] === undefined是true。 var undefs = [,,]; // 數(shù)組直接量語(yǔ)法允許有可選的結(jié)尾的逗號(hào),顧[,,]只有兩個(gè)元素而非三個(gè),undefs.length 是 22、構(gòu)造函數(shù)Array()創(chuàng)建數(shù)組
調(diào)用時(shí)沒(méi)有參數(shù),等同于[],創(chuàng)建一個(gè)沒(méi)有任何元素的空數(shù)組
var arr = new Array();
調(diào)用時(shí)有一個(gè)數(shù)值參數(shù),它指定長(zhǎng)度
var arr = new Array(10) // (10) [empty × 10]
顯式指定兩個(gè)或者多個(gè)數(shù)組元素或者數(shù)組元素的一個(gè)非數(shù)值元素
var arr = new Array(1,2,3,"one");3、ES6的一些方法
(1)Array.of() 返回由所有參數(shù)組成的數(shù)組,不考慮參數(shù)的數(shù)量或類(lèi)型,如果沒(méi)有參數(shù)就返回一個(gè)空數(shù)組 (ES6新增)
參數(shù):
elementN 任意個(gè)參數(shù),將按順序成為返回?cái)?shù)組中的元素。
注意:
of() 可以解決上述構(gòu)造器因參數(shù)個(gè)數(shù)不同,導(dǎo)致的行為有差異的問(wèn)題(參數(shù)只有一個(gè)數(shù)值時(shí),構(gòu)造函數(shù)會(huì)把它當(dāng)成數(shù)組的長(zhǎng)度)。
Array.of(1,2,3); // [1,2,3] Array.of(1,{a:1},null,undefined) // [1, {a:1}, null, undefined] // 只有一個(gè)數(shù)值參數(shù)時(shí) let B = new Array(3); // (3) [empty × 3] let C = Array.of(3); // [3]
返回值: 新的 Array 實(shí)例。
(2)Array.from()從一個(gè)類(lèi)數(shù)組或可迭代對(duì)象中創(chuàng)建一個(gè)新的數(shù)組 (ES6新增)
參數(shù):
第一個(gè)參數(shù):想要轉(zhuǎn)換成數(shù)組的類(lèi)數(shù)組或可迭代對(duì)象
第二個(gè)參數(shù)(可選):回調(diào)函數(shù),類(lèi)似數(shù)組的map方法,對(duì)每個(gè)元素進(jìn)行處理,將處理后的值放入返回的數(shù)組。
第三個(gè)參數(shù)(可選):綁定回調(diào)函數(shù)的this對(duì)象
// 有l(wèi)ength屬性的類(lèi)數(shù)組 Array.from({length:5},(v,i) => i) //[0, 1, 2, 3, 4] // 部署了Iterator接口的數(shù)據(jù)結(jié)構(gòu) 比如:字符串、Set、NodeList對(duì)象 Array.from("hello") // ["h","e","l","l","o"] Array.from(new Set(["a","b"])) // ["a","b"] // 傳入一個(gè)數(shù)組生成的是一個(gè)新的數(shù)組,引用不同,修改新數(shù)組不會(huì)改變?cè)瓟?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í)例。
知識(shí)點(diǎn)
//數(shù)組合并去重 function combine(){ let arr = [].concat.apply([], arguments); //沒(méi)有去重復(fù)的新數(shù)組,之后用Set數(shù)據(jù)結(jié)構(gòu)的特性來(lái)去重 return Array.from(new Set(arr)); } var m = [1, 2, 2], n = [2,3,3]; console.log(combine(m,n));
參數(shù): item1, item2, ..., itemX ,要添加到數(shù)組末尾的元素
let arr = [1,2,3]; let length = arr.push("末尾1","末尾2"); // 返回?cái)?shù)組長(zhǎng)度 console.log(arr,length) // [1, 2, 3, "末尾1", "末尾2"] 5
返回值: 數(shù)組的長(zhǎng)度
參數(shù):無(wú)
//組合使用push()和pop()能夠用JavaScript數(shù)組實(shí)現(xiàn)先進(jìn)后出的棧 let stack = []; stack.push(1,2) // 返回長(zhǎng)度2,這時(shí)stack的值是[1,2] stack.pop() // 返回刪除的值2,這時(shí)stack的值是[1]
返回值: 從數(shù)組中刪除的元素(當(dāng)數(shù)組為空時(shí)返回undefined)。
參數(shù): item1, item2, ..., itemX ,要添加到數(shù)組開(kāi)頭的元素
let arr = [3,4,5]; let length = arr.unshift(1,2); // 返回長(zhǎng)度是5 console.log(arr, length) //[1, 2, 3, 4, 5] 5
注意: 當(dāng)調(diào)用unshift()添加多個(gè)參數(shù)時(shí),參數(shù)時(shí)一次性插入的,而非一次一個(gè)地插入。就像是上例添加1和2,他們插入到數(shù)組中的順序跟參數(shù)列表中的順序一致,而不是[2,1,3,4,5]。
返回值: 返回?cái)?shù)組新的長(zhǎng)度。
參數(shù): 無(wú)。
let arr = [1,2,3]; let item = arr.shift(); // 返回刪除的值1 console.log(arr, item) // [2, 3] 1
返回值: 從數(shù)組中刪除的元素; 如果數(shù)組為空則返回undefined 。
語(yǔ)法
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
參數(shù):
start?
指定修改的開(kāi)始位置(從0計(jì)數(shù))。如果超出了數(shù)組的長(zhǎng)度,則從數(shù)組末尾開(kāi)始添加內(nèi)容;如果是負(fù)值,則表示從數(shù)組末位開(kāi)始的第幾位(從-1計(jì)數(shù));若只使用start參數(shù)而不使用deleteCount、item,如:array.splice(start) ,表示刪除[start,end]的元素。
deleteCount (可選)
整數(shù),表示要移除的數(shù)組元素的個(gè)數(shù)。如果 deleteCount 是 0,則不移除元素。這種情況下,至少應(yīng)添加一個(gè)新元素。如果 deleteCount 大于start 之后的元素的總數(shù),則從 start 后面的元素都將被刪除(含第 start 位)。
如果deleteCount被省略,則其相當(dāng)于(arr.length - start)。
item1, item2, ... (可選)
要添加進(jìn)數(shù)組的元素,從start 位置開(kāi)始。如果不指定,則 splice() 將只刪除數(shù)組元素。
返回值: 由被刪除的元素組成的一個(gè)數(shù)組。如果只刪除了一個(gè)元素,則返回只包含一個(gè)元素的數(shù)組。如果沒(méi)有刪除元素,則返回空數(shù)組。
// start不超過(guò)數(shù)組長(zhǎng)度(以下操作是連續(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],因?yàn)榇藭r(shí)數(shù)組從第0位開(kāi)始不夠3位,所以是刪除從0開(kāi)始到最后的所有元素。 // start大于數(shù)組長(zhǎng)度(以下操作是連續(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ù)組本身,而不是數(shù)組元素 let arr = [1,4,5]; arr.splice(1,0,[2,3]) // arr是[1,[2,3],4,5],返回值是[]
參數(shù):
compareFunction (可選) 用來(lái)指定按某種順序進(jìn)行排列的函數(shù)。如果省略,元素按照轉(zhuǎn)換為的字符串的各個(gè)字符的Unicode位點(diǎn)進(jìn)行排序。
如果指明了 compareFunction ,那么數(shù)組會(huì)按照調(diào)用該函數(shù)的返回值排序。即 a 和 b 是兩個(gè)將要被比較的元素:
如果 compareFunction(a, b) 小于 0 ,那么 a 會(huì)被排列到 b 之前;
如果 compareFunction(a, b) 等于 0 , a 和 b 的相對(duì)位置不變。備注: ECMAScript 標(biāo)準(zhǔn)并不保證這一行為,而且也不是所有瀏覽器都會(huì)遵守(例如 Mozilla 在 2003 年之前的版本);
如果 compareFunction(a, b) 大于 0 , b 會(huì)被排列到 a 之前。
compareFunction(a, b) 必須總是對(duì)相同的輸入返回相同的比較結(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()); // 沒(méi)有使用比較函數(shù)時(shí),數(shù)字并不會(huì)按照我們?cè)O(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ù)組代替。
參數(shù): 無(wú)
let arr = [1,2,3]; arr.reverse() // arr是[3,2,1],返回值是[3,2,1]
返回值: 返回順序顛倒后的數(shù)組。原數(shù)組已經(jīng)被排序后的數(shù)組代替。
語(yǔ)法:
arr.copyWithin(target[, start[, end]])
參數(shù):
target
0 為基底的索引,復(fù)制序列到該位置。如果是負(fù)數(shù),target 將從末尾開(kāi)始計(jì)算。
如果 target 大于等于 arr.length,將會(huì)不發(fā)生拷貝。如果 target 在 start 之后,復(fù)制的序列將被修改以符合 arr.length。
start
0 為基底的索引,開(kāi)始復(fù)制元素的起始位置。如果是負(fù)數(shù),start 將從末尾開(kāi)始計(jì)算。
如果 start 被忽略,copyWithin 將會(huì)從0開(kāi)始復(fù)制。
end
0 為基底的索引,開(kāi)始復(fù)制元素的結(jié)束位置。copyWithin 將會(huì)拷貝到該位置,但不包括 end 這個(gè)位置的元素。如果是負(fù)數(shù), end 將從末尾開(kāi)始計(jì)算。
如果 end 被忽略,copyWithin 將會(huì)復(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è)計(jì)為通用的,其不要求其 this 值必須是一個(gè)數(shù)組對(duì)象。 [].copyWithin.call({length: 5, 3: 1}, 0, 3); // {0: 1, 3: 1, length: 5}
語(yǔ)法:
arr.fill(value[, start[, end]])
參數(shù):
value 用來(lái)填充數(shù)組元素的值。
start (可選) 起始索引,默認(rèn)值為0。
end (可選) 終止索引,默認(rèn)值為 this.length。
如果 start 是個(gè)負(fù)數(shù), 則開(kāi)始索引會(huì)被自動(dòng)計(jì)算成為 length+start, 其中 length 是 this 對(duì)象的 length 屬性值. 如果 end 是個(gè)負(fù)數(shù), 則結(jié)束索引會(huì)被自動(dòng)計(jì)算成為 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è)計(jì)成通用方法, 該方法不要求 this 是數(shù)組對(duì)象。 [].fill.call({ length: 3 }, 4); // {0: 4, 1: 4, 2: 4, length: 3}
參數(shù):
begin (可選)
從該索引處開(kāi)始提取原數(shù)組中的元素(從0開(kāi)始)。
如果該參數(shù)為負(fù)數(shù),則表示從原數(shù)組中的倒數(shù)第幾個(gè)元素開(kāi)始提取,slice(-2)表示提取原數(shù)組中的倒數(shù)第二個(gè)元素到最后一個(gè)元素(包含最后一個(gè)元素)。
如果省略 begin,則 slice 從索引 0 開(kāi)始。
end (可選)
在該索引處結(jié)束提取原數(shù)組元素(從0開(kāi)始)。
slice會(huì)提取原數(shù)組中索引從 begin 到 end 的所有元素(包含begin,但不包含end)。
slice(1,4) 提取原數(shù)組中的第二個(gè)元素開(kāi)始直到第四個(gè)元素的所有元素 (索引為 1, 2, 3的元素)。
如果該參數(shù)為負(fù)數(shù), 則它表示在原數(shù)組中的倒數(shù)第幾個(gè)元素結(jié)束抽取。 slice(-2,-1)表示抽取了原數(shù)組中的倒數(shù)第二個(gè)元素到最后一個(gè)元素(不包含最后一個(gè)元素,也就是只有倒數(shù)第二個(gè)元素)。
如果 end 被省略,則slice 會(huì)一直提取到原數(shù)組末尾。
如果 end 大于數(shù)組長(zhǎng)度,slice 也會(huì)一直提取到原數(shù)組末尾。
返回值: 一個(gè)含有提取元素的新數(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] // 開(kāi)始位置在結(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是[] //如果元素是個(gè)對(duì)象引用 (不是實(shí)際的對(duì)象),slice 會(huì)拷貝這個(gè)對(duì)象引用到新的數(shù)組里。兩個(gè)對(duì)象引用都引用了同一個(gè)對(duì)象。如果被引用的對(duì)象發(fā)生改變,則新的和原來(lái)的數(shù)組中的這個(gè)元素也會(huì)發(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"}] // 對(duì)于字符串、數(shù)字及布爾值來(lái)說(shuō)(不是 String、Number 或者 Boolean 對(duì)象),slice 會(huì)拷貝這些值到新的數(shù)組里。在別的數(shù)組里修改這些字符串或數(shù)字或是布爾值,將不會(huì)影響另一個(gè)數(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)然,如果向兩個(gè)數(shù)組任一中添加了新元素(簡(jiǎn)單或者引用類(lèi)型),則另一個(gè)不會(huì)受到影響。
參數(shù):
separator (可選)
指定一個(gè)字符串來(lái)分隔數(shù)組的每個(gè)元素。
如果有(separator),將分隔符轉(zhuǎn)換為字符串。
如果省略(),數(shù)組元素用逗號(hào)分隔。默認(rèn)為 ","。
如果separator是空字符串(""),則所有元素之間都沒(méi)有任何字符。
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)換成字符串,再用一個(gè)分隔符將這些字符串連接起來(lái)。如果元素是undefined 或者null, 則會(huì)轉(zhuǎn)化成空字符串。 let num = [1,null,3]; let str1 = num.join(); // 1,,3 //如果數(shù)組中的元素是數(shù)組,會(huì)將里面的數(shù)組也調(diào)用join() let num = [[1,2],3]; let str1 = num.join("-"); // 1,2-3 // 如果數(shù)組中的元素是對(duì)象,對(duì)象會(huì)被轉(zhuǎn)為[object Object]字符串 let num = [{num: 1},2,3]; let str1 = num.join("-"); // [object Object]-2-3
返回值: 一個(gè)所有數(shù)組元素連接的字符串。如果 arr.length 為0,則返回空字符串
知識(shí)點(diǎn)
// 扁平化簡(jiǎn)單的二維數(shù)組 const arr = [11, [22, 33], [44, 55], 66]; const flatArr = arr.join().split(","); // ["11", "22", "33", "44", "55", "66"]
參數(shù): 無(wú)
[1,2,3].toString(); // 1,2,3 [1,[2,"c"]].toString(); //1,2,c // 以上與不使用任何參數(shù)調(diào)用join()方法返回的字符串是一樣的。 // 以下的這個(gè)例子要跟下面的toLocaleString對(duì)照看 [{a:1},1,new Date()].toString() //"[object Object],1,Sat Jul 07 2018 18:43:45 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"
注意: 當(dāng)數(shù)組和字符串操作的時(shí)候,js 會(huì)調(diào)用這個(gè)方法將數(shù)組自動(dòng)轉(zhuǎn)換成字符串
[1,2,3]+"abc" //1,2,3abc
返回值: 返回一個(gè)字符串表示數(shù)組中的元素
知識(shí)點(diǎn)
// 扁平化簡(jiǎn)單的二維數(shù)組 const arr = [11, [22, 33], [44, 55], 66]; const flatArr = arr.toString().split(","); // ["11", "22", "33", "44", "55", "66"]
參數(shù):(還有待考證,我試了一下沒(méi)用,看了一下ECMA的官網(wǎng),確實(shí)是標(biāo)注有兩個(gè)可選參數(shù)的)
locales (可選) 帶有BCP 47語(yǔ)言標(biāo)記的字符串或字符串?dāng)?shù)組
options (可選) 一個(gè)可配置屬性的對(duì)象
//數(shù)組中的元素將會(huì)使用各自的 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上的舉例中說(shuō)是 "¥7,¥500,¥8,123,¥12",在瀏覽器和Node中驗(yàn)證了返回的都是 "¥7,500,8,123,12" 啊! // 以下的這個(gè)例子要跟上面的toString對(duì)照看 [{a:1},1,new Date()].toLocaleString() //"[object Object],1,2018/7/7 下午6:45:00"
返回值: 表示數(shù)組元素的字符串。
它的元素包括調(diào)用concat()的原始數(shù)組的元素和concat()的每個(gè)參數(shù),但是要注意,concat()不會(huì)遞歸扁平化數(shù)組的數(shù)組,concat()也不會(huì)修改調(diào)用的數(shù)組。
參數(shù):
valueN (可選) 將(多個(gè))數(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方法不會(huì)改變this或任何作為參數(shù)提供的數(shù)組,而是返回一個(gè)淺拷貝,所以原始數(shù)組和新數(shù)組都引用相同的對(duì)象。 如果引用的對(duì)象被修改,新數(shù)組和原始數(shù)組都會(huì)變。 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}] // 說(shuō)了是淺拷貝,而且原數(shù)組也不改變,那我們就可以用它來(lái)實(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 實(shí)例
知識(shí)點(diǎn)
// concat 和擴(kuò)展運(yùn)算符可以快速扁平化數(shù)組 const arr = [11, [22, 33], [44, 55], 66]; const flatArr = [].concat(...arr); // [11, 22, 33, 44, 55, 66]
參數(shù):
obj 需要檢測(cè)的值。
// 下面的函數(shù)調(diào)用都返回 true Array.isArray([]); Array.isArray([1]); Array.isArray(new Array()); // 這里注意:Array.prototype 也是一個(gè)數(shù)組,一個(gè)屬性值不是索引的數(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 });
返回值: 如果對(duì)象是 Array,則為true; 否則為false。
知識(shí)點(diǎn)
//判斷數(shù)組的歷程 // step one: 使用constructor var a = [1]; console.log(a.constructor === Array) // true // 但是原型的contructor屬性是可以被改寫(xiě)的,例如在原型繼承的時(shí)候,我們都是要把繼承過(guò)來(lái)的prototype的constructor改寫(xiě)成我們當(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不能檢測(cè)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 :萬(wàn)無(wú)一失的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,也可以檢測(cè)iframes的數(shù)組
介紹方法之前,先對(duì)這些數(shù)組方法做一個(gè)概述:
首先,大多數(shù)方法的第一個(gè)參數(shù)接收一個(gè)函數(shù),并且對(duì)數(shù)組的每個(gè)元素(或一些元素)調(diào)用一次該函數(shù)。如果是稀疏數(shù)組,對(duì)不存在的元素不調(diào)用該函數(shù)。大多數(shù)情況下,調(diào)用提供的函數(shù)使用三個(gè)參數(shù):數(shù)組元素、元素的索引和數(shù)組本身。通常,只需要第一個(gè)參數(shù)值,可以忽略后兩個(gè)參數(shù)。
大多數(shù)方法,第二個(gè)參數(shù)是可選的。如果有第二個(gè)參數(shù),則調(diào)用的第一個(gè)函數(shù)參數(shù)被看做是第二個(gè)參數(shù)的方法,即當(dāng)執(zhí)行第一個(gè)函數(shù)參數(shù)時(shí)用作this的值(參考對(duì)象)。
方法的返回值很重要,不同的方法處理返回值的方式也不一樣。
下面這些方法運(yùn)行時(shí)的規(guī)則:
對(duì)于空數(shù)組是不會(huì)執(zhí)行回調(diào)函數(shù)的
對(duì)于已在迭代過(guò)程中刪除的元素,或者空元素會(huì)跳過(guò)回調(diào)函數(shù)
遍歷次數(shù)在第一次循環(huán)前就會(huì)確定,再添加到數(shù)組中的元素不會(huì)被遍歷。
如果已經(jīng)存在的值被改變,則傳遞給 callback 的值是遍歷到他們那一刻的值。
已刪除的項(xiàng)不會(huì)被遍歷到。如果已訪問(wèn)的元素在迭代時(shí)被刪除了(例如使用 shift()) ,之后的元素將被跳過(guò)
參數(shù):
callback 為數(shù)組中每個(gè)元素執(zhí)行的函數(shù),該函數(shù)接收三個(gè)參數(shù):
currentValue(當(dāng)前值) 數(shù)組中正在處理的當(dāng)前元素。
index(索引) 數(shù)組中正在處理的當(dāng)前元素的索引。
array forEach()方法正在操作的數(shù)組。
thisArg (可選) 當(dāng)執(zhí)行回調(diào)函數(shù)時(shí)用作this的值(參考對(duì)象)。默認(rèn)值為undefined
注意:
forEach無(wú)法中途退出循環(huán),只能用return退出本次回調(diào),進(jìn)行下一次回調(diào),如果要提前終止,可以把forEach方法放在try塊中,并能拋出一個(gè)異常,但這種方法是不推薦的。
它與之后會(huì)說(shuō)到的幾個(gè)方法不同,總是返回 undefined值,即使你return了一個(gè)值。
// 1、 空元素不遍歷,undefined和null是會(huì)遍歷的。 let numberArr = [1,2,,3]; numberArr.forEach(function (value,index,array) { console.log(value,index,array) }) //打印信息如下,可見(jiàn)空元素是不會(huì)遍歷的 //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是會(huì)遍歷的 //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、已刪除的項(xiàng)不會(huì)被遍歷到。如果已訪問(wèn)的元素在迭代時(shí)被刪除了,之后的元素將被跳過(guò) let numberArr = [1,2,3]; numberArr.forEach(function (value,index,array) { if(index === 0) { delete numberArr[2]; //刪除第三項(xiàng) //或者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() //遍歷到第二項(xiàng)的時(shí)候,刪除第一項(xiàng) } console.log(value,index,array) }) // 打印信息如下,遍歷到第二項(xiàng)的時(shí)候,刪除第一項(xiàng),會(huì)跳過(guò)第三項(xiàng) // 1 0 (4) [1, 2, 3, 4] // 2 1 (3) [2, 3, 4] // 4 2 (3) [2, 3, 4] // 3、forEach 遍歷的范圍在第一次調(diào)用 callback 前就會(huì)確定。調(diào)用forEach 后添加到數(shù)組中的項(xiàng)不會(huì)被 callback 訪問(wèn)到。如果已經(jīng)存在的值被改變,則傳遞給 callback 的值是 forEach 遍歷到他們那一刻的值。 let arr = [1,2,3]; arr.forEach(function (value,index,array) { if(index === 0) { arr.push("新增的不會(huì)被遍歷到") arr[2] = 4; } console.log(value,index,array) }) // 1 0 (4) [1, 2, 4, "新增的不會(huì)被遍歷到"] // 2 1 (4) [1, 2, 4, "新增的不會(huì)被遍歷到"] // 4 2 (4) [1, 2, 4, "新增的不會(huì)被遍歷到"] // 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無(wú)法中途退出循環(huán),只能用return退出本次回調(diào),進(jìn)行下一次回調(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的值如下,說(shuō)明return 并不能終止循環(huán) // 1 // 3
返回值: undefined
參數(shù):(之前說(shuō)過(guò),大多說(shuō)方法都會(huì)是這樣一些參數(shù))
callback 生成新數(shù)組元素的函數(shù),使用三個(gè)參 這個(gè)函數(shù)跟forEach()的函數(shù)不同的是,傳遞給map()的函數(shù)應(yīng)該有返回值。
currentValue callback 的第一個(gè)參數(shù),數(shù)組中正在處理的當(dāng)前元素。
index callback 的第二個(gè)參數(shù),數(shù)組中正在處理的當(dāng)前元素的索引。
array callback 的第三個(gè)參數(shù),map 方法被調(diào)用的數(shù)組。
thisArg (可選) 執(zhí)行 callback 函數(shù)時(shí) 使用的this 值。
注意: map() 返回的是新數(shù)組,它不修改調(diào)用的數(shù)組。如果是稀疏數(shù)組,返回的也是相同方式的稀疏數(shù)組:它具有相同的長(zhǎng)度,相同索引的缺失元素(因?yàn)榭罩挡粫?huì)調(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]
返回值: 一個(gè)新數(shù)組,每個(gè)元素都是回調(diào)函數(shù)的結(jié)果
知識(shí)點(diǎn)
不要用 map 代替 forEach,map 會(huì)創(chuàng)建一個(gè)新的數(shù)組,占用內(nèi)存。如果你不用 map 的返回值,那你就應(yīng)當(dāng)使用 forEach
參數(shù):
callback 用來(lái)測(cè)試數(shù)組的每個(gè)元素的函數(shù)。調(diào)用時(shí)使用參數(shù) (element, index, array)。返回true表示保留該元素(通過(guò)測(cè)試),false則不保留。它接受三個(gè)參數(shù):
element 當(dāng)前在數(shù)組中處理的元素
index(可選) 正在處理元素在數(shù)組中的索引
array(可選)調(diào)用了filter篩選器的數(shù)組
thisArg(可選)可選。執(zhí)行 callback 時(shí)的用于 this 的值。
注意:
callback 只會(huì)在已經(jīng)賦值的索引上被調(diào)用,對(duì)于那些已經(jīng)被刪除或者從未被賦值的索引不會(huì)被調(diào)用。也就是說(shuō)filter()會(huì)跳過(guò)稀疏數(shù)組中缺少的元素,它的返回?cái)?shù)組總是稠密的,可以用這個(gè)方法壓縮稀疏數(shù)組的空缺。
filter 不會(huì)改變?cè)瓟?shù)組,它返回過(guò)濾后的新數(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]
返回值: 一個(gè)新的通過(guò)測(cè)試的元素的集合的數(shù)組,如果沒(méi)有通過(guò)測(cè)試則返回空數(shù)組。
參數(shù):
callback 用來(lái)測(cè)試每個(gè)元素的函數(shù)。
thisArg 執(zhí)行 callback 時(shí)使用的 this 值。
注意:
every 方法為數(shù)組中的每個(gè)元素執(zhí)行一次 callback 函數(shù),callback 只會(huì)為那些已經(jīng)被賦值的索引調(diào)用。不會(huì)為那些被刪除或從來(lái)沒(méi)被賦值的索引調(diào)用。every 方法在callback第一次返回false后就返回false,然后終止遍歷。但如果callback一直返回true,它將會(huì)遍歷整個(gè)數(shù)組,最終返回true。
空數(shù)組上調(diào)用every方法,返回 true,因?yàn)榭諗?shù)組沒(méi)有元素,所以空數(shù)組中所有元素都符合給定的條件
every 不會(huì)改變?cè)瓟?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 // 可見(jiàn)發(fā)現(xiàn)5這個(gè)小于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 // 不會(huì)遍歷沒(méi)有賦值的索引位置,所以num為4 let result = [].every(function (element, index, array) { return element > 10; }) console.log(result) // 打印 true
返回值: 一個(gè)布爾值,當(dāng)所有的元素都符合條件才返回true,否則返回false
參數(shù):
callback 用來(lái)測(cè)試每個(gè)元素的函數(shù)
thisArg 可選 執(zhí)行 callback 時(shí)使用的 this 值。
注意:
some 為數(shù)組中的每一個(gè)元素執(zhí)行一次 callback 函數(shù),直到找到一個(gè)使得 callback 返回一個(gè)“真值”,這時(shí),some 將會(huì)立即返回 true。否則,some 返回 false。callback 只會(huì)在那些”有值“的索引上被調(diào)用,不會(huì)在那些被刪除或從來(lái)未被賦值的索引上調(diào)用。
some 被調(diào)用時(shí)不會(huì)改變數(shù)組。
空數(shù)組調(diào)用some,返回false
// 一個(gè)簡(jiǎn)單的例子說(shuō)明 function isBiggerThan10(element, index, array) { return element > 10; } [2, 5, 8, 1, 4].some(isBiggerThan10); // false [12, 5, 8, 1, 4].some(isBiggerThan10); // true // 實(shí)現(xiàn)一個(gè)跟includes方法類(lèi)似的功能 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ù)組中的任意一個(gè)元素在回調(diào)函數(shù)中返回的是真值,就返回true,否則為false
參數(shù):
callback 執(zhí)行數(shù)組中每個(gè)值的函數(shù),包含四個(gè)參數(shù):
accumulator 累加器累加回調(diào)的返回值; 它是上一次調(diào)用回調(diào)時(shí)返回的累積值,或initialValue(如下所示)。
currentValue 數(shù)組中正在處理的元素。
currentIndex (可選) 數(shù)組中正在處理的當(dāng)前元素的索引。 如果提供了initialValue,則索引號(hào)為0,否則為索引為1。
array (可選) 調(diào)用reduce的數(shù)組
initialValue (可選) 用作第一個(gè)調(diào)用 callback的第一個(gè)參數(shù)的值。 如果沒(méi)有提供初始值,則將使用數(shù)組中的第一個(gè)元素。 在沒(méi)有初始值的空數(shù)組上調(diào)用 reduce 將報(bào)錯(cuò)。
注意:
reduce為數(shù)組中的每一個(gè)元素依次執(zhí)行callback函數(shù),不包括數(shù)組中被刪除或從未被賦值的元素,回調(diào)函數(shù)第一次執(zhí)行時(shí),accumulator 和currentValue的取值有兩種情況:調(diào)用reduce時(shí)提供initialValue,accumulator取值為initialValue,currentValue取數(shù)組中的第一個(gè)值;沒(méi)有提供 initialValue,accumulator取數(shù)組中的第一個(gè)值,currentValue取數(shù)組中的第二個(gè)值。即:如果沒(méi)有提供initialValue,reduce 會(huì)從索引1的地方開(kāi)始執(zhí)行 callback 方法,跳過(guò)第一個(gè)索引。如果提供initialValue,從索引0開(kāi)始。
如果數(shù)組為空且沒(méi)有提供initialValue,會(huì)拋出TypeError 。如果數(shù)組僅有一個(gè)元素(無(wú)論位置如何)并且沒(méi)有提供initialValue, 或者有提供initialValue但是數(shù)組為空,那么此唯一值將被返回并且callback不會(huì)被執(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 沒(méi)傳入initialValue,索引是從1開(kāi)始 arr.reduce(function (accumulator,currentValue,currentIndex,arr) { console.log(currentIndex) return accumulator + currentValue; },10) // 0,1,2,3,4,5 傳入initialValue,索引從0開(kāi)始 // 應(yīng)用到二維數(shù)組展開(kāi) let arr = [[0, 1], [2, 3], [4, 5]].reduce( (a, b) => a.concat(b) ); console.log(arr) // [0, 1, 2, 3, 4, 5]
返回值: 函數(shù)累計(jì)處理的結(jié)果
參數(shù):
searchElement 要查找的元素
fromIndex (可選)開(kāi)始查找的位置。
如果該索引值大于或等于數(shù)組長(zhǎng)度,意味著不會(huì)在數(shù)組里查找,返回-1。
如果該索引值是負(fù)值,代表相對(duì)數(shù)組末尾的偏移量,即-1表示從最后一個(gè)元素開(kāi)始查找,-2表示從倒數(shù)第二個(gè)元素開(kāi)始查找,注意的是,這并不改變其查找順序,查找順序仍然是從前向后查詢(xún)數(shù)組。
如果該索引值是負(fù)值,其絕對(duì)值大于數(shù)組長(zhǎng)度,則整個(gè)數(shù)組都將會(huì)被查詢(xún)。其默認(rèn)值為0。
注意: indexOf 使用嚴(yán)格相等(即 ===)比較 searchElement 和數(shù)組中的元素。而且indexOf()不能識(shí)別 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
返回值: 首個(gè)被找到的元素在數(shù)組中的索引位置; 若沒(méi)有找到則返回 -1
參數(shù):
searchElement 要查找的元素
fromIndex (可選)開(kāi)始查找的位置。默認(rèn)為數(shù)組的長(zhǎng)度減 1,即整個(gè)數(shù)組都被查找。
如果該值大于或等于數(shù)組的長(zhǎng)度,則整個(gè)數(shù)組會(huì)被查找。
如果為負(fù)值,將其視為從數(shù)組末尾向前的偏移。即使該值為負(fù),數(shù)組仍然會(huì)被從后向前查找。
如果該值為負(fù)時(shí),其絕對(duì)值大于數(shù)組長(zhǎng)度,則方法返回 -1,即數(shù)組不會(huì)被查找。
注意: lastIndexOf 使用嚴(yán)格相等(即 ===)比較 searchElement 和數(shù)組中的元素。而且lastIndexOf()不能識(shí)別 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ù)組中最后一個(gè)符合元素的索引,如未找到返回-1
參數(shù):
searchElement 需要查找的元素值。
fromIndex (可選) 從該索引處開(kāi)始查找 searchElement。默認(rèn)為 0。如果為負(fù)值,則按升序從 array.length + fromIndex 的索引開(kāi)始搜索。負(fù)值絕對(duì)值超過(guò)長(zhǎng)數(shù)組度,從0開(kāi)始搜索。
如果fromIndex 大于等于數(shù)組長(zhǎng)度 ,則返回 false 。該數(shù)組不會(huì)被搜索。
注意:
includes解決了兩個(gè)indexOf的問(wèn)題:
indexOf方法不能識(shí)別NaN
indexOf方法檢查是否包含某個(gè)值不夠語(yǔ)義化,需要判斷是否不等于-1,表達(dá)不夠直觀
[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
返回值: 一個(gè)布爾值,根據(jù)情況,如果包含則返回 true,否則返回false。
參數(shù): 這兩個(gè)方法跟其他的方法類(lèi)似
callback 在數(shù)組每一項(xiàng)上執(zhí)行的函數(shù),接收 3 個(gè)參數(shù):
element 當(dāng)前遍歷到的元素。
index 當(dāng)前遍歷到的索引。
array 數(shù)組本身。
thisArg 可選,指定 callback 的 this 參數(shù)。
注意:
這兩個(gè)方法對(duì)數(shù)組中的每一項(xiàng)元素執(zhí)行一次 callback 函數(shù),直至有一個(gè) callback 返回 true。在稀疏數(shù)組中,即使對(duì)于數(shù)組中不存在的條目的索引也會(huì)調(diào)用回調(diào)函數(shù)。 這意味著對(duì)于稀疏數(shù)組來(lái)說(shuō),該方法的效率要低于那些只遍歷有值的索引的方法。
當(dāng)找到一個(gè)callback判斷為true的元素,find方法會(huì)立即返回這個(gè)元素的值,否則返回 undefined。findIndex會(huì)立即返回該元素的索引。如果回調(diào)從不返回真值,或者數(shù)組的length為0,則findIndex返回-1。
這兩個(gè)方法都不會(huì)修改所調(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也會(huì)調(diào)用一次,而且返回為true,立即退出 return n === 3; })
返回值:
find 方法,當(dāng)某個(gè)元素通過(guò) callback 的測(cè)試時(shí),返回?cái)?shù)組中的一個(gè)值,否則返回 undefined。
findIndex方法,返回?cái)?shù)組中滿(mǎn)足提供的測(cè)試函數(shù)的第一個(gè)元素的索引。否則返回-1。
知識(shí)點(diǎn)
不要用 find() 代替 some(),通?;煊檬沁@種場(chǎng)景,find 返回第一個(gè)符合條件的值,直接拿這個(gè)值做 if 判斷是否存在,但是這個(gè)符合條件的值也有可能恰好為 0。
find 是找到數(shù)組中的值后對(duì)其進(jìn)一步處理,一般用于對(duì)象數(shù)組的情況;some 才是檢查存在性;兩者不可混用。
參數(shù): 都是無(wú)。
都是一個(gè)新的 Array 迭代器對(duì)象。
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"
數(shù)組是對(duì)象的特殊形式,使用方括號(hào)訪問(wèn)數(shù)組元素和使用方括號(hào)訪問(wèn)對(duì)象屬性一樣。JavaScript將指定的數(shù)字索引值轉(zhuǎn)換成字符串——索引1變成"1"——然后將其作為屬性名來(lái)使用。數(shù)組的特別之處在于,當(dāng)使用小于2^32的非負(fù)整數(shù)作為屬性名時(shí)數(shù)組會(huì)自動(dòng)維護(hù)其length屬性。
// 索引到屬性名的轉(zhuǎn)化 let arr = [1,2,3]; console.log(arr[1]) // 2 console.log(arr["1"]) // 2
所有的數(shù)組都是對(duì)象,可以為其創(chuàng)建任意名字的屬性,不過(guò),只有在小于2^32的非負(fù)整數(shù)才是索引,數(shù)組才會(huì)根據(jù)需要更新length。事實(shí)上數(shù)組的索引僅僅是對(duì)象屬性名的一種特殊類(lèi)型,這意味著JavaScript數(shù)組沒(méi)有“越界”錯(cuò)誤的概念。當(dāng)查詢(xún)?nèi)魏螌?duì)象中不存在的屬性時(shí),不會(huì)報(bào)錯(cuò),只會(huì)得到undefined
let arr = []; arr["a"] = 1; console.log(arr,arr.length) // arr是[a:1] length是0
對(duì)于使用負(fù)數(shù)或非整數(shù)的情況,數(shù)值會(huì)轉(zhuǎn)換為字符串,字符串作為屬性名來(lái)用,當(dāng)時(shí)只能當(dāng)做常規(guī)的對(duì)象屬性,而非數(shù)組的索引。
let arr = []; arr[-1.23] = 0; console.log(arr,arr.length) // arr是[-1.23: 0] length是0
使用非負(fù)整數(shù)的字符串或者一個(gè)跟整數(shù)相等的浮點(diǎn)數(shù)時(shí),它就當(dāng)做數(shù)組的索引而非對(duì)象屬性。
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 是22、稀疏數(shù)組
稀疏數(shù)組就是包含從0開(kāi)始的不連續(xù)索引的數(shù)組。通常數(shù)組的length屬性值代表數(shù)組中元素的個(gè)數(shù)。如果數(shù)組是稀疏的,length屬性值大于元素的個(gè)數(shù)
足夠稀疏的數(shù)組通常在實(shí)現(xiàn)上比稠密的數(shù)組更慢,更耗內(nèi)存,在這樣的數(shù)組中查找元素所用的時(shí)間就變得跟常規(guī)對(duì)象的查找時(shí)間一樣長(zhǎng)了,失去了性能的優(yōu)勢(shì)。
let a1 = [,,]; // 數(shù)組直接量,該數(shù)組是[empty × 2] 0 in a1 // false: a1在索引0處沒(méi)有元素 let a2 = new Array(3); //[empty × 3],該數(shù)組根本沒(méi)有元素 0 in a2 // false: a2在索引0處沒(méi)有元素 let a3 = [undefined]; 0 in a3 // true: a3在索引0處有一個(gè)值為undefined的元素 let a4 = [,undefined]; 0 in a4 // fasle: a4在索引0處沒(méi)有元素 1 in a4 // true: a4在索引1處有一個(gè)值為undefined的元素 console.log(a4[0],a4[1]) // undefined undefined,可見(jiàn)數(shù)組訪問(wèn)返回undefined,可能是稀疏數(shù)組,也可能是數(shù)組元素為undefined3、類(lèi)數(shù)組對(duì)象
擁有一個(gè)數(shù)值length屬性和對(duì)應(yīng)非負(fù)整數(shù)屬性的對(duì)象看做一種類(lèi)型的數(shù)組
數(shù)組跟類(lèi)數(shù)組相比有以下不同:
當(dāng)有新元素添加到數(shù)組中時(shí),自動(dòng)更新length屬性
設(shè)置length為一個(gè)較小值將截?cái)鄶?shù)組
從Array.prototype中繼承了一些方法
其類(lèi)屬性為"Array"
JavaScript 數(shù)組有很多方法特意定義通用,因此他們不僅應(yīng)用在真正的數(shù)組而且在類(lèi)數(shù)組對(duì)象上都能正確工作,JavaScript權(quán)威指南一書(shū)說(shuō)的是:ES5中所有的方法都是通用的,ES3中除了toString()和toLocaleString()意外所有方法也是通用的。
類(lèi)數(shù)組對(duì)象顯然沒(méi)有繼承自Array.prototype,所以它們不能直接調(diào)用數(shù)組方法,不過(guò)可以間接地使用Function.call方法調(diào)用。
// 類(lèi)數(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); } //對(duì)的,這樣也可以的 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ù)組的進(jìn)化——類(lèi)型化數(shù)組的引入
先說(shuō)一下普遍意義上的Array,數(shù)組是一串 連續(xù) 的內(nèi)存位置,用來(lái)保存某些值。JavaScript 中的數(shù)組是哈希映射,可以使用不同的數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn),如鏈表,上一個(gè)元素包含下一個(gè)元素的引用。這樣其他語(yǔ)言中數(shù)組的取值是根據(jù)內(nèi)存位置進(jìn)行數(shù)學(xué)計(jì)算就能找到,而在JavaScript中就需要遍歷鏈表之類(lèi)的結(jié)構(gòu),數(shù)組越長(zhǎng),遍歷鏈表跟數(shù)據(jù)計(jì)算相比就越慢。
現(xiàn)代 JavaScript 引擎是會(huì)給數(shù)組分配連續(xù)內(nèi)存的 —— 如果數(shù)組是同質(zhì)的(所有元素類(lèi)型相同)。所以在寫(xiě)代碼時(shí)保證數(shù)組同質(zhì),以便 JIT(即時(shí)編譯器)能夠使用 c 編譯器式的計(jì)算方法讀取元素是一種優(yōu)雅的方式。
不過(guò),一旦你想要在某個(gè)同質(zhì)數(shù)組中插入一個(gè)其他類(lèi)型的元素,JIT 將解構(gòu)整個(gè)數(shù)組,并按照舊有的方式重新創(chuàng)建。
ES6 增加了 ArrayBuffer, 提供一塊連續(xù)內(nèi)存供我們隨意操作。然而,直接操作內(nèi)存還是太復(fù)雜、偏底層。于是便有了處理 ArrayBuffer 的視圖(View)。
ArrayBuffer 對(duì)象用來(lái)表示通用的、固定長(zhǎng)度的原始二進(jìn)制數(shù)據(jù)緩沖區(qū)。ArrayBuffer 不能直接操作,而是要通過(guò)類(lèi)型數(shù)組對(duì)象或 DataView 對(duì)象來(lái)操作,它們會(huì)將緩沖區(qū)中的數(shù)據(jù)表示為特定的格式,并通過(guò)這些格式來(lái)讀寫(xiě)緩沖區(qū)的內(nèi)容。
語(yǔ)法: new ArrayBuffer(length) 參數(shù) length:要?jiǎng)?chuàng)建的 ArrayBuffer 的大小,單位為字節(jié)。 返回值:一個(gè)指定大小的 ArrayBuffer 對(duì)象,其內(nèi)容被初始化為 0。 異常:如果 length 大于 Number.MAX_SAFE_INTEGER(>= 2 ** 53)或?yàn)樨?fù)數(shù),則拋出一個(gè) RangeError 異常。
類(lèi)型數(shù)組對(duì)象 一個(gè)TypedArray 對(duì)象描述一個(gè)底層的二進(jìn)制數(shù)據(jù)緩存區(qū)的一個(gè)類(lèi)似數(shù)組(array-like)視圖。事實(shí)上,沒(méi)有名為 TypedArray的全局對(duì)象,也沒(méi)有一個(gè)名為的 TypedArray構(gòu)造函數(shù)。相反,有許多不同的全局對(duì)象,下面會(huì)列出這些針對(duì)特定元素類(lèi)型的類(lèi)型化數(shù)組的構(gòu)造函數(shù)。
new TypedArray(); // ES2017中新增 new TypedArray(length); new TypedArray(typedArray); new TypedArray(object); new TypedArray(buffer [, byteOffset [, length]]); TypedArray()指的是以下的其中之一: Int8Array();//8位二進(jìn)制帶符號(hào)整數(shù) -2^7~(2^7) - 1,大小1個(gè)字節(jié) Uint8Array();//8位無(wú)符號(hào)整數(shù) 0~(2^8) - 1,大小1個(gè)字節(jié) Int16Array();//16位二進(jìn)制帶符號(hào)整數(shù) -2^15~(2^15)-1,大小2個(gè)字節(jié) Uint16Array();//16位無(wú)符號(hào)整數(shù) 0~(2^16) - 1,大小2個(gè)字節(jié) Int32Array();// 32位二進(jìn)制帶符號(hào)整數(shù) -2^31~(2^31)-1,大小4個(gè)字節(jié) Uint32Array();//32位無(wú)符號(hào)整數(shù) 0~(2^32) - 1,大小4個(gè)字節(jié) Float32Array();//32位IEEE浮點(diǎn)數(shù),大小4個(gè)字節(jié) Float64Array(); //64位IEEE浮點(diǎn)數(shù),大小8個(gè)字節(jié)
應(yīng)用:
var buffer = new ArrayBuffer(8); var view = new Int32Array(buffer); view[0] = 100; console.log(view)// [100,0],一個(gè)八個(gè)字節(jié),Int32Array一個(gè)元素大小是4個(gè)字節(jié),所以只能放下兩個(gè)元素參考和鏈接
《JavaScript權(quán)威指南》數(shù)組部分
詳解JS遍歷
給初學(xué)者:JavaScript 中數(shù)組操作注意點(diǎn)
一次掌握 JavaScript ES5 到 ES8 數(shù)組內(nèi)容
【干貨】js 數(shù)組詳細(xì)操作方法及解析合集
【譯】深入 JavaScript 數(shù)組:進(jìn)化與性能
彩蛋 彩蛋就是關(guān)注奇舞周刊啊,文章寫(xiě)得好,想讓更多人看到的同學(xué),可以找我投稿啊。文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96660.html
摘要:三國(guó)時(shí)代著名的兵器鑒別家呂虔根據(jù)兵器的特點(diǎn)對(duì)漢武帝欽定的十八般兵器重新排列為九長(zhǎng)九短。明代五雜俎和清代堅(jiān)集兩書(shū)所載十八般兵器為弓弩槍刀劍矛盾斧鉞戟黃锏撾殳棍叉耙頭錦繩套索白打拳術(shù)。后人稱(chēng)其為小十八般。 知識(shí)點(diǎn) 在古典小說(shuō)和傳統(tǒng)評(píng)話(huà)中,常說(shuō)武藝高強(qiáng)的人是十八般武藝樣樣精通...
摘要:清單一些說(shuō)明注意文檔的書(shū)寫(xiě)順序,先寫(xiě)兩側(cè)欄,再寫(xiě)主面板,更換后則側(cè)欄會(huì)被擠到下一列圣杯布局和雙飛翼布局都會(huì)用到。可以通過(guò)設(shè)置的屬性或使用雙飛翼布局避免問(wèn)題。雙飛翼布局不用設(shè)置相對(duì)布局,以及對(duì)應(yīng)的和值。 本文首發(fā)于知乎專(zhuān)欄:前端指南 CSS布局 布局是CSS中一個(gè)重要部分,本文總結(jié)了CSS布局中的常用技巧,包括常用的水平居中、垂直居中方法,以及單列布局、多列布局的多種實(shí)現(xiàn)方式(包括傳統(tǒng)的...
摘要:今天的文章來(lái)自李貝寧,成都研究院的資深程序猿和架構(gòu)師。是研究院內(nèi)部的教練,也是成都研究院若干內(nèi)部培訓(xùn)課程的講師。而李貝寧,在成都研究院三支分別使用和的開(kāi)發(fā)團(tuán)隊(duì)里都被任命為架構(gòu)師,技術(shù)的全面性不輸于史大郎。 今天的文章來(lái)自李貝寧(Ben),SAP成都研究院的資深程序猿和架構(gòu)師。 作為成都研究院里同時(shí)精通Java, JavaScript和ABAP這三門(mén)編程語(yǔ)言的數(shù)位同事之一,Ben曾經(jīng)先后...
摘要:基于接口的自動(dòng)化測(cè)試選型近期投入的一個(gè)項(xiàng)目需要做核心功能的測(cè)試場(chǎng)景自動(dòng)化,以應(yīng)對(duì)部署復(fù)雜和跨系統(tǒng)間的流程驗(yàn)證。雖然個(gè)人來(lái)講更熟悉和趁手,但是在接口自動(dòng)化方面確實(shí)支持的更全面。 ...
摘要:云計(jì)算一詞在從年開(kāi)始在國(guó)內(nèi)興起被譽(yù)為科技領(lǐng)域的第四次技術(shù)革命好像不知道云計(jì)算都不好意思說(shuō)自己從事工作那么云計(jì)算到底是什么意思就是如果想讓計(jì)算能力變強(qiáng),怎么辦加,加內(nèi)存,加硬盤(pán)。云計(jì)算一詞在從07年開(kāi)始在國(guó)內(nèi)興起被譽(yù)為科技領(lǐng)域的第四次技術(shù)革命(好像不知道云計(jì)算都不好意思說(shuō)自己從事IT工作)那么云計(jì)算到底是什么?意思就是如果想讓計(jì)算能力變強(qiáng),怎么辦?加CPU,加內(nèi)存,加硬盤(pán)。老板,我身上的孔已經(jīng)...
閱讀 3581·2023-04-26 02:10
閱讀 1343·2021-11-22 15:25
閱讀 1684·2021-09-22 10:02
閱讀 920·2021-09-06 15:02
閱讀 3480·2019-08-30 15:55
閱讀 613·2019-08-30 13:58
閱讀 2789·2019-08-30 12:53
閱讀 3068·2019-08-29 12:38