?數(shù)組
?如何判斷一個變量是否為數(shù)組记罚?
?為什么不用typeof减余?
var list = [1,2,3];typeof list //"object"
Array繼承與Object,所以typeof 會直接返回object,所以不可以用typeof方法來檢測
為什么不用instanceof?
var list = [1,2,3];list instanceof Array //true
instanceof 表面上看確實是返回了true筷畦,但其實并不可靠。原因是Array實質(zhì)是一個引用症杏,用instanceof方法(包括下面的constructor方法)都是利用和引用地址進(jìn)行比較的方法來確定的,但是在frame嵌套的情況下瑞信,每一個Array的引用地址都是不同的厉颤,比較起來結(jié)果也是不確定的,所以這種方法有其局限性凡简。
?為什么不用constructor方法逼友?
var list = [1,2,3];list.constructor === Array; //true
原因已經(jīng)解釋過了,不再贅述秤涩。
?可靠的檢測數(shù)組方式
?1.利用Object的toString方法
var list = [1,2,3];Object.prototype.toString.call(list); //[object Array]
?2.利用ES6的Array.isArray()方法
var list = [1,2,3];Array.isArray(list); //true
?數(shù)組的原生方法有哪些帜乞?
會改變自身的方法
Array.prototype.copyWithin() 在數(shù)組內(nèi)部,將一段元素序列拷貝到另一段元素序列上筐眷,覆蓋原有的值黎烈。
Array.prototype.fill() 將數(shù)組中指定區(qū)間的所有元素的值,都替換成某個固定的值匀谣。
Array.prototype.pop()刪除數(shù)組的最后一個元素照棋,并返回這個元素。
Array.prototype.push()在數(shù)組的末尾增加一個或多個元素武翎,并返回數(shù)組的新長度烈炭。
Array.prototype.reverse()顛倒數(shù)組中元素的排列順序,即原先的第一個變?yōu)樽詈笠粋€宝恶,原先的最后一個變?yōu)榈谝粋€梳庆。
Array.prototype.shift()刪除數(shù)組的第一個元素,并返回這個元素卑惜。
Array.prototype.sort()對數(shù)組元素進(jìn)行排序膏执,并返回當(dāng)前數(shù)組。
Array.prototype.splice()在任意的位置給數(shù)組添加或刪除任意個元素露久。
Array.prototype.unshift()在數(shù)組的開頭增加一個或多個元素更米,并返回數(shù)組的新長度。
?不會改變自身的方法
Array.prototype.concat()返回一個由當(dāng)前數(shù)組和其它若干個數(shù)組或者若干個非數(shù)組值組合而成的新數(shù)組毫痕。
Array.prototype.includes() 判斷當(dāng)前數(shù)組是否包含某指定的值征峦,如果是返回 true,否則返回 false消请。
Array.prototype.join()連接所有數(shù)組元素組成一個字符串栏笆。
Array.prototype.slice()抽取當(dāng)前數(shù)組中的一段元素組合成一個新數(shù)組。
Array.prototype.toSource() 返回一個表示當(dāng)前數(shù)組字面量的字符串臊泰。遮蔽了原型鏈上的 Object.prototype.toSource() 方法蛉加。
Array.prototype.toString()返回一個由所有數(shù)組元素組合而成的字符串。遮蔽了原型鏈上的 Object.prototype.toString() 方法。
Array.prototype.toLocaleString()返回一個由所有數(shù)組元素組合而成的本地化后的字符串针饥。遮蔽了原型鏈上的 Object.prototype.toLocaleString() 方法厂抽。
Array.prototype.indexOf()返回數(shù)組中第一個與指定值相等的元素的索引,如果找不到這樣的元素丁眼,則返回 -1筷凤。
Array.prototype.lastIndexOf()返回數(shù)組中最后一個(從右邊數(shù)第一個)與指定值相等的元素的索引,如果找不到這樣的元素苞七,則返回 -1藐守。
?遍歷方法
Array.prototype.forEach()為數(shù)組中的每個元素執(zhí)行一次回調(diào)函數(shù)。
Array.prototype.entries() 返回一個數(shù)組迭代器對象蹂风,該迭代器會包含所有數(shù)組元素的鍵值對卢厂。
Array.prototype.every()如果數(shù)組中的每個元素都滿足測試函數(shù),則返回 true硫眨,否則返回 false。
Array.prototype.some()如果數(shù)組中至少有一個元素滿足測試函數(shù)巢块,則返回 true礁阁,否則返回 false。
Array.prototype.filter()將所有在過濾函數(shù)中返回 true 的數(shù)組元素放進(jìn)一個新數(shù)組中并返回族奢。
Array.prototype.find() 找到第一個滿足測試函數(shù)的元素并返回那個元素的值姥闭,如果找不到,則返回 undefined越走。
Array.prototype.findIndex() 找到第一個滿足測試函數(shù)的元素并返回那個元素的索引棚品,如果找不到,則返回 -1廊敌。
Array.prototype.keys() 返回一個數(shù)組迭代器對象铜跑,該迭代器會包含所有數(shù)組元素的鍵。
Array.prototype.map()返回一個由回調(diào)函數(shù)的返回值組成的新數(shù)組骡澈。
Array.prototype.reduce()從左到右為每個數(shù)組元素執(zhí)行一次回調(diào)函數(shù)锅纺,并把上次回調(diào)函數(shù)的返回值放在一個暫存器中傳給下次回調(diào)函數(shù),并返回最后一次回調(diào)函數(shù)的返回值肋殴。
Array.prototype.reduceRight()從右到左為每個數(shù)組元素執(zhí)行一次回調(diào)函數(shù)囤锉,并把上次回調(diào)函數(shù)的返回值放在一個暫存器中傳給下次回調(diào)函數(shù),并返回最后一次回調(diào)函數(shù)的返回值护锤。
Array.prototype.values() 返回一個數(shù)組迭代器對象官地,該迭代器會包含所有數(shù)組元素的值。
Array.prototype[@@iterator]() 和上面的 values() 方法是同一個函數(shù)烙懦。
?如何將類數(shù)組的變量轉(zhuǎn)化為數(shù)組驱入?
是如果是ES6,可以用Array.from()方法。
如果不確定環(huán)境的話沧侥,可以用Array.prototype.slice.call()的方法可霎,將類似數(shù)組轉(zhuǎn)換為。
Array.from()的詳解:
Set類型的轉(zhuǎn)換
let s = new Set(['foo', window]);
Array.from(s);
// ["foo", window]
Map類型的轉(zhuǎn)換
let m = new Map([[1, 2], [2, 4], [4, 8]]);Array.from(m);
// [[1, 2], [2, 4], [4, 8]]
類數(shù)組的值
function f() {
return Array.from(arguments);}
f(1, 2, 3);
// [1, 2, 3]
Array.from()的第二個參數(shù)mapFn也很有用處宴杀,可以對于傳入的類數(shù)組值進(jìn)行定制化修改
// Using an arrow function as the map function to// manipulate the elementsArray.from([1, 2, 3], x => x + x);
// [2, 4, 6]
// Generate a sequence of numbers// Since the array is initialized with `undefined` on each position,// the value of `v` below will be `undefined`Array.from({length: 5}, (v, i) => i);// [0, 1, 2, 3, 4]
ES6對于數(shù)組的擴(kuò)展
增加了擴(kuò)展運(yùn)算符(spread)...
它將一個數(shù)組轉(zhuǎn)化為以逗號分隔的一個參數(shù)序列癣朗。
var list = [1,2,3];console.log(...list); //1 2 3
增加了兩個方法,Array.from()和Array.of()方法旺罢。
增加了一些實例方法旷余,如copyWithin()、entries()扁达、keys()正卧、values()等。
數(shù)組去重跪解,多少種方法炉旷?
?1.利用一個空Object來實現(xiàn)
Array.prototype.unique = function(){
var tmp = {},res=[];
this.forEach(function(i){
!tmp[i] && res.push(i) && (tmp[i] = true);
})
return res;}var list = [0,0,1,2,3,6,6];console.log(list.unique()); //[0,1,2,3,6]
?2.利用ES6 的Set數(shù)據(jù)結(jié)構(gòu)
console.log([...new Set(list)]); //[0,1,2,3,6]
?你知道Array.prototype的類型是什么嗎?
很多人都不知道叉讥,其實Array.prototype是一個數(shù)組窘行,只不過length為0
如何“打平”一個嵌套數(shù)組,如[1,[2,[3]],4,[5]] => [1,2,3,4,5]?
這個方法很多图仓,如果你的答案是用遞歸的話罐盔,那確實有點low,而且代碼會比較復(fù)雜救崔。
我的覺得可以用以下方法來解決這個問題:
?1.利用Array.prototype.toString()方法
var list = [1,[2,[3]],4,[5]];console.log(list.toString()); //1,2,3,4,5
原理:toString 方法返回一個字符串惶看,該字符串由數(shù)組中的每個元素的 toString() 返回值經(jīng)調(diào)用 join() 方法連接(由逗號隔開)組成。
?2.利用Array.prototype.join()方法
var list = [1,[2,[3]],4,[5]];console.log(list.join()); //1,2,3,4,5
原理:join方法會讓所有的數(shù)組元素轉(zhuǎn)換成字符串六孵,再用一個分隔符將這些字符串連接起來纬黎。如果元素是undefined 或者null, 則會轉(zhuǎn)化成空字符串劫窒。
PS:如果你覺得上面輸出的不是一個數(shù)組莹桅,可以稍微加工一下
var list = [1,2,3,4,5];JSON.parse(`[${list.toString()}]`); //[1,2,3,4,5]JSON.parse(`[${list.join()}]`); //[1,2,3,4,5]
如何克隆一個數(shù)組?
?1.借用concat方法
var arr1 = [1,2,3];var arr2 = arr1.concat();
2.借用slice方法
var arr1 = [1,2,3];var arr2 = arr1.slice(0);
原理:數(shù)組本質(zhì)上也是Object烛亦,直接賦值的話诈泼,只是將引用賦值給另一個變量,最終會導(dǎo)致被復(fù)制的變量也會隨著原來的數(shù)組變化而變化煤禽。
說一說Array.prototype.sort()方法的原理铐达?(追問:不傳遞參數(shù)會如何?)
語法
sort方法接受一個“比較函數(shù)”作為參數(shù)檬果。
如果調(diào)用該方法時沒有使用參數(shù)瓮孙,將按字母順序?qū)?shù)組中的元素進(jìn)行排序唐断,說得更精確點,是按照字符編碼的順序進(jìn)行排序杭抠。要實現(xiàn)這一點脸甘,首先應(yīng)把數(shù)組的元素都轉(zhuǎn)換成字符串(如有必要),以便進(jìn)行比較偏灿。
如果想按照其他標(biāo)準(zhǔn)進(jìn)行排序丹诀,就需要提供比較函數(shù),該函數(shù)要比較兩個值翁垂,然后返回一個用于說明這兩個值的相對順序的數(shù)字铆遭。比較函數(shù)應(yīng)該具有兩個參數(shù) a 和 b,其返回值如下:
若 a 小于 b沿猜,在排序后的數(shù)組中 a 應(yīng)該出現(xiàn)在 b 之前枚荣,則返回一個小于 0 的值。
若 a 等于 b啼肩,則返回 0橄妆。
若 a 大于 b,則返回一個大于 0 的值祈坠。
?找出Array中的最大元素害碾,你能說出幾種方法?
1.自己實現(xiàn)一個冒泡算法
?2.利用Math的max方法
var list = [1,100,23,65,43,2,9];Math.max.apply(null, list); //[1, 2, 9, 23, 43, 65, 100]
?3.利用Array的sort方法先排序再取值
var list = [1,100,23,65,43,2,9];list.sort((a, b) => {return a-b;}) //[1, 2, 9, 23, 43, 65, 100]
總結(jié)
數(shù)組是平時開發(fā)中經(jīng)常用到的颁虐,所以經(jīng)常被面試官問到也是正常的蛮原。希望每一個開發(fā)者都能夠在平時用的時候不僅是機(jī)械的應(yīng)用Array的原生方法卧须,也應(yīng)該勤思考另绩、多想為什么,這也是面試官希望見到的花嘶。