有关数组的总结

 数组

 如何判断一个变量是否为数组?

 为什么不用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实质是一个引用,用instanceof方法(包括下面的constructor方法)都是利用和引用地址进行比较的方法来确定的,但是在frame嵌套的情况下,每一个Array的引用地址都是不同的,比较起来结果也是不确定的,所以这种方法有其局限性。

 为什么不用constructor方法?

var list = [1,2,3];list.constructor === Array; //true

原因已经解释过了,不再赘述。

 可靠的检测数组方式

 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

 数组的原生方法有哪些?

会改变自身的方法

Array.prototype.copyWithin() 在数组内部,将一段元素序列拷贝到另一段元素序列上,覆盖原有的值。

Array.prototype.fill() 将数组中指定区间的所有元素的值,都替换成某个固定的值。

Array.prototype.pop()删除数组的最后一个元素,并返回这个元素。

Array.prototype.push()在数组的末尾增加一个或多个元素,并返回数组的新长度。

Array.prototype.reverse()颠倒数组中元素的排列顺序,即原先的第一个变为最后一个,原先的最后一个变为第一个。

Array.prototype.shift()删除数组的第一个元素,并返回这个元素。

Array.prototype.sort()对数组元素进行排序,并返回当前数组。

Array.prototype.splice()在任意的位置给数组添加或删除任意个元素。

Array.prototype.unshift()在数组的开头增加一个或多个元素,并返回数组的新长度。

 不会改变自身的方法

Array.prototype.concat()返回一个由当前数组和其它若干个数组或者若干个非数组值组合而成的新数组。

Array.prototype.includes() 判断当前数组是否包含某指定的值,如果是返回 true,否则返回 false。

Array.prototype.join()连接所有数组元素组成一个字符串。

Array.prototype.slice()抽取当前数组中的一段元素组合成一个新数组。

Array.prototype.toSource() 返回一个表示当前数组字面量的字符串。遮蔽了原型链上的 Object.prototype.toSource() 方法。

Array.prototype.toString()返回一个由所有数组元素组合而成的字符串。遮蔽了原型链上的 Object.prototype.toString() 方法。

Array.prototype.toLocaleString()返回一个由所有数组元素组合而成的本地化后的字符串。遮蔽了原型链上的 Object.prototype.toLocaleString() 方法。

Array.prototype.indexOf()返回数组中第一个与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。

Array.prototype.lastIndexOf()返回数组中最后一个(从右边数第一个)与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。

 遍历方法

Array.prototype.forEach()为数组中的每个元素执行一次回调函数。

Array.prototype.entries() 返回一个数组迭代器对象,该迭代器会包含所有数组元素的键值对。

Array.prototype.every()如果数组中的每个元素都满足测试函数,则返回 true,否则返回 false。

Array.prototype.some()如果数组中至少有一个元素满足测试函数,则返回 true,否则返回 false。

Array.prototype.filter()将所有在过滤函数中返回 true 的数组元素放进一个新数组中并返回。

Array.prototype.find() 找到第一个满足测试函数的元素并返回那个元素的值,如果找不到,则返回 undefined。

Array.prototype.findIndex() 找到第一个满足测试函数的元素并返回那个元素的索引,如果找不到,则返回 -1。

Array.prototype.keys() 返回一个数组迭代器对象,该迭代器会包含所有数组元素的键。

Array.prototype.map()返回一个由回调函数的返回值组成的新数组。

Array.prototype.reduce()从左到右为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。

Array.prototype.reduceRight()从右到左为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。

Array.prototype.values() 返回一个数组迭代器对象,该迭代器会包含所有数组元素的值。

Array.prototype[@@iterator]() 和上面的 values() 方法是同一个函数。

 如何将类数组的变量转化为数组?

是如果是ES6,可以用Array.from()方法。

如果不确定环境的话,可以用Array.prototype.slice.call()的方法,将类似数组转换为。

Array.from()的详解:

Set类型的转换

let s = new Set(['foo', window]);

Array.from(s);

// ["foo", window]

Map类型的转换

let m = new Map([[1, 2], [2, 4], [4, 8]]);Array.from(m);

// [[1, 2], [2, 4], [4, 8]]

类数组的值

function f() {

return Array.from(arguments);}

f(1, 2, 3);

// [1, 2, 3]

Array.from()的第二个参数mapFn也很有用处,可以对于传入的类数组值进行定制化修改

// 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对于数组的扩展

增加了扩展运算符(spread)...

它将一个数组转化为以逗号分隔的一个参数序列。

var list = [1,2,3];console.log(...list); //1 2 3

增加了两个方法,Array.from()和Array.of()方法。

增加了一些实例方法,如copyWithin()、entries()、keys()、values()等。

数组去重,多少种方法?

 1.利用一个空Object来实现

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数据结构

console.log([...new Set(list)]); //[0,1,2,3,6]

 你知道Array.prototype的类型是什么吗?

很多人都不知道,其实Array.prototype是一个数组,只不过length为0

如何“打平”一个嵌套数组,如[1,[2,[3]],4,[5]] => [1,2,3,4,5]?

这个方法很多,如果你的答案是用递归的话,那确实有点low,而且代码会比较复杂。

我的觉得可以用以下方法来解决这个问题:

 1.利用Array.prototype.toString()方法

var list = [1,[2,[3]],4,[5]];console.log(list.toString()); //1,2,3,4,5

原理:toString 方法返回一个字符串,该字符串由数组中的每个元素的 toString() 返回值经调用 join() 方法连接(由逗号隔开)组成。

 2.利用Array.prototype.join()方法

var list = [1,[2,[3]],4,[5]];console.log(list.join()); //1,2,3,4,5

原理:join方法会让所有的数组元素转换成字符串,再用一个分隔符将这些字符串连接起来。如果元素是undefined 或者null, 则会转化成空字符串。

PS:如果你觉得上面输出的不是一个数组,可以稍微加工一下

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]

如何克隆一个数组?

 1.借用concat方法

var arr1 = [1,2,3];var arr2 = arr1.concat();

2.借用slice方法

var arr1 = [1,2,3];var arr2 = arr1.slice(0);

原理:数组本质上也是Object,直接赋值的话,只是将引用赋值给另一个变量,最终会导致被复制的变量也会随着原来的数组变化而变化。

说一说Array.prototype.sort()方法的原理?(追问:不传递参数会如何?)

语法

sort方法接受一个“比较函数”作为参数。

如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。

如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:

若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。

若 a 等于 b,则返回 0。

若 a 大于 b,则返回一个大于 0 的值。

 找出Array中的最大元素,你能说出几种方法?

1.自己实现一个冒泡算法

 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]

总结

数组是平时开发中经常用到的,所以经常被面试官问到也是正常的。希望每一个开发者都能够在平时用的时候不仅是机械的应用Array的原生方法,也应该勤思考、多想为什么,这也是面试官希望见到的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容