20230626前端大佬的面试筛出的问题,做了份答案。希望各位能用的上。顺祝各位早日上岸。

正则

涉及正则的 函数

1. search(yourRegexpOrString);

    定义:检索字符串中与指定的子字符串或正则表达式相匹配的子字符串。

    其他说明:该方法将忽略"g"标志和正则对象的lastIndex属性(即总是从开头找起),返回找到的第一个字符的位置,如果未找到返回-1。

2. match(yourRegexpOrString);

    定义:在字符串内查找一个或多个与正则表达式匹配的字符串,返回一个对象。(忽略laseIndex属性)

    其他说明:若没开启"g"标志,将只查找第一个匹配的字符串,返回一个对象,包含下标0、index、input,其中下标0等价于index,input是String的引用;开启"g",返回一个数组,数组的length是匹配的字符串个数,每个元素是每个匹配的起始字符位置。

3. replace(yourRegexpOrString,placementString);

    定义:用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

    其他说明:如果没有"g"标志只会替换一次,并且如果参数是字符串而不是正则对象始终替换一次。

4. split(yourRegexpOrString[,howMany]);

    定义:把一个字符串分割成字符串值的数组。

    其他说明:是arr.join(separatorString)反操作,如果传入"",则每个字符都将会被分隔到数组。howMany指定返回数组的个数。

HTML、CSS、JS

1、浏览器页面渲染流程,说完后会问到重排重绘区别

1.1 浏览器页面渲染流程

0. 渲染引擎首先通过网络获得所请求文档的内容
1. 解析HTML文件,构建 DOM Tree
2. 解析CSS,构建 CSSOM Tree(CSS规则树)
3. 将 DOM Tree 和 CSSOM Tree合并,构建Render tree(渲染树)
4. reflow(重排):根据Render tree进行节点信息计算(Layout)
5. repaint(重绘):根据计算好的信息绘制整个页面(Painting)

1.2 重排重绘区别

1.2.1 定义
重绘: 重绘是一个元素外观的改变导致的浏览器行为(例如改变visibility,outline,background等属性),浏览器会根据元素新的属性呈现新的外观;
重排:重排是DOM元素被js触发某种变化,渲染树需要重新计算。浏览器对DOM 树进行重新排列;这便是重排。排列完成之后重新绘制元素则是重绘。
1.2.2 操作

常见的触发重排的操作:

DOM元素的几何属性变化

DOM树的结构变化(例如节点的增减、移动)

获取某些属性(例如offsetTop,offsetLeft,offsetHeight,offsetWidth,clientWidth,clientHeight等)

改变元素的一些样式(例如调整浏览器窗口大小)

1.2.2 两者的区别

重绘不会带来重新布局,并不一定伴随着重排.

1.3 为什么要使用 虚拟 DOM
1、操作 DOM 会导致浏览器频繁的出现页面的回流和重绘,⾮常耗性能
2、手动操作 DOM 还是比较麻烦的,要考虑浏览器兼容性问题

3、相对于 DOM对象,js对象处理起来更快,而且更简单,通过 diff算法 对比 新旧vdom 之间的差异,可以 批量的、最⼩化的执行 dom操作,从而提高性能
4、虚拟DOM 进行频繁修改,最终一次性比较并修改 真实DOM 中需要改的部分,最后在 真实DOM中 进行排版与重绘,减少过多 DOM节点 回流与重绘损耗
5、使用 虚拟DOM 改变了当前的状态不需要立即的去更新 DOM 而且更新的内容进行更新,对于没有改变的内容不做任何操作,通过前后两次差异进行比较
6、虚拟DOM 可以实现跨平台渲染,服务器渲染 、小程序、原生应用都使用了 虚拟DOM
7、虚拟 DOM 可以维护程序的状态,跟踪上一次的状态

总之: 
虚拟DOM 就是为了解决浏览器性能问题而被设计出来的
若一次操作中有 10 次更新 DOM 的动作,虚拟 DOM 不会立即操作 DOM 而是将这 10 次更新的 diff 内容保存到本地一个 JS 对象中
最终将这个 JS 对象一次性 attch 到 DOM 树上,再进行后续操作,避免大量无谓的计算量

所以:
用 JS 对象模拟 DOM 节点的好处是,页面的更新可以先全部反映在 JS 对象(虚拟 DOM )上
操作内存中的 JS 对象的速度显然要更快,等更新完成后,再将最终的 JS 对象映射成真实的 DOM,交由浏览器去绘制

2、CSS动画,transform与animate的区别等

2.1 动画状态不同

1.transform过渡只有开始和结束两种状态;
2.animation有开始,过程,结束多种状态;

2.2 动画触发方式不同:

1. CSS的transition需要借助别的方式来触发, 比如CSS的状态选择器(如:hover)或 借助JavaScript来触发 。
2. animation 不但可以使用上面的方式触发, 更重要的是可以自动触发 。

2.3 功能点(属性)不同

animation 控制动效上要比 transition 强,因为它具备一些控制动效的属性,比如“播放次数”、“播放方向”、“播放状态”等。

2.4 transform和animation的相同点

1. 从整体来看,animation 和 transition 想做的事情都是一样, 通过控制属性变化的过程也, 实现动画; 都是立足于控制本身 dom 的 css 属性变化过程, 来实现动画的视觉效果。

2. 他们都有“持续时间”、“延迟时间” 和“时间缓动函数”等概念,这些都是用来控制动效的效果。

3、上下居中、flex、栅格化、定位、BFC及应用、主题切换

3.1 水平居中

1. 水平居中:
    text-align:center

2. flex 布局

3.1 上下居中

1. 上下居中文字
    line-height: 容器高度

2. 非文字的上下居中
    top: 50%
    margin: 容器一半高度 0 0 容器一半宽度;

3. 使用浮动
    float:left;
    clear:both;

4. 上下垂直居中
    padding:10px 0

5. flex
    display:flex;
    align-items:center;

6. transform:translate();加一半减一半居中 与第二条相似
    position: relative;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);

3.2 Grid

3.2 Flex

3.2.1 定义
flex布局是一种布局模型,经常被称之为flexbox,使用flex布局之后,他会给子元素提供强大空间分配和对齐能力。
flex的优点就是避免不灵活的布局形式,创建更多种布局模式供你选择,解决了子元素的对齐和分布与 响应式等问题。缺点是只能依靠自身的布局模式,稍有变化则无法改变。 
3.2.2 总结
用于容器的属性:
    display:flex 指定flex布局                       

    flex-direction 主轴的排序(主轴方向),默认值row                        

    flex-warp:nowarp 项目在容器中是否换行显示,常用之warp                        

    justify-content 主轴的对齐方式                        

    align-items交叉轴的对齐方式(一般用于单轴线)                        

    align-content多轴线对齐方式

用于项目的属性:
    order:0项目的排序                       

    flex-grow:0放大规则,默认0,不放大                      

    flex-shrink:1 收缩规则,默认1,缩小;0,不缩小。                        

    flex-basis:200px 指定主轴长度尺寸,不允许负值,默认值auto,优先级比主轴的尺寸高    

    flex集合写法,放大,缩小,初始尺寸,默认0  1  auto。flex:1指放大,flex:0  0不放大不缩小    

3.3 栅格化

1. 容器
2. 行
3. 列

3.4 定位

一、静态定位:static
    静态定位是元素的默认定位方式,无定位的意思。它相当于border里面的none,不要定位的时候用。

    特点:按照标准流特性摆放位置,它没有边偏移,在布局时我们几乎不用。

二、相对定位:relative
    特点:相对于自己原来在标准流中位置来移动的,原来在标准流的区域继续占有,后面的盒子仍然以标准流的方式对待它。

三、绝对定位:absolute
    特点:绝对定位是元素依据最近的已经定位的父级元素来进行移动,不占用原来在标准流的位置

    若父元素没有定位,则以浏览器为准定位(Document 文档)

四、固定定位:fixed
    固定定位是绝对定位的一种特殊形式: 如果说绝对定位是一个矩形那么固定定位就类似于正方形

    特点:
        1. 不占位置
        2、跟父元素没有任何关系,单独设置位置
        3、不随滚动条滚动

五、定位要点——子绝父相
    子级元素是绝对定位,父级元素要用相对定位,即所谓的子绝父相

3.5 BFC及应用

3.5.1 BFC
块格式化上下文(Block Formatting Context,BFC) 是 Web 页面的可视化 CSS 渲染的一部分

根元素(<html>)
浮动元素(元素的 float 不是 none)
绝对定位元素(元素的 position 为 absolute 或 fixed)
display 为 inline-block、table-cells、flex、grid...
overflow 值不为 visible 的块元素(hidden、auto、scroll)
3.5.2 应用
1. 可以避免外边距重叠 ( 把两个div包裹在两个不同container容器中,用over-hidden触发container的BFC)
2. 清除浮动
2. 避免重叠

3.6 主题切换

方法1:定义全局的CSS变量
方法2:切换已定义好的css文件
方法3:切换顶级CSS类名 (需使用css处理器,如sass、less等)

4、深浅拷贝、promise、防抖节流、es6新特性、事件循环、websocket长链接、闭包、数据存储、es6数组新方法 等这些都是目前js的基本问题,一般公司都会拿出来几个

4.1 深浅拷贝

1. 浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
2. 深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。
手搓深拷贝-递归、type of 判定引用数据类型、for循环、回调function

function deepClone(obj) {
    //判断obj是数组还是对象.
    var objClone = Array.isArray(obj) ? [] : {};
    //进行深拷贝的不能为空,并且是对象或者是"object"
    if (obj && typeof obj === "object") {
    for (key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (obj[key] && typeof obj[key] === "object") {
                objClone[key] = deepClone(obj[key]);
            } else {
                objClone[key] = obj[key];
            }
        }
    }
    }
    return objClone;
}

4.2 promise

4.2.1 定义
是异步编程的一种解决方案,注意一下三点
1. 链式操作减低了编码难度
2. 代码可读性明显增强

3. 状态一旦修改将不或改变。(即 resolve() reject(),先执行先生效,后续不改变)
4.2.1 状态
. pending(进行中)
. fulfilled(已成功)
. rejected(已失败)
4.2.2 实例
. then()
. catch()
. finally()
4.2.3 构造方法
. all()  当所有Promise任务是resolve结果才是resolve--也就是执行then里面的回调,只要有一个任务reject则就会执行catch里面的回调,执行时间是所有任务中执行时间最长的那个任务所对应的时间
. race() 执行结果就是最先改变状态的promise任务的状态,无论是resolve还是reject,那个先改变状态,整个任务的执行时间就是对应的那个成功任务所对应的时间
. any() 捕获任意一个先成功执行的Promise任务,那个先成功,整个任务的执行时间就是对应的那个成功任务所对应的时间
. allSettled() allSettled方法接收一组promise实例作为参数,包装成一个新的实例。只有等所有的实例都返回结果,才会结束。返回的结果不论成功失败,状态总是fulfilled,不会是失败。
. try()
. reject()
. resolve()
. catch()

4.3 防抖节流

定义
    节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效。场景:验证码,防点击按钮,王者技能
    防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时。场景:获取输入框内容,王者回城

一个经典的比喻:
    想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应
    假设电梯有两种运行策略 debounce 和 throttle,超时设定为15秒,不考虑容量限制
    电梯第一个人进来后,15秒后准时运送一次,这是节流
    电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这是防抖
4.3.1 防抖
function debounce(func, wait) {
    let timeout;

    return function () {
        let context = this; // 保存this指向
        let args = arguments; // 拿到event对象

        clearTimeout(timeout)
        timeout = setTimeout(function(){
            func.apply(context, args)
        }, wait);
    }
}
4.3.2 节流
function debounce(func, wait) {
    let timeout;

    return function () {
        let context = this; // 保存this指向
        let args = arguments; // 拿到event对象

        clearTimeout(timeout)
        timeout = setTimeout(function(){
            func.apply(context, args)
        }, wait);
    }
}

4.4 es6新特性

4.5 前端常用的存储数据的方式有2种

1.本地存储:(localstorage、sessionstorage、cookie)

2.Vuex存储:(state、getter、mutations、action、modules)

1. vuex存储在内存;
2. localstorage(本地存储)则以文件的方式存储在本地,永久保存;
3. sessionstorage( 会话存储 ) ,临时保存。
4. localStorage和sessionStorage只能存储字符串类型,

( 对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理。)

4.5.1 Vuex和本地存储的区别:
1、实质的区别
vuex存的是状态,存储在内存,localstorage是浏览器提供的接口,让你存的是文件,以文件的形式存储在本地

2、应用场景
vuex用于组件之间的传值,localstorage则主要用于页面之间的传值

3、永久性
当刷新页面时,vuex存储的值会丢失,localstorage不会

4、响应式

localstorage无法做到响应式,vuex可以绑定数据响应式。

使用vuex容器存储数据时,可以配合localstorage(sessionStorage)来存储到本地,实现持久化数据

注意: localStorage.setItem(key, String), set的值必须是字符串,如果你的数据是对象都需要先行转换(JSON.stringify(xxx)),取出时localStorage.getItem(key),取出后的字符串可以通过JSON.parse(xxx) 转回对象。

4.5.2 Cookie,localStorage,sessionStorage区别?

特性 Cookie localStorage sessionStorage 数据的生命期 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 除非被清除,否则永久保存 仅在当前会话下有效,关闭页面或浏览器后被清除 存放数据大小 4K左右 一般为5MB 与服务器端通信 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 仅在客户端(即浏览器)中保存,不参与和服务器的通信 易用性 需要程序员自己封装,源生的Cookie接口不友好 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

4.6 事件循环

4.6.1 Event Loop
 是JavaScript或Node为解决单线程代码执行不阻塞主进程一种机制
4.6.2 同步任务、异步任务(宏任务、微任务)
整体的script(作为第一个宏任务)开始执行的时候,会把所有代码分为两部分:“同步任务”、“异步任务”;

同步任务会直接进入主线程依次执行;

异步任务会再分为宏任务(进入宏任务队列) 和 微任务(进入微任务队列)。

当主线程内的任务执行完毕(主线程为空时),会检查微任务的任务队列,如果有任务,就进入主线程全部执行,如果没有就从宏任务队列读取下一个宏任务执行;

每执行完一个宏任务就清空一次微任务队列,此过程会不断重复,这就是Event Loop;
4.6.3 栗子

new Promise((res)=>{
    console.log(1)
    setTimeout(()=>{
        console.log(2)
    })
    res()
}).then(()=>{
    console.log(3)
})

//输出结果: 1 -> 3 -> 2

// setTimeout的定时器回调函数是异步执行的,而Promise中的resolve函数res()是同步执行的。
// 当Promise的状态变为resolved后,.then中的回调函数会被添加到微任务队列中等待执行。由于
// 微任务队列中的任务会在主线程的同步任务执行完毕后立即执行,所以数字3会在数字2之前被打印出来。

5、还有一些更简单的比如基本数据类型,let const var区别(或者说变量提升),改变this指针,跨域,作用域等等

5.1 基本数据类型

1. 引用数据类型 Function、Array、Object
2. 基本数据类型 Number、String、Boolean、Undefined、null、symbol

3. Undefined、Null 的区别
主要区别在于undefined表示尚未初始化的变量的值,而null表示该变量有意缺少对象指向。

5.2 let const var区别

var声明的变量既是全局变量,变量提升,允许重复;
let命令所在的代码块内有效,块级作用域,不允许重复;
const声明一个只读的常量,块级作用域,不允许重复,不允许修改;

变量提升: 变量提升的作用是在代码执行之前提前声明变量,避免变量在代码执行时被意外修改

5.2 修改 this 指向

call  参数列表 立即执行
apply 参数数组 立即执行
bind  参数列表 返回函数

5.3 跨域

1. devServer proxy
2. nginx 反向代理

5.4 作用域

1. 全局作用域 var
2. 函数作用域
3. 块级作用域 let  const

6 function 与 箭头函数 区别

1. 字面意思:function  箭头
2. this指向:function的 this指向调用该函数的对象,如果没有直接指定就是window;箭头函数不会创建自己的 this ,始终指向箭头函数声明时所在作用域下的 this 值,也就是从箭头函数所在作用域的父层继承this。
3. 箭头函数:没有constructor, 不能用作构造器(不能被new)
4. 箭头函数:没有__proto__,
5. 箭头函数:不绑定arguments。普通函数中可以使用 arguments 对象获取函数的所有参数。
6. apply、call、bind中使用箭头函数,不能改变this指向

VUE相关

1、vue2与vue3区别以及vue3的组合式api好处

v2/v3区别

1.数据劫持方式不同
1.vue2的底层原理是基于 Object.defineProperty封装的一种发布订阅模式,利用它的get和set方法对对象的属性进行监听
2.vue3是基于es6的proxy封装的发布订阅模式

数据劫持方式的不同是的v2和v3有何区别
Object.defineProperty只能监听对象的属性并且不能监听动态添加的属性。es6的proxy可以监听一切。
2.v-if和 v-for优先级问题 (不会就别说这条)
v-for的优先级⾼. 因为v-for的时候我们才开始渲染dom元素,这个v-if还⽆法进⾏判断.
v-for和v-if不能同时使⽤,我们可以通过标签,⽐如div或者template标签来进⾏包裹,把v-if写到包裹的标签上⾯(写到v-for外⾯
3.vue3中废除了filter
4.生命周期钩子函数的不同
v2 beforeDestroy 废弃了 v3 beforeUnmount
v2 destroyed 废弃了 v3 用 unmounted
6.router (不会就别说这条)
7.API

vue2是选项api 需要什么选项就直接写什么选项    vue3是组合api 所有的代码都写在setup里边  需要什么就要import引入什么

8.Vue3默认使用懒加载
9.重构虚拟DOM

2、v2/v3生命周期、watch与computed区别、slot插槽、v2/v3的vif与vfor优先级区别、nextTick

2.4 nexTick

2.4.1 定义

在下次 DOM 更新循环结束之后执行延迟回调。

2.4.2 场景

1. 在 Vue 的数据变化后,想要执行一些操作,确保操作在 DOM 更新后执行,例如在数据变化后操作 DOM 元素、触发子组件的方法等。
2. 在 Vue 的生命周期钩子函数或自定义的方法中,需要等待 DOM 更新完成后执行一些操作。

3、权限控制 —— 这问题很多,一般都是问按钮权限的控制,我一般都是答全局指令

钩子函数: 指令定义函数提供了几个钩子函数(可选):

    bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

    inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

    update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。

    componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。

    unbind: 只调用一次, 指令与元素解绑时调用。

4、axios封装、用过的ui组件,用过的echarts图表等

5、v2/v3 diff算法、v2/v3 双向绑定原理、动态添加路由(addRoute,也是和权限相关一起问)

5.1 diff 算法

5.1.1 diff定义

diff 算法是一种通过同层的树节点进行比较的高效算法

虚拟 dom 渲染成真实 dom 的新旧 VNode 节点比较

5.1.1 diff整体策略为:深度优先,同层比较

5.2 vue双向数据绑定

vue双向数据绑定是 通过 `数据劫持` 并结合 `发布-订阅模式` 的方法来实现的。 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变。

示例:
<input type="text">
  <p></p>
  <script>
    window.onload = function () {
      const input = document.querySelector('input')   // 发布者
      const p = document.querySelector('p')   // 订阅者
      window.data = ''  // 要双向绑定的数据

      Object.defineProperty(window, 'data', {
        get: function() {
          return data
        },
        set: function(value) {  // 数据劫持,订阅者函数,更新 DOM
          p.innerText = value
        }
      })

      input.onkeyup = (e) => {   // onkeyuo与setter 共同形成事件中心 broker
        window.data = input.value // 发布数据
      }
    }
  </script>

6、组件通信 —- 基本必问

7、性能优化 —- 基本必问

1.cdn、懒加载、各类loader压缩、gzip压缩、精灵图、icon转font、接口合并等等

8、xxs攻击以及预防(这个问题济南本地的公司没有问的,只有啥啥济南分公司可能问道)

写在最后的话

鸡儿的济南今年真热。
写的不全凑活着看吧,这次收获颇丰。
面试题仓库地址自己fork看着改就行,个人学习系列 20230626面试题 https://gitee.com/yiyanghuayigai/personal-learning-notes.git
先声明下不是我自己的库,我拿别人的库改的。原始库:https://github.com/febobo/web-interview
被人问的最多的就是项目经历,还好出彩的地方能说的过去。面试题要背,项目经历也要梳理一下。比如说,权限控制等等啥的,以及你做过的出彩的技术之处和项目经历。
学历加专业筛人太狠了,有公司现在都招聘985211的。
市场好转后也不知道从北上广回来的铁子们,还要不要回去?