JavaScript面试题总结系列(三)

Kubernetes舵手
• 阅读 1146

3. JavaScript数组

3.1 数组常用方法

  • map: 遍历数组,返回回调函数返回值组成的新数组,不改变原数组
  • forEach:无法break,可以用try/catch中throw new Error来停止
  • filter:过滤
  • some:有一项返回true,则整体为true
  • every:有一项返回false,则整体为false
  • join:通过指定连接符生成字符串
  • push / pop:末尾推入和弹出,改变原数组, 返回推入/弹出项
  • unshift / shift:头部推入和弹出,改变原数组,返回操作项
  • sort(fn) / reverse:排序与反转,改变原数组
  • concat:连接数组,不影响原数组, 浅拷贝
  • slice(start, end):返回截断后的新数组,不改变原数组
  • splice(start, number, value):返回删除元素组成的数组,value为插入项,改变原数组
  • indexOf / lastIndexOf(value, fromIndex):查找数组项,返回对应的下标
  • reduce / reduceRight(fn(prev, cur), defaultPrev):两两执行,prev 为上次化简函数的return值,cur为当前值(从第二项开始)

3.2 判断数组

  • instanceof 方法
    • instanceof 运算符是用来判断一个对象的原型链中是不是能找到类型的 prototype

      var arr = [];
      arr instanceof Array; // true
  • constructor 方法

    constructor属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数

    var arr = [];
    arr.constructor == Array; // true
  • isArray() 方法
    var a = new Array(123);
    var b = new Date();
    console.log(Array.isArray(a)); // true
    console.log(Array.isArray(b)); // false
  • Object.prototype.toString.call()

    这个在之前讲判断数据类型的文章里说过,这里不再赘述。

3.3 数组的遍历

  • map和forEach的区别
    • map具有返回值,返回一个新的数组,不修改原数组;
      forEach没有返回值,直接修改原数组
    • 从性能上来说,forEach的性能要略好于map。
      测试例子请狠狠点击这里
  • JavaScript数组和对象的遍历方式,以及几种方式的比较
    通常我们会用循环的方式来遍历数组。但是循环是 导致js 性能问题的原因之一。一般我们会采用下几种方式来进行数组的遍历
    • for in循环
    • for循环
    • forEach

      • 这里的 forEach回调中两个参数分别为 value,index
      • forEach 无法遍历对象
      • IE不支持该方法;Firefox 和 chrome 支持
      • forEach 无法使用 break,continue 跳出循环,且使用 return 是跳过本次循环
    • 这两种方法应该非常常见且使用很频繁。但实际上,这两种方法都存在性能问题
    • 在方式一中,for-in需要分析出array的每个属性,这个操作性能开销很大。用在 key 已知的数组上是非常不划算的。所以尽量不要用for-in,除非你不清楚要处理哪些属性,例如 JSON对象这样的情况
    • 在方式2中,循环每进行一次,就要检查一下数组长度。读取属性(数组长度)要比读局部变量慢,尤其是当 array 里存放的都是 DOM 元素,因为每次读取都会扫描一遍页面上的选择器相关元素,速度会大大降低
    • ES6新增的 for of 循环。for in循环通常用来遍历对象的Key,for of通常用来遍历对象的Value。

3.4 数组去重

  • 利用双重循环去判断。声明一个空数组,然后遍历原数组,从原数组第一个元素开始往新的数组中放,如果没有该值,则push进去,否则跳过,最后返回新数组。实现数组去重。
  • 使用ES的Set集合。

Set集合的特性之一是其集合中没有重复的元素,因此可以利用这一特性来实现数组去重的目的。举例:

var array2 = [...new Set([1,2,3,3,3,4,5])];
console.log(array2); // Array(5) [ 1, 2, 3, 4, 5 ]

3.5 数组乱序

  • 思路:使用sort()排序,或者使用洗牌算法。
  • 实现:
    • 创建一个数组
    let arr = Array(100000).fill(0).map((item, index) => index + 1);
      1. 直接利用sort进行排序,有漏洞,大部分元素位置没有移动
    arr.sort((a, b) => (Math.random() > 0.5 ? -1 : 1));
    console.log(arr);
      1. 经典洗牌算法实现
    function shuffle(array) { 
        let arrayLength = array.length,   
            randomIndex, //随机数   
            tempItem; //临时存储元素  
        for (let i = arrayLength - 1; i >= 0; i--) {    
            randomIndex = Math.floor(Math.random() * (i + 1));    
            tempItem = array[randomIndex];    
            array[randomIndex] = array[i];    
            array[i] = tempItem;  
        }  
        return array;
    }
    console.log(shuffle(arr));

3.6 数组的扁平化(数组降维/多维转一维)

3.6.1 概念

数组的扁平化是指将一个多为数组变为一维数组。例如:
[1, [2, 3, [4, 5]]] ------> [1, 2, 3, 4, 5]

3.6.2 实现

  • ES10 数组新特性: Array.prototype.flat()方法

    flat()方法按照一个可以指定的嵌套深度的参数来递归遍历数组,并将所有元素以及遍历到的子数组里面的元素合并返回一个新数组。

    var arr = [true, function(){}, [{}, [2]]];
    var newArr = arr.flat(2);
    console.log(newArr); //  [true, ƒ, {…}, 2]
  • 递归。如下:
    function flatten(arr) {
        var res = [];
        arr.map(item => {
            if(Array.isArray(item)) {
                res = res.concat(flatten(item));
            } else {
                res.push(item);
            }
        });
        return res;
    }
  • 扩展运算符
    function flatten(arr) {
        while(arr.some(item=>Array.isArray(item))) {
            arr = [].concat(...arr);
        }
        return arr;
    }
  • reduce

    使用数组的reduce方法,遍历数组中的每一个项,如果某一项是数组,则继续遍历,否则concat(连接数组);
    举例:

    function flatten(arr) {  
        return arr.reduce((result, item)=> {
            return result.concat(Array.isArray(item) ? flatten(item) : item);
        }, []);
    }
    var arr = [false, function(){}, [{}, [2]]];
    var arr2 = [1, [2,3],4,[5,[6,7]]];
    var newArr = flatten(arr); 
    var newArr2 = flatten(arr2);
    console.log(newArr); // [false, ƒ, {…}, 2]
    console.log(newArr2); // [1, 2, 3, 4, 5, 6, 7]

3.6.3 总结

实现数组扁平化的方法有很多,但是最核心的一点就是,遍历数组,拿到数组的每一项,如果是数组,再继续遍历,直到每一项不再是数组则停止。然后将这些项放到一个新的数组,最后将这个数组返回。数组降维,或者多维转一维都和数组扁平化是一个道理。


参考链接:
http://blog.poetries.top/FE-Interview-Questions/review/#_23-%E6%95%B0%E7%BB%84-array
https://www.cnblogs.com/chris-oil/p/8743509.html
https://www.cnblogs.com/owenzh/p/11058708.html https://juejin.im/post/5d391d336fb9a07ebe750343https://juejin.im/post/59716f15f265da6c4c500fc7
https://juejin.im/post/5adc8e396fb9a07aa0479725 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
点赞
收藏
评论区
推荐文章
她左右 她左右
4年前
JavaScript数组常用方法总结
数组基本操作可以归纳为增、删、改、查,需要留意的是哪些方法会对原数组产生影响,哪些方法不会下面对数组常用的操作方法做一个归纳增下面前三种是对原数组产生影响的增添方法,第四种则不会对原数组产生影响push()unshift()splice()concat()push
Karen110 Karen110
4年前
盘点JavaScript中数组遍历的全部方式(下篇)
前言JavaScript想必大家都不陌生了,上篇文章已经给大家介绍了7种数组遍历的方式,这篇文章继续介绍7种数组遍历的方式,这样一共14种遍历方式,基本上囊括了JavaScript中全部的数组遍历方式了。下面的内容,紧接上面文章的内容,一起来学习下吧八、Find通过寻找数组中的对象返回数组中符合目标函数条件的第一个元素。否则返回undefined,如下:九
Karen110 Karen110
4年前
盘点JavaScript中数组遍历的全部方式(上篇)
前言JavaScript想必大家都不陌生了,其中的字符串和数组大家经常都会用到,今天就让我们来说说这里面的数组对象的遍历吧,因为遍历经常使用的缘故,所以小编带着大家来解锁遍历的所有方法,以便大家能够更深入的了解数组遍历,并在实际项目中灵活运用。一、Entries这个是ES6中提供的用于遍历数组的方法,它会返回一个遍历器对象,Entries是对键值对的遍历。
Stella981 Stella981
3年前
JavaScript 常用数组函数方法专题
1、由字符串生成数组split() 分割字符串,并将分割的部分作为一个元素保存在一个新建的数组中。varstr1"thisisanemampletousingthemethodofarray.";varstr2str1.split("");//以空格作为分割条件
Stella981 Stella981
3年前
JavaScript中遍历数组和对象的方法
js数组遍历和对象遍历针对js各种遍历作一个总结分析,从类型用处,分析数组和对象各种遍历使用场景,优缺点等JS数组遍历:1,普通for循环,经常用的数组遍历vararr1,2,0,3,9,10,20,
Stella981 Stella981
3年前
JavaScript回调函数及数组方法测试
JavaScript回调函数及数组方法测试具体代码如下:<!DOCTYPEhtml<htmllang"en"<head<metacharset"GBK"<metahttpequiv"XUACompatible"content"ieedge
Stella981 Stella981
3年前
Javascript数组系列一之栈与队列
所谓数组(英语:Array),是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。---百度百科简单理解,数组就是数据的有序列表。Array在Javascript中属于最常用的数据类型之一了,与其它语言一样Javascript中的数
Stella981 Stella981
3年前
JavaScript——数组(三)数组方法汇总
前面两篇大致介绍了一下数组的基本特性,这里说一下数组的常用方法:Array.join()   将数组中所有的元素都转化为字符串并拼接在一起,返回最后生成的字符串。  不改变原数组可通过指定的分隔符来分隔各个元素,如果不指定分隔符,则默认使用逗号。1vararr1,2,3;//创
3A网络 3A网络
2年前
重写数组的方法(改变原数组)
重写数组的方法(改变原数组)下图是我自我学习模拟数组时总结的一些重新数组的方法:本文我们暂不讨论不改变原数组的方法,只谈改变原数组用到的6种方法。改变原数组的方法push()按参数顺序向数组尾部添加元素,返回新数组的长度javascriptvarcolorreverse()将数组倒叙,改变原数组javascriptArray.prototype.
达里尔 达里尔
1年前
给数组添加新数据,判断数据是否重复
多选要进行数组拼接,希望判断往原数组里添的新数据是否重复,封装个简易方法languageconstdataArrayname:'aaa',id:1,name:'bbb',id:2;constnewDataname:'ccc',id:2;//要添加的新数
小万哥 小万哥
1年前
Kotlin 循环与函数详解:高效编程指南
Kotlin中的循环结构让你能轻松遍历数组或范围内的元素。使用for循环结合in操作符,可以简洁地访问数组中的每个项,如字符串数组或整数数组。对于范围,可以用..来定义一系列连续的值并进行迭代。此外,Kotlin支持通过break和continue控制循环流程。函数则允许封装可复用的代码块,你可以定义接受参数并返回值的函数,利用简写语法使代码更加紧凑。例如,myFunction(x:Int,y:Int)xy简洁地定义了一个计算两数之和的函数。
Kubernetes舵手
Kubernetes舵手
Lv1
已经在原地冲你的背影挥累了手
文章
4
粉丝
0
获赞
0