场景
今天的小马同学可谓是十分自信啊,准备了几个月的面试题知识。信心满满,感觉今天已经拿下了,酒都买好了,回家得好好庆祝一下。面试开始。
面试官 (推了推眼镜,微笑着):你好,我们今天的面试从一个简单的问题开始——数组?
小马 (自信地):数组?当然懂啊,不就是一组数据的集合吗?
面试官 (点点头):那我问你,创建数组有哪些方式?
小马 (不假思索):这还不简单,用数组字面量 [ ] 或者 new Array() 呗。
面试官 (追问):那 new Array(5) 和 [undefined, undefined, undefined, undefined, undefined] 有什么区别?
小马 (愣了一下):嗯...应该没区别吧?都是5个元素的数组。
面试官 (摇摇头):不,区别大了。 new Array(5) 创建的是一个长度为5的数组,但里面的元素是 empty ,这些位置的key没有被释放,所以 for key in 不能迭代它们。而后者是真正有5个 undefined 元素的数组。
小马(恍然大悟):哦,原来是这样!那如果我想初始化一个长度为5,每个元素都是 undefined 的数组,应该怎么做?
面试官 (微笑):可以用 new Array(5).fill(undefined) 。
小马 (记下来):好的,我记住了。
面试官 (继续提问):那你知道数组的静态方法吗?比如 Array.of() 和 Array.from() ?
小马 (思考了一下): Array.of() 好像是用来创建数组的,而 Array.from() 是用来把类数组对象转换成数组的吧?
面试官 (点头):没错。那你能举个例子吗?
小马 (想了想):比如 Array.of(1, 2, 3) 就创建了一个包含1、2、3的数组。而 Array.from([1, 2, 3], x => x * 2) 就会创建一个包含2、4、6的数组。
面试官 (满意):不错。那遍历数组有哪些方式?
小马 (自信地):有很多啊,比如 for 循环、 forEach 、 for...of 等等。
面试官 (追问):那它们各有什么优缺点?
小马 (组织了一下语言):
- for 循环性能好,但可读性差;
- forEach 可读性好,但不能中途退出;
- for...of 最现代,可读性最好,还能使用 break 和 continue 。
面试官 (点头):说得不错。那你知道arr.entries()吗?
小马 (挠了挠头,用手抵在下巴下):不太清楚。
面试官 (鼓励):arr.entries()是用来同时获取索引和值的,你可以这样用:
for (const [index, value] of arr.entries()) {
console.log(`索引${index}的值是${value}`);
}
小马 (惊喜):这个方法挺实用的,我以前没怎么用过。
面试官 (继续提问):那你知道reduce方法吗?它是做什么用的?
小马 (额头开始冒汗):额。。。是响应式状态管理吗?
面试官 (笑了笑):不太一样, reduce 是用来把数组.reduce成一个单一值的。比如计算数组的总和:
const sum = [1, 2, 3, 4, 5,
6].reduce((prev, curr) => {
return prev + curr;
}, 0);
小马 (尴尬地笑笑) : 原来是这样啊。以前没怎么用过。
面试官 (微笑):那你知道数组还有什么特殊的特性吗?
小马 (想了想):数组其实既是列表,又是对象,对吧?它可以有自己的属性。
面试官 (追问):那如果我给数组添加一个超出范围的属性,比如 arr[100] = 100 ,数组的 length 会变成101吗?
小马 (犹豫了一下):应该会吧?
面试官 (摇摇头):不,不会。数组的 length 只跟最大的数字索引有关。如果你的数组原来的 length 是4,那么即使你设置了 arr[100] = 100 , length 也只会变成101吗?不,其实不会。数组的 length 是等于最大的数字索引加1。比如,如果你有一个数组 arr = [1, 2, 3] ,它的 length 是3。如果你设置了 arr[100] = 100 ,那么 length 会变成101。
小马 (有点懵):啊?那我之前的理解错了?
面试官 (笑了笑):其实也不能说完全错。数组的 length 确实是等于最大的数字索引加1。但要注意,这里的索引必须是有效的数字索引。比如,如果你设置了 arr['name'] = 'array' ,这不会影响 length ,因为 'name' 不是数字索引。
小马 (松了口气):哦,原来是这样!我之前还以为数组的 length 是固定的呢。
面试官 (总结):其实数组是JavaScript中最灵活、最强大的数据结构之一。它不仅可以存储数据,还可以进行各种操作,比如遍历、映射、过滤、归约等等。要想真正掌握数组,不仅要知道它的基本用法,还要了解它的内部工作原理和各种高级特性。
小马 (诚恳地):谢谢面试官的指导!我回去之后一定会更加深入地学习数组的知识。
面试官 (微笑):好的,我们今天的面试就到这里。回去等通知吧。
之后小马回家喝完了啤酒,连夜总结了一下JavaScript数组的知识点。
数组知识点
-
数组的创建方式 :
- 数组字面量: const arr = [1, 2, 3];
- new Array() : const arr2 = new Array(5);
- 注意 new Array(5) 创建的是 empty*5 的数组,而不是5个 undefined 的数组。
-
数组的静态方法 :
- Array.of() :创建一个包含指定元素的数组。
- Array.from() :把类数组对象转换成数组,还可以进行映射。
-
数组的遍历方式 :
- for 循环:性能好,但可读性差。
- forEach :可读性好,但不能中途退出。
- for...of :最现代,可读性最好,还能使用 break 和 continue 。
- arr.entries() :同时获取索引和值。
-
数组的 reduce 方法 :
- 用来把数组.reduce(减少)成一个单一值。
- 可以用来计算总和、平均值、最大值、最小值等等。
-
数组的特性 :
- 既是列表,又是对象,可以有自己的属性。
- 数组的 length 等于最大的数字索引加1。
- 非数字索引不会影响 length 。