擊右上方紅色按鈕關(guān)注“小鄭搞碼事”,每天都能學(xué)到知識(shí),搞懂一個(gè)問題!
如何實(shí)現(xiàn)深拷貝?
就是遞歸調(diào)用淺拷貝方法。
基本類型值的拷貝屬于深拷貝,然而,值的分析的是數(shù)組和對(duì)象的深拷貝實(shí)現(xiàn)問題。兩者的分析思路完全類同,包含代碼實(shí)現(xiàn)和方法利用。所以,今天先來總結(jié)一下數(shù)組的深拷貝問題。主要看看有哪些是你我想到一塊去的地方。
通過逐個(gè)拷貝數(shù)組中的元素來實(shí)現(xiàn)一維數(shù)組的深拷貝。
來看一段代碼:
上面這段代碼,從執(zhí)行結(jié)果來看,實(shí)現(xiàn)了一個(gè)一維數(shù)組的深拷貝,拷貝后的數(shù)組和源數(shù)組完全是獨(dú)立的。
以二維為例子,比一維稍微復(fù)雜點(diǎn),實(shí)現(xiàn)思路就是遞歸一維的代碼,來保證每次拷貝的都是基本類型值。
數(shù)組中的slice和concat方法,對(duì)于數(shù)組元素為基本數(shù)據(jù)類型的情況,可以實(shí)現(xiàn)數(shù)組的深拷貝。相信大家都會(huì)用。
onst numbers=[43,45,56,33,44,1,7];
const numbers2=new Array(22,40,32,76,99);
const fruit=["apple","banana","orange","pear"]
const mixed=[22,"helllo",true,undefined,null,{a:1,b:2},new Date()];
let val;
//獲取長(zhǎng)度
val=numbers.length; //(7) [43, 45, 56, 33, 44, 1, 7]
//檢查是不是數(shù)組
val=Array.isArray(numbers); //true
//獲取數(shù)組單個(gè)元素
val=numbers[3]; //33
//更改某個(gè)元素值
numbers[2]=100; //56變100
//查找元素下標(biāo)位置
val=numbers.indexOf(44); //4
//添加和刪除
numbers.push(250); //從后面加:(8) [43, 45, 100, 33, 44, 1, 7, 250]
numbers.unshift(120); //從前面加:(9) [120, 43, 45, 100, 33, 44, 1, 7, 250]
numbers.pop(); //從后面刪除:(8) [120,43, 45, 100, 33, 44, 1, 7]
numbers.shift(); //從前面刪除:(7) [43, 45, 100, 33, 44, 1, 7]
//刪掉多個(gè)
numbers.splice(1,3);//(4) [43, 44, 1, 7]
//反轉(zhuǎn)
numbers.reverse();//反轉(zhuǎn)(4) [7, 1, 44, 43]
//數(shù)組拼接
val=numbers.concat(numbers2); //(9)[7, 1, 44, 43, 22, 40, 32, 76, 99]
//排序
val=fruit.sort(); //(4) ["apple", "banana", "orange", "pear"]
val=numbers.sort(); //(4) [1, 43, 44, 7]
val=numbers.sort(function(x,y){
return x-y;
}); //(4) [1, 7, 43, 44]
console.log(numbers);
console.log(val);
近面試有道題是至少寫出 15 個(gè)數(shù)組方法,數(shù)組方法平時(shí)經(jīng)常用到的也就6-7個(gè),突然要一下子寫出15個(gè),還是有點(diǎn)卡殼了,今天整理一波,日后好復(fù)習(xí)。
map() 方法創(chuàng)建一個(gè)新數(shù)組,這個(gè)新數(shù)組由原數(shù)組中的每個(gè)元素都調(diào)用一次提供的函數(shù)后的返回值組成。
const list=[, , , ];
list.map((??)=> ); // [, , , ]
const list=[1, 2, 3, 4];
list.map((el)=> el * 2); // [2, 4, 6, 8]
filter() 方法創(chuàng)建一個(gè)新數(shù)組, 其包含通過所提供函數(shù)實(shí)現(xiàn)的測(cè)試的所有元素。
const list=[, , , ];
list.filter((??)=> ??===); // [, ]
// Code
const list=[1, 2, 3, 4];
list.filter((el)=> el % 2===0); // [2, 4]
reduce() 方法對(duì)數(shù)組中的每個(gè)元素按序執(zhí)行一個(gè)由您提供的 reducer 函數(shù),每一次運(yùn)行 reducer 會(huì)將先前元素的計(jì)算結(jié)果作為參數(shù)傳入,最后將其結(jié)果匯總為單個(gè)返回值。
const list=[, , , , ];
list.reduce((??, ??)=> ?? + ??); // + + + +
// OR
const list=[1, 2, 3, 4, 5];
list.reduce((total, item)=> total + item, 0); // 15
reduceRight() 方法的功能和 reduce() 功能是一樣的,不同的是 reduceRight() 從數(shù)組的末尾向前將數(shù)組中的數(shù)組項(xiàng)做累加。
const list=[, , , , ];
list.reduceRight((??, ??)=> ?? + ??); // + + + +
// Code
const list=[1, 2, 3, 4, 5];
list.reduceRight((total, item)=> total + item, 0); // 15
fill() 方法用一個(gè)固定值填充一個(gè)數(shù)組中從起始索引到終止索引內(nèi)的全部元素。不包括終止索引。
const list=[, , , , ];
list.fill(); // [, , , , ]
const list=[1, 2, 3, 4, 5];
list.fill(0); // [0, 0, 0, 0, 0]
find() 方法返回?cái)?shù)組中滿足提供的測(cè)試函數(shù)的第一個(gè)元素的值。否則返回 undefined。
const list=[, , , , ];
list.find((??)=> ??===); //
list.find((??)=> ??===); // undefined
const list=[1, 2, 3, 4, 5];
list.find((el)=> el===3); // 3
list.find((el)=> el===6); // undefined
indexOf() 方法返回在數(shù)組中可以找到一個(gè)給定元素的第一個(gè)索引,如果不存在,則返回-1。
const list=[, , , , ];
list.indexOf(); // 0
list.indexOf(); // -1
// Code
const list=[1, 2, 3, 4, 5];
list.indexOf(3); // 2
list.indexOf(6); // -1
arr.lastIndexOf(searchElement[, fromIndex])
lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或變量)在數(shù)組中的最后一個(gè)的索引,如果不存在則返回 -1。從數(shù)組的后面向前查找,從 fromIndex 處開始。
const list=[, , , , ];
list.lastIndexOf(); // 3
list.lastIndexOf(, 1); // 0
// Code
const list=[1, 2, 3, 4, 5];
list.lastIndexOf(3); // 2
list.lastIndexOf(3, 1); // -1
findIndex() 方法返回?cái)?shù)組中滿足提供的測(cè)試函數(shù)的第一個(gè)元素的索引。若沒有找到對(duì)應(yīng)元素則返回-1。
const list=[, , , , ];
list.findIndex((??)=> ??===); // 0
// You might be thinking how it's different from `indexOf`
const array=[5, 12, 8, 130, 44];
array.findIndex((element)=> element > 13); // 3
// OR
const array=[{
id:
}, {
id:
}, {
id:
}];
array.findIndex((element)=> element.id===); // 2
includes() 方法用來判斷一個(gè)數(shù)組是否包含一個(gè)指定的值,根據(jù)情況,如果包含則返回 true,否則返回 false。
const list=[, , , , ];
list.includes(); // true
// Code
const list=[1, 2, 3, 4, 5];
list.includes(3); // true
list.includes(6); // false
pop() 方法從數(shù)組中刪除最后一個(gè)元素,并返回該元素的值。此方法會(huì)更改數(shù)組的長(zhǎng)度。
const list=[, , , , ];
list.pop(); //
list; // [, , , ]
// Code
const list=[1, 2, 3, 4, 5];
list.pop(); // 5
list; // [1, 2, 3, 4]
push() 方法將一個(gè)或多個(gè)元素添加到數(shù)組的末尾,并返回該數(shù)組的新長(zhǎng)度。
const list=[, , , , ];
list.push(); // 5
list; // [, , , , , ]
// Code
const list=[1, 2, 3, 4, 5];
list.push(6); // 6
list; // [1, 2, 3, 4, 5, 6]
shift() 方法從數(shù)組中刪除第一個(gè)元素,并返回該元素的值。此方法更改數(shù)組的長(zhǎng)度。
const list=[, , , , ]; list.shift(); // list; // [, , , ]
// Code const list=[1, 2, 3, 4, 5]; list.shift(); // 1 list; // [2, 3, 4, 5]
unshift() 方法將一個(gè)或多個(gè)元素添加到數(shù)組的開頭,并返回該數(shù)組的新長(zhǎng)度(該方法修改原有數(shù)組)。
const list=[, , , , ];
list.unshift(); // 6
list; // [, , , , , ]
// Code
const list=[1, 2, 3, 4, 5];
list.unshift(0); // 6
list; // [0, 1, 2, 3, 4, 5]
splice() 方法通過刪除或替換現(xiàn)有元素或者原地添加新的元素來修改數(shù)組,并以數(shù)組形式返回被修改的內(nèi)容。此方法會(huì)改變?cè)瓟?shù)組。
const list=[, , , , ];
list.splice(1, 2); // [, ]
list; // [, , ]
// Code
const list=[1, 2, 3, 4, 5];
list.splice(1, 2); // [2, 3]
list; // [1, 4, 5]
slice() 方法返回一個(gè)新的數(shù)組對(duì)象,這一對(duì)象是一個(gè)由 begin 和 end 決定的原數(shù)組的淺拷貝(包括 begin,不包括end)。原始數(shù)組不會(huì)被改變。
const list=[, , , , ];
list.slice(1, 3); // [, ]
list; // [, , , , ]
// Code
const list=[1, 2, 3, 4, 5];
list.slice(1, 3); // [2, 3]
list; // [1, 2, 3, 4, 5]
join() 方法將一個(gè)數(shù)組(或一個(gè)類數(shù)組對(duì)象)的所有元素連接成一個(gè)字符串并返回這個(gè)字符串。如果數(shù)組只有一個(gè)項(xiàng)目,那么將返回該項(xiàng)目而不使用分隔符。
const list=[, , , , ];
list.join('??'); // "????????"
// Code
const list=[1, 2, 3, 4, 5];
list.join(', '); // "1, 2, 3, 4, 5"
reverse() 方法將數(shù)組中元素的位置顛倒,并返回該數(shù)組。數(shù)組的第一個(gè)元素會(huì)變成最后一個(gè),數(shù)組的最后一個(gè)元素變成第一個(gè)。該方法會(huì)改變?cè)瓟?shù)組。
const list=[, , , , ];
list.reverse(); // [, , , , ]
list; // [, , , , ]
// Code
const list=[1, 2, 3, 4, 5];
list.reverse(); // [5, 4, 3, 2, 1]
list; // [5, 4, 3, 2, 1]
sort() 方法用原地算法對(duì)數(shù)組的元素進(jìn)行排序,并返回?cái)?shù)組。默認(rèn)排序順序是在將元素轉(zhuǎn)換為字符串,然后比較它們的UTF-16代碼單元值序列時(shí)構(gòu)建的。
const list=[, , , , ];
list.sort(); // [, , , , ]
// This make more sense
const array=['D', 'B', 'A', 'C'];
array.sort(); // ['A', 'B', 'C', 'D']
// OR
const array=[4, 1, 3, 2, 10];
array.sort(); // [1, 10, 2, 3, 4]
array.sort((a, b)=> a - b); // [1, 2, 3, 4, 10]
some() 方法測(cè)試數(shù)組中是不是至少有1個(gè)元素通過了被提供的函數(shù)測(cè)試。它返回的是一個(gè)Boolean類型的值。
const list=[, , , , ];
list.some((??)=> ??===); // true
list.some((??)=> ??===); // false
// Code
const list=[1, 2, 3, 4, 5];
list.some((el)=> el===3); // true
list.some((el)=> el===6); // false
every() 方法測(cè)試一個(gè)數(shù)組內(nèi)的所有元素是否都能通過某個(gè)指定函數(shù)的測(cè)試。它返回一個(gè)布爾值。
const list=[, , , , ];
list.every((??)=> ??===); // false
const list=[, , , , ];
list.every((??)=> ??===); // true
// Code
const list=[1, 2, 3, 4, 5];
list.every((el)=> el===3); // false
const list=[2, 4, 6, 8, 10];
list.every((el)=> el%2===0); // true
Array.from() 方法對(duì)一個(gè)類似數(shù)組或可迭代對(duì)象創(chuàng)建一個(gè)新的,淺拷貝的數(shù)組實(shí)例。
const list=;
Array.from(list); // [, , , , ]
const set=new Set(['', '', '', '', '']);
Array.from(set); // [, , ]
const range=(n)=> Array.from({ length: n }, (_, i)=> i + 1);
console.log(range(10)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Array.of() 方法創(chuàng)建一個(gè)具有可變數(shù)量參數(shù)的新數(shù)組實(shí)例,而不考慮參數(shù)的數(shù)量或類型。
Array.of() 和 Array 構(gòu)造函數(shù)之間的區(qū)別在于處理整數(shù)參數(shù):Array.of(7) 創(chuàng)建一個(gè)具有單個(gè)元素 7 的數(shù)組,而 Array(7) 創(chuàng)建一個(gè)長(zhǎng)度為7的空數(shù)組(注意:這是指一個(gè)有7個(gè)空位(empty)的數(shù)組,而不是由7個(gè) undefined 組成的數(shù)組)。
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
Array.isArray() 用于確定傳遞的值是否是一個(gè) Array。
Array.isArray([, , , , ]); // true
Array.isArray(); // false
// Code
Array.isArray([1, 2, 3, 4, 5]); // true
Array.isArray(5); // false
at() 方法接收一個(gè)整數(shù)值并返回該索引的項(xiàng)目,允許正數(shù)和負(fù)數(shù)。負(fù)整數(shù)從數(shù)組中的最后一個(gè)項(xiàng)目開始倒數(shù)。
const list=[, , , , ];
list.at(1); //
// Return from last
list.at(-1); //
list.at(-2); //
// Code
const list=[1, 2, 3, 4, 5];
list.at(1); // 2
list.at(-1); // 5
list.at(-2); // 4
arr.copyWithin(target[, start[, end]])
copyWithin() 方法淺復(fù)制數(shù)組的一部分到同一數(shù)組中的另一個(gè)位置,并返回它,不會(huì)改變?cè)瓟?shù)組的長(zhǎng)度。
const list=[, , , , ];
list.copyWithin(1, 3); // [, , , , ]
const list=[, , , , ];
list.copyWithin(0, 3, 4); // [, , , , ]
// Code
const list=[1, 2, 3, 4, 5];
list.copyWithin(0, 3, 4); // [4, 2, 3, 4, 5]
如果沒看懂,可以看MDN介紹:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin
var newArray=arr.flat([depth])
// depth 可選:指定要提取嵌套數(shù)組的結(jié)構(gòu)深度,默認(rèn)值為 1。
flat() 方法會(huì)按照一個(gè)可指定的深度遞歸遍歷數(shù)組,并將所有元素與遍歷到的子數(shù)組中的元素合并為一個(gè)新數(shù)組返回。
const list=[, , [, , ]];
list.flat(Infinity); // [, , , , ]
// Code
const list=[1, 2, [3, 4, [5, 6]]];
list.flat(Infinity); // [1, 2, 3, 4, 5, 6]
flatMap() 方法首先使用映射函數(shù)映射每個(gè)元素,然后將結(jié)果壓縮成一個(gè)新數(shù)組。它與 map 連著深度值為1的 flat 幾乎相同,但 flatMap 通常在合并成一種方法的效率稍微高一些。
const list=[, , [, , ]];
list.flatMap((??)=> [??, ?? + ?? ]); // [, , , , , , , , , ]
// Code
const list=[1, 2, 3];
list.flatMap((el)=> [el, el * el]); // [1, 1, 2, 4, 3, 9]
作者:Rahul Sharma 譯者:前端小智 來源:dev 原文:https://dev.to/devsmitra/28-javascript-array-hacks-a-cheat-sheet-for-developer-5769
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。