面试看这里!!!2020年前端面试知识点(持续更新)

this指向:

a.如果是一般函数,this指向全局对象window;

b.在严格模式下"use strict",为undefined.

c.对象的方法里调用,this指向调用该方法的对象.

d.构造函数里的this,指向创建出来的实例.

改变this指向:(call,apply,bind)

call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:

call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,‘成都’, … ,‘string’ )。

apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,[‘成都’, …, ‘string’ ])。

bind 除了返回是函数以外,它 的参数和 call 一样。区别在于bind方法返回值是函数以及bind接收的参数列表的使用。

当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!


Cookie

Cookie的特性:会话数据保存在浏览器客户端

单个 cookies 保存的数据不能超过 4 K,很多浏览器限制一个站点保存最多 20 个 cookies

Cookie的底层实现原理:

 1)服务器创建cookie对象,把会话数据存储到cookie对象中。

      new Cookie("name","value");

 2)服务器发送cookie信息到浏览器

      response.addCookie(cookie);

 3)浏览器从响应头中得到服务器发送的Cookie然后保存到浏览器本地。

Session

Session的特性:会话数据保存在服务器端

Session底层实现原理:服务器创建一个session之后,会在响应头里面将sessionId返回给浏览器。浏览器从响应头中获取sessionId,然后保存在浏览器本地。与浏览器窗口打开有关,关闭就没了(换窗口也会消失)

sessionStorage与存储数据的顶级窗口或浏览器选项卡具有相同的生命周期。当选项卡永久关闭时,将删除通过sessionStorage存储的所有数据。

Locastrage:通过localStorage存储的数据是永久性的:它不会过期并保留在用户的计算机上,直到Web应用程序删除它或用户要求浏览器删除它。

localstorage和sessionstorage都是H5提供的新的存储类型,以前只有cookies来完成存储的工作。

这两种新方式存储限制比使用cookie要大得多(至少5MB),而且速度更快。
数据永远不会传输到服务器,只有在客户端特别要求时才能使用。


1:对象转换数组  

let obj = {'val1':1, 'val2':2, 'val3':3, 'val4':4};

  var arr = []

  for (let i in obj) {  //取键

    let o = {};

    o[i] = obj[i];  //寻找键值对赋值

    arr.push(o)

  }

  console.log(arr);  //[ { val1: 1 }, { val2: 2 }, { val3: 3 }, { val4: 4 } ]

2:数组转字符串  

let a = [123,432,42,5,344,5]

  1) toString()

    console.log(a.toString())  //123,432,42,5,344,5

  2)  join('')

    console.log(a.join('-'))  //123-432-42-5-344-5

3:字符串转数组 

 let str = 'daw2312-daw=+'

  console.log(str.split(''))  //[ 'd', 'w', '2', '2', '-', 'a', 'w', '=' ]

4:通过 JSON.stringify() 把 JavaScript 对象转换为字符串。 


 JavaScript window.onload 事件和 jQuery ready 函数有何不同?

JavaScript window.onload 事件和 jQuery ready 函数之间的主要区别是,前者除了要等待 DOM 被创建还要等到包括大型图片、音频、视频在内的所有外部资源都完全加载。如果加载图片和媒体内容花费了大量时间,用户就会感受到定义在 window.onload 事件上的代码在执行时有明显的延迟。

另一方面,jQuery ready() 函数只需对 DOM 树的等待,而无需对图像或外部资源加载的等待,从而执行起来更快。使用 jQuery $(document).ready() 的另一个优势是你可以在网页里多次使用它,浏览器会按它们在 HTML 页面里出现的顺序执行它们,相反对于 onload 技术而言,只能在单一函数里使用。鉴于这个好处,用 jQuery ready() 函数比用 JavaScript window.onload 事件要更好些。


什么是节流和防抖?
节流(throttle):节流可以控制事件触发的频率,节流就跟小水管一样,如果不加节流的话,水就会哗啦啦啦啦啦啦的流出来,但是一旦加了节流阀,你就可以自己控制水的流速了,加了节流后水可以从哗啦啦啦变成滴答滴答滴答,放到我们的函数事件里面说就是可以让事件触发变慢,比如说事件触发可以让它在每一秒内只触发一次;

防抖(debounce):防抖就是可以限制事件在一定时间内不能多次触发,比如说你疯狂按点击按钮,一顿操作猛如虎,不加防抖的话它也会跟着你疯起来,疯狂执行触发的方法。但是一旦加了防抖,无论你点击多少次,他都只会在你最后一次点击的时候才执行;

防抖:

    理解:在车站上车,人员上满了车才发走重点是人员上满触发一次。

    场景:实时搜索,拖拽。

    实现:

        //每一次都要清空定时器,重新设置上计时器值,使得计时器每一次都重新开始,直到最后满足条件并且等待delay时间后,才开始执行handler函数。

function debunce(handler,delay){ 
   //handler是要传入的进行防抖的函数,delay是等待时间。
    var timer = null;
    return function(){
        var _self = this,args = arguments; 
        clearTimeout(timer);        //每次都要清除这个定时器 
        timer = setTimeout(function(){    //重新开启定时器 
            handler.apply(_self,args); 
        },delay); 
    } 
}


节流:

    理解:大于等于10分钟发一次车,重点是一定间隔时间就会触发一次。

            (即预定一个函数只有在大于等于执行周期时才会执行,周期内不执行)。

    场景:窗口调整(调整大小),页面滚动(滚动),抢购时疯狂点击(鼠标按下)

    实现:

        //处理程序是要传入的进行节流的函数,wait是上述的间隔时间。

        //使用时间戳进行时间的计算。

      

  function throttle(handler,wait){  //handler是要进行节流的函数,wait是等待时间
            var lastTime = 0;
            return function(){
                var nowTime = new Date().getTime();    //获取当前时间
                if(nowTime - lastTime> wait){
                    handler.apply(this,arguments);
                    lastTime = nowTime;      //更新最后时间
                }
            }
        }

AJAX

1、是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

2、通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

3、传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

Fetch

fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。

Axios

-axios主要是jQuery的ajax与fetch的融合,十分强大

特点

  1. 支持浏览器和node.js
  2. 支持promise(重点)
  3. 能拦截请求和响应
  4. 能转换请求和响应数据
  5. 能取消请求
  6. 自动转换JSON数据
  7. 浏览器端支持防止CSRF(跨站请求伪造)

Js闭包

闭包指的是:能读取其他函数内部变量的函数。(函数嵌套函数,内访外)

清晰的讲:闭包就是一个函数,这个函数能够访问其他函数的作用域中的变量。

优点:

  1. 避免全局变量的污染
  2. 希望一个变量长期存储在内存中(缓存变量)

闭包带来的问题:

1 、闭包使得函数被保存在内存中,内存消耗很大,所以不能滥用

2 、函数本身是对象,内部变量相当于它的私有属性,所以这是不安全的


从输入一个url到浏览器页面展示都经历了哪些过程

1、首先,在浏览器地址栏中输入url

2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。

3、在发送http请求前,需要域名解析(DNS解析),解析获取相应的IP地址。

4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手

5、握手成功后,浏览器向服务器发送http请求请求数据包

6、服务器处理收到的请求,将数据返回至浏览器

7、浏览器收到HTTP响应

8、读取页面内容,浏览器渲染,解析html源码

9、生成Dom树、解析css样式、js交互

10、客户端和服务器交互

11、ajax查询

其中,步骤2的具体过程是:

浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统,获取操作系统的记录(保存最近的DNS查询缓存);
路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
ISP缓存:若上述均失败,继续向ISP搜索。


.基本的数据类型:String, Number, boolean, Null, Undefined,Symbol(ES6新增)  

  特点: 存储的是该对象的实际数据,(存放在栈中)

.对象数据类型(也称为引用数据类型):Array,Object,Function

  特点: 存储的是该对象在栈中引用,真实的数据存放在堆内存里,(存放在堆内存中的对象,每个空间大小不一样,要根据情况进行特定的配置)

注:在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象

深拷贝和浅拷贝的区别

1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用

2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

例:

假设B复制了A,修改A的时候,看B是否发生变化:

如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)

如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)


new操作符在创建实例的时候经历了哪几个阶段

new创建了一个对象,共经历了4个阶段:
1、 创建一个空对象
2、 设置原型链
3、让实例化对象中的this指向对象,并执行函数体
4、 判断实例化对象的返回值类型


常见算法时间复杂度:

O(1): 表示算法的运行时间为常量

O(n): 表示该算法是线性算法

O(㏒2n): 二分查找算法

O(n2): 对数组进行排序的各种简单算法,例如直接插入排序的算法。

O(n3): 做两个n阶矩阵的乘法运算

O(2n): 求具有n个元素集合的所有子集的算法

O(n!): 求具有N个元素的全排列的算法

优<---------------------------<劣

O(1)<O(㏒2n)<O(n)<O(n2)<O(2n)

时间复杂度按数量级递增排列依次为:常数阶O(1)、对数阶O(log2n)、线性阶O(n)、线性对数阶O(nlog2n)、平方阶O(n2)、立方阶O(n3)、……k次方阶O(nk)、指数阶O(2n)。 


跨域

https://blog.csdn.net/Sestid/article/details/103913229


HTTP

工作原理:HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

客户端请求消息:

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。

服务器响应消息:

HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

HTTP 请求方法:

 HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。

HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。 

HTTPS

是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。

HTTPS 提供了加密 (Encryption)、认证 (Verification)、鉴定 (Identification) 三种功能。如下的解释中,假设是张三和李四在通讯。

  • 私密性(Confidentiality/Privacy):
    也就是提供信息加密,保证数据传输的安全;保证信息只有张三和李四知道,而不会被窃听。
  • 可信性(Authentication):
    身份验证,主要是服务器端的,确认网站的真实性,有些银行也会对客户端进行认证;用来证明李四就是李四。
  • 完整性(Message Integrity):
    保证信息传输过程中的完整性,防止被修改;李四接收到的消息就是张三发送的。

HTTPS就是在应用层和传输层中间加了一道验证的门槛以保证数据安全

 

 


get和post

http协议最常见的两种方法GET和POST:

请求缓存:GET 会被缓存,而post不会

收藏书签:GET可以,而POST不能

保留浏览器历史记录:GET可以,而POST不能

用处:get常用于取回数据,post用于提交数据

安全性:post比get安全

请求参数:querystring 是url的一部分get、post都可以带上。 get的querystring(仅支持urlencode编码),post的参数是放在body(支持多种编码)

请求参数长度限制:get请求长度最多1024kb,post对请求数据没有限制


三次握手

三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口建立TCP连接,并同步连接双方的序列号和确认号交换TCP窗口大小信息

四次挥手

建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。

TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务器均可主动发起挥手动作。

详细的看这里https://blog.csdn.net/Sestid/article/details/103909449


同步模式" 就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

异步模式" 非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。


js处理异步的几种方式

一、回调函数(callback)

回调是一个函数被作为一个参数传递到另一个函数里,在那个函数执行完后再执行。( 也即:B函数被作为参数传递到A函数里,在A函数执行完后再执行B )

二、事件监听

监听函数有:on,bind,listen,addEventListener,observe

三、发布/订阅

四、promise对象(promise 模式)

五、优雅的async/await


Promise详解

Promise有三种状态:pengding(),resolved(已完成),rejected(已失败);Promise从Pending状态开始,如果成功就转到成功态,并执行resolve回调函数;如果失败就转到失败状态并执行reject回调函数。

Promise 新建后就会立即执行。

优点:可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

缺点:无法取消 Promise;当处于pending状态时,无法得知目前进展到哪一个阶段。

两个特点:1、对象的状态不受外界影响 2、一旦状态改变,就不会再变,任何时候都可以得到这个结果

采用链式的then,可以指定一组按照次序调用的回调函数。

getJSON("/post/1.json").then(function(post) {
  return getJSON(post.commentURL);
}).then(function (comments) {
  console.log("resolved: ", comments);
}, function (err){
  console.log("rejected: ", err);
});

Promise.all()接收一个数组为参数,当数组的所有Promise都为resolve的状态时,Promise.all()才会成功;若有一个失败,都会被认为是失败的。举个小例子:

var p1 = Promise.resolve('a');
 var p2 = Promise.resolve('b');
 var p3 = Promise.resolve('c');
Promise.all([p1,p2,p3]).then(function(value) {
    console.log(value);
})

let,const,var有什么区别

let 和 const 定义的变量不会出现变量提升,而 var 定义的变量会提升;let 和 const 是JS中的块级作用域;let 和 const 不允许重复声明(会抛出错误);let 和 const 定义的变量在定义语句之前,如果使用会抛出错误(形成了暂时性死区),而 var 不会;const 声明一个只读的常量,一旦声明,常量的值就不能改变(如果声明是一个对象,那么不能改变的是对象的引用地址)。


Webpack如何实现打包

WebPack是一个模块打包工具,你可以使用WebPack管理你的模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包Web开发中所用到的HTML、Javascript、CSS以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack有对应的模块加载器。webpack模块打包器会分析模块间的依赖关系,最后生成了优化且合并后的静态资源。


MVC模式【Model(模型)+View(视图)+controller(控制器)】

View通过Controller来和Model联系,Controller是View和Model的协调者,View和Model不直接联系,基本联系都是单向的。用户User通过控制器Controller来操作模板Model从而达到视图View的变化
React框架【MVC】

优点:jsx语法创建虚拟DOM,极速的渲染性能;组件化开发,组件独立,方便重复使用;单向数据流;组件生命周期;跨浏览器兼容性好

缺点:不适合单独做一个完整的框架

应用场景:个性化需求、中型应用

Vue与React的区别

相同点:react和vue都是用虚拟DOM Virtual DOM;中心思想相同:一切都是组件,组件实例之间可以嵌套;都有着合理的钩子函数;都不内置ajax、route等核心包,以插件的形式加载;都有配套的路由和负责处理全局状态管理的库;

不同点:React使用JSX渲染页面,Vue使用简单的模板;Vue双向数据流,React单向数据流;Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作DOM;Vue比react运行更快

React生命周期函数

1、组件的挂载(Mounting)阶段(初始): constructor 、componentWillMount、 render 、componentDidMount

2、组件的更新(update)阶段:componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,render,componentDidUpdate

3、组件销毁阶段:componentWillUnmount

React hook的优点

1、代码可读性更强,原本同一块功能的代码逻辑被拆分在了不同的生命周期函数中,容易使开发者不利于维护和迭代,通过 React Hooks 可以将功能代码聚合,方便阅读维护。

2、组件树层级变浅

3、不用再去考虑 this 的指向问题

useEffect
语法:useEffect(fn,Array)

第一个参数传递函数,可以用来做一些副作用比如异步请求,修改外部参数等行为。
第二个参数是个数组,数组中的值发生变化才会触发 useEffect 第一个参数中的函数。
如果第二个参数是个空数组的话,默认会在页面加载后执行一次
如果第一个参数有返回值,会在组件销毁或者调用函数前调用。
可以使用useEffect模拟componentDidMount、 componentDidMount 和 componentWillUnmount钩子函数

import React, { useState, useEffect } from "react";
function App(){
    const [count, setCount] = useState(0);
    useEffect(()=>{
        //只要count有变化,就会执行这里
    },[count])
    
    useEffect(()=>{
        //如果在下面没有参数的话,页面加载后执行,执行一次
        return()=>{
            //页面退出的时候执行
        }
    },[])
}

React Fiber 架构理解 

React Fiber 的目标是提高其对动画,布局和手势等领域的适用性。它的主体特征是增量渲染:能够将渲染工作分割成块,并将其分散到多个帧中。

其他主要功能包括在进行更新时暂停,中止或重新使用工作的能力,为不同类型的更新分配优先权的能力和新的并发原语。

diff算法

diff算法会从根节点开始,一层层的向下比较,如果在某一层的某个节点发现不同了,他就会直接替换这个节点下面的所有内容。
这样有同学就会想为什么不一直比较下去呢,下面不需要改变的也替换掉了。是存在这种问题。
但是同层比对的算法简单,算发简单,比对起来速度就很快。

  • 把树形结构按照层级分解,只比较同级元素。
  • 给列表结构的每个单元添加唯一的 key 属性,方便比较。
  • React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
  • 合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制.
  • 选择性子树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能

mmutable Data
Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改、添加或删除操作都会返回一个新的 Immutable 对象。
Immutable 实现原理是持久化数据结构(Persistent Data Structure),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。
为了避免深度拷贝(deep Copy)把所有节点都复制一遍带来的性能损耗,Immutable 使用了共享结构(Structural Sharing),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

Immutable 特点

  • 持久化数据结构(Persistent Data Structure)
  • 共享结构(Structural Sharing)
  • 速度快、用时短

redux

我个人粗浅的理解是:
Store的角色是整个应用的数据存储中心,集中大部分页面需要的状态数据;
ActionCreators ,view 层与data层的介质;
Reduce ,接收action并更新Store。
所以流程是 用户通过界面组件 触发ActionCreator,携带Store中的旧State与Action 流向Reducer,Reducer返回新的state,并更新界面。


数组去重
方法一:
这是个没有什么技术含量的方法(使用了ES6 Set数据结构)!

  let arr = [1,1,1,1,2,3,4,5,5,6];
    arr = [...new Set(arr)];       // [1,2,3,4,5,6]

方法二:
for循环嵌套for循环

function unique(arr){
    for(let i = 0; i<arr.length; i++) {
        for(let j = i+1; j < arr.length; j++) {
            if(arr[i] === arr[j]){
                arr.splice(j,1);   // 去除重复的这个
                j--;
            }
        }
    }
    return arr;
}

方法三
使用indexOf方法,或数组的includes方法

function unique(arr) {
    let arr1 = [];
    for(let i=0; i<arr.length; i++) {
        if(arr1.indexOf(arr[i]) === -1) {  // !arr1.includes(arr[i])
            arr1.push(arr[i]);      // 如果arr1中不存在该元素则push进arr1
        }    
    }
    return arr1;
}

方法四
利用sort排序后,相邻元素进行对比

function unique(arr) {
    arr.sort( (a,b) => a-b);
    for(let i=0; i< arr.length-1; i++){
        if(arr[i] === arr[i+1]) {
            arr.splice(i+1,1);
        }
    }
    return arr;
}

 方法五

  reduce()

let arr = [1,1,2,3,4,5,5,6]
let arr2 = arr.reduce(function(ar,cur) {
  if(!ar.includes(cur)) {
    ar.push(cur)
  }

  return ar
},[])

 方法六

  filter()

// 这种方法会有一个问题:[1,'1']会被当做相同元素,最终输入[1]
let arr = [1,1,2,3,4,5,5,6]
let arr2 = arr.filter(function(item,index) {
  // indexOf() 方法可返回某个指定的 字符串值 在字符串中首次出现的位置
  return arr.indexOf(item) === index
})

数组排序 

第一种:arrayObject.sort(sortby)

function sortNum(a, b) {

return a - b;

}

let arr = [524, 684, 5, 69, 15];

let res = arr.sort(sortNum);

console.log(res);

第二种:冒泡排序

function bubbleSort(arr) {

    for (let i = 0; i < arr.length; i++) {

        for (let j = 0; j < arr.length; j++) {

            if (arr[i] < arr[j]) {

                let temp = arr[j];

                arr[j] = arr[i];

                arr[i] = temp;

            }

        }

    }

    return arr;

}

let arr = [524, 684, 5, 69, 15];

console.log(bubbleSort(arr));

第三种:快速排序

function quickSort(arr) {

    if (arr.length <= 1) {

        return arr;

    }

    let pivotIndex = Math.floor(arr.length / 2),

    pivot = arr.splice(pivotIndex, 1)[0],

    lef = [],

    rig = [];

    for (var i = 0; i < arr.length; i++) {

        if (arr[i] < pivot) {

            lef.push(arr[i]);

        }else {

            rig.push(arr[i]);

        }

    }

    return quickSort(lef).concat(pivot, quickSort(rig));

}

let arr = [524, 684, 5, 69, 15];

console.log(quickSort(arr));

第四种:插入排序

function insertSort(arr, a) {

    for (let i = 1; i < arr.length; i++) {

        if (arr[i] >= a) {

            for (let j = arr.length; j > i; j--) {

                arr[j] = arr[j - 1];

            }

            arr[i] = a;

            break;

        }

    }

    return arr;

}

let arr = [5, 15, 69, 524, 684];

console.log(insertSort(arr, 92));

多维数组转一维 

1、使用apply结合concat,缺点是只能将二维转一维,多维数组就不行了

let arr = [1,[2,3],[4,5]];
console.log([].concat.apply([],arr));

2、将数组转为字符串再转为数组,缺点是数组中每项成字符串了

let arr = [1,[2,[[3,4],5],6]];
let arr2 = arr.join(',').split(',');
console.log(arr2);//["1", "2", "3", "4", "5", "6"]
//或
let c=[1,3,4,5,[6,[0,1,5],9],[2,5,[1,5]],[5]];
console.log(c.toString().split(','))

3、递归调用

let arr = [1, 2, 3, 4, 5, [6, 7, 8, [9, 10, 11, 12, [13, 14, 15, 16]]]]
let newArr = [] // 存放转化后的一维数组
function arrConversion (arr) {
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      arrConversion(arr[i])
    } else {
      newArr.push(arr[i])
    }
  }
}
arrConversion(arr)
console.log(newArr) // 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

4、es6中的flat()方法

console.log([1 ,[2, 3]].flat()); // [1, 2, 3]
 
// 指定转换的嵌套层数
console.log([1, [2, [3, [4, 5]]]].flat(2)); // [1, 2, 3, [4, 5]] 
// 不管嵌套多少层
console.log([1, [2, [3, [4, 5]]]].flat(Infinity)); // [1, 2, 3, 4, 5] 
// 自动跳过空位
console.log([1, [2, , 3]].flat());<p> // [1, 2, 3]

5、正则

    let ary = [1, [2, [3, [4, 5]]], 6];
    let str = JSON.stringify(ary);
    let result = str.replace(/(\[|\])/g, '').split(',');
    console.log( result )

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值