react以及常见前端面试题(看这一篇就够了)持续更新中...

目录

1、说说对React的理解?有哪些特性?

2、说说Real diff算法是怎么运作的?

3、 说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?

4、说说你对React中虚拟dom的理解?

5、 说说你对react hook的理解?

6、 React组件之间如何通信?

7、 说说你对受控组件和非受控组件的理解?应用场景?

8、 说说Connect组件的原理是什么?

9、说说react 中jsx语法糖的本质?

10、说说你对redux中间件的理解?常用的中间件有哪些?实现原理?

11、说说AMD、CMD、commonJS模块化规范的区别?

12、说说package.json中版本号的规则?

13、说说React jsx转换成真实DOM的过程?

14、说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?

15、 React render方法的原理,在什么时候会触发?

16、 React性能优化的手段有哪些?

17、如何通过原生js实现一个节流函数和防抖函数?

18、说说你对koa中洋葱模型的理解?

19、说说如何借助webpack来优化前端性能?

20、 说说你对webSocket的理解?

21、bind、call、apply 区别?如何实现一个bind?

22、 什么是防抖和节流?有什么区别?如何实现?

23、怎么理解回流跟重绘?什么场景下会触发?

24、VUE路由的原理?

25、你了解vue的diff算法吗?说说看?

26、说说你对keep-alive的理解?

27、什么是响应式设计?响应式设计的基本原理是什么?如何做?

28、如何解决跨域问题?

29、如何优化webpack打包速度?

30、SPA首屏加载速度慢的怎么解决?

31、说说react router有几种模式?实现原理?

32、从浏览器地址栏输入url到显示页面的步骤?

33、说说JavaScript中的数据类型?存储上的差别?

34、说说对React Hooks的理解?解决了什么问题?

35、说说你对promise的了解?

36、 说说webpack中常见的Loader?解决了什么问题?

37、说说 React 性能优化的手段有哪些?

38、 说说 React中的setState执行机制?

39、 Vue组件之间的通信方式都有哪些?

40、 说说React生命周期中有哪些坑?如何避免?

41、调和阶段setState干了什么?

42、说说redux的实现原理是什么,写出核心代码?

43、 React合成事件的原理?

44、 为什么react元素有一个$$type属性?

45、说说你对redux中间件的理解?常用的中间件有哪些?实现原理?

46、说说你对事件循环event loop的理解?

47、前端跨域的解决方案?

48、数组常用方法及作用,至少15个?

49、说说你对vue中mixin的理解?

50、for...in循环和for...of循环的区别?

51、Js数据类型判断都有哪几种方式?至少说出5种?它们的区别是什么?

52、说说你对Object.defineProperty()的理解?

53、Vue中自定义指令的理解,应用场景有哪些?

54、说说javascript内存泄漏的几种情况?

55、大文件如何做断点续传?

56、原生js如何实现上拉加载下拉刷新?

57、说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别?

58、谈谈你对BFC的理解?

59、说说TCP为什么需要三次握手和四次握手?

60、前端性能优化的手段有哪些?

61、最少说出三种前端清除浮动的方法?

62、什么是强缓存和协商缓存?

63、说说你对栈、队列的理解?应用场景?

64、说说你对git rebase 和git merge的理解?区别?

65、说说git常用的命令有哪些?

66、Vue组件通信?

67、说说你对vuex的理解?写出其原理的核心代码?

68、props和state相同点和不同点?render方法在哪些情况下会执行?

69、react新出来两个钩子函数是什么?和删掉的will系列有什么区别?

70、CDN的特点及意义?

71、什么是闭包,应用场景是什么?

72、介绍一下你对浏览器内核的理解?

73、 清除浮动的几种方式?各自的优缺点?

74、 如果需要手动写动画,你认为最小时间间隔是多久,为什么?

75、说说Real DOM和Virtual DOM的区别?优缺点?

76、说说react的事件机制?

77、说说你对fiber架构的理解?解决了什么问题?

78、说说react diff的原理是什么?

79、如何使用css实现一个三角形?

80、shouldComponentUpdate有什么作用?

81、说说你对git rebase 和git merge的理解?区别?

82、在使用redux过程中,如何防止定义的action-type的常量重复?

83、说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关系?

84、React的props.children使用map函数来遍历会收到异常显示,为什么?应该 如何遍历?

85、谈谈你对immutable.js的理解?

86、redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的 实现原理是什么?

87、redux中同步action与异步action最大的区别是什么?

88、redux-saga和redux-thunk的区别与使用场景?

89、为什么普通的for循环比forEach循环性能要高?

90、移动端1像素的解决方案?

91、弹性盒中的缩放机制是怎样?

92、说说你对vue中mixin的理解?

93、for...in循环和for...of循环的区别?

94、什么是发布订阅模式,写出其核心实现代码?

95、说一说你对视口的理解?

96、说说你对useEffect的理解,可以模拟哪些生命周期?

97、说说React中setState和replaceState的区别?

98、说说react中onClick绑定后的工作原理?

99、什么是垂直外边距合并?说说合并后的几种情况?

100、useEffect的依赖为引用类型如何处理?

101、知道react里面的createPortal么,说说其使用场景?

1、Portal ,将子节点渲染到存在于父组件以外的 DOM 节点。2、ReactDOM.createPortal(child, container)第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或 fragment。第二个参数(container)是一个 DOM 元素。2、Portals 适合脱离文档流(out of flow) 的组件,特别是 position: absolute 与 position: fixed的组件。比如模态框,通知,警告,goTop 等

2.0版本

1、说说你对Event Loop的理解?

2、说说你对BOM的理解,常见的BOM对象你了解哪些?

3、浏览器的内核都有哪些,什么区别?

4、说说浏览器的渐进增强和优雅降级的区别?

5、 网站性能优化的方案都有哪些?

6、Link和@import之间有什么区别?

7、说说你对BFC的理解,触发条件有哪些?

8、null,undefined 的区别?

9、说说css中元素脱离文档流的方式有哪些?定位的方式有哪些以及区别?

10、同步和异步的区别?

11、伪类和伪元素的区别有哪些? Css3新增了哪些选择器?

12、说说Promise和async/await的区别是?

13、说说重排和重绘的区别?触发条件有哪些?

14、Javascript如何实现继承?

15、说说什么是严格模式,限制都有哪些?

16、如何快速的让一个打乱一个数组的顺序,比如 var arr = [1,2,3,4,5,6,7,8,9,10]?

17、Vue的自定义指令钩子函数有哪些?你用自定义指令做过什么?

18、从A页面跳转到B页面,缓存A组件,从A组件跳转到C组件,取消缓存,如何实现?

19、Vue2和Vue3中响应式原理及区别?

20、Vue是如何实现实现权限管理的,按钮级别权限如何实现?

21、Vue2和Vue3的区别至少说5点?

22、 Vue3中组件通信的流程【父传子,子传父】?

23、Apply/call/bind的原理是什么?

24、说说你对原型和原型链的理解?

25、说说你对ES6中Generator的理解?

26、说说浏览器事件循环和nodeJs的事件循环的区别?

27、说说你对浏览器缓存机制的理解?

28、说说你对浏览器内核的理解?

29、说说你对Vue的响应式原理的理解?

30、Methods watch computed区别是什么?

31、说说你对Virtual DOM的理解?

32、说说你对nextTick的理解和作用?

33、说说你对webpack的理解?

34、谈谈GET和POST的区别?

35、说说HTTP和HTTPS的区别,HTTPS加密原理是?

36、TCP为什么要三次握手?

37、说说Proxy代理的原理?

38、说说内存泄漏的理解?内存泄漏的情况有哪些?

39、说说箭头函数和普通函数的区别?

40、SPA首屏加载速度慢怎么解决?

41、说说webpack中常见的Loader?解决了什么问题?

42、你对SPA单页面的理解,它的优缺点分别是什么?如何实现SPA应用呢?

43、Vue中组件和插件有什么区别?

44、Vue组件之间的通信方式都有哪些?

45、你了解vue的diff算法吗?说说看?

46、简单说一下 Virtual Dom?

47、Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

48、说说 React中的setState执行机制?

49、说说对React中类组件和函数组件的理解?有什么区别?

50、说说对React Hooks的理解?解决了什么问题?

51、UseMemo和useCallback如何提升了性能,应用场景有哪些?

52、Vue-router的实现原理是什么?

53、如何封装组件在不同的项目之间使用如何实现?

54、vue、react、angular 区别?

55、说说你对Redux的理解?其工作原理?

56、说说对盒子模型的理解?

57、Css的选择器有哪些?优先级?哪些可以继承?

58、元素水平垂直居中的方法有哪些?如果元素不定宽高呢?

59、怎么理解回流跟重绘?什么场景下会触发?

60、什么是响应式设计?响应式设计的基本原理是什么?如何做?

61、说一下对盒子模型的理解?

62、如何让一个盒子水平垂直居中,有哪些方法?

63、说说JavaScript有哪些数据类型,如何存储?

64、如何理解响应式?实现的方法有哪些?有什么区别?

65、Css性能优化有哪些常见的方法,具体如何实现?

66、判断数据类型的方法有哪些?有什么区别?

67、Bind 、Call 、Apply有什么区别?如何实现一个bind方法?

68、如何理解闭包?闭包的应用场景是?

69、简单的说一下什么是事件代理?

70、什么是防抖和节流?有什么区别?如何实现?

71、说说你对作用域链的理解?

72、说说对原型和原型链的理解?

73、vue的生命周期和含义有哪些?

74、vue自定义指令的钩子函数有哪些?

75、JavaScript本地存储有哪些?区别和使用场景?

76、说说你对递归的理解?封装一个方法用递归实现树形结构封装?

77、Link和@import有什么区别?

78、什么是FOUC?如何避免?

79、说说你对预编译器的理解?

80、shouldcomponentUpdate的作用?

81、概述React中的事务处理逻辑?

82、React组件的划分业务组件技术组件?

83、React性能优化是哪个周期函数?

84、说说对于Fiber架构的理解和应用场景?

85、React性能优化的方案?

86、简述flux和css渲染的过程是什么?

87、说一下DOM0、DOM2、DOM3事件处理的区别是什么?

88、如何判断页面滚动到底部,如何判断页面中元素是否进入可视化区域?

89、说一下浏览器Event Loop和nodejs中Event Loop的区别?

90、说一下vue-router的底层实现原理?

91、说一下vuex的实现原理?commit和dispatch方法是如何实现的?

92、有A,B,C 三个组件,A组件跳转到B组件缓存,A组件跳转到C组件不缓存,如何实现?

93、对于MVVM的理解?

94、请详细说一下对于vue生命周期的理解?

95、vue组件之间的数据传递方式有哪些?

96、vue的路由实现:hash模式和history模式原理?

97、vue路由的钩子函数有哪些?

98、v-if和v-show的区别?

99、$route和$router的区别?

100、如何让CSS只在当前组件中起作用?

101、的作用是什么?

102、在vue中使用插件的步骤?

103、请列举出三个vue中常见的生命周期钩子函数?

104、什么是Vue SSR?

105、Proxy相比于definedProperty的优势?

106、vuex是什么?怎么使用?哪种功能场景使用它?

107、vue2.x响应式原理?

108、ES5、ES6和ES2015有什么区别?

109、let有什么作用,有了var为什么还要使用let?

110、举一些ES6对于String字符串做的常用升级优化?

111、举一些ES6对于Array数组类型做的常用升级优化?

1.0版本

1、说说对React的理解?有哪些特性?

1、React是用于构建用户界面的JavaScript库,只提供了UI层面的解决方案,遵循组件设计模式、声明式编程范式和函数式编程概念,使得前端应用程序更加高效。
2、使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流,帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面。
3、特性:JSX语法、单项数据绑定、虚拟DOM、声明式编程、Component

2、说说Real diff算法是怎么运作的?

1、diff算法是为了节省性能而设计的,通过同层级进行比较,不跨层级使得性能更加高效
2、运作流程主要分为三层:tree层、component层、element层
    1、tree层:tree层对于DOM节点的跨层级移动的操作忽略,只对相同层级的DOM节点进行比较,一旦发现节点不存在,直接删除该节点以及以下的所有子节点
    2、component层:遇到同一个类型的组件遵循tree diff,进行层级对比,遇到不同类型的组件,直接将这个不同的组件判断为脏组件,并且替换该组件之下的所有的子节点,当知道这个组件的虚拟DOM没有任何变化,就可以手动使用,shouldComponentUpdate来判断是否需要进行diff,进一步提升了diff效率和性能
    3、element层:低于同一层级,面对全新节点,可以实现插入的操作;面对多余的节点,执行删除操作;面对换位的节点,执行移动的操作

3、 说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?

1、React生命周期主要分为三个阶段:创建阶段、更新阶段和卸载阶段
2、创建阶段:
    1、constructor:用来定义状态,或者是用来存放一些this的方法;
    2、getDerivedStateFromProps():将来会使用的,需要返回一个新的对象作为新的state或者返回null表示state状态不需要更新
    3、render():类组件必须实现的方法,用于渲染DOM结构,可以访问组件state与prop属性
    4、componentDidMount():用于执行一些数据获取,事件监听等操作
3、更新阶段:
    1、getDerivedStateFromProps():将来会使用的,需要返回一个新的对象作为新的state或者返回null表示state状态不需要更新
    2、shouldComponentUpdate:用于告知组件本身基于当前的props和state是否需要重新渲染组件,默认情况返回true
    3、render:类组件必须实现的方法,用于渲染DOM结构,可以访问组件state与prop属性
    4、getSnapshotBeforeUpdate:该周期函数在render后执行,执行之时DOM元素还没有被更新,目的在于获取组件更新前的一些信息,比如组件的滚动位置之类的,在组件更新后可以根据这些信息恢复一些UI视觉上的状态
    5、componentDidUpdate:可以根据前后的props和state的变化做相应的操作,如获取数据,修改DOM样式等
4、卸载阶段:
    componentWillUnmount:此方法用于组件卸载前,清理一些注册是监听事件,或者取消订阅的网络请求等,一旦一个组件实例被卸载,其不会被再次挂载,而只可能是被重新创建

4、说说你对React中虚拟dom的理解?

1、虚拟DOM用js对象的形式,来模拟页面dom的嵌套关系;
2、虚拟DOM是一棵虚拟的JavaScript对象树,画重点,”虚拟的“、”JS对象“,指的是它把真实的网页文档节点,虚拟成一个个的js对象,并以树型结构,保存在内存中。
3、实现原理:通过JS模拟网页文档节点,生成JS对象树(虚拟DOM),然后再进一步生成真实的DOM树,再绘制到屏幕。如果后面有内容发生改变,React会重新生成一棵全新的虚拟DOM树,再与前面的虚拟DOM树进行比对diff,把差异的部分打包成patch,再应用到真实DOM,然后渲染到屏幕浏览器。

5、 说说你对react hook的理解?

1、Hook是React 16.8.0版本增加的新特性/新语法,可以让你在函数组件中使用 state 以及其他的 React 特性
常见的Hook:
2、useState:跟类组件中state类似,方便我们定义初始化的数据,接收两个参数,一个是初始化数据,另一个是修改数据的方法
3、useEffect:副作用函数,只有使用之后,才会产生副作用,他接受两个参数,一个是函数,另一个是要监听的数据,可以是[],表示只执行一次,也可以传参,传参之后只要当我们的数据发生变化时才会触发,如果不写,那么发生一次变化就会执行一次
4、useMemo:数据缓存,当我们进行组件通信时,如果我们父组件中的数据发生变化,那么我们的子组件也会随着进行更新,不管我们更新的数据是否跟我们的子组件的数据有关系,他都会进行更新操作,这时候,就会存在更新性能的浪费,我们可以使用ysememo来进行缓存,减少不必要的更新操作,他的缓存的参数是一个字符串,如果是一个函数的话,那么我们的usememo就会失效,这时候就需要使用useCallback进行数据的缓存操作
5、useRef:可以监听我们的输入框数据的变化,获取输入框中的值

6、 React组件之间如何通信?

React组件通信就是值组件通过某种方式来传递信息以达到某个目的
    方式:
    1、父组件向子组件传递信息:由于react数据流动是单向的,父组件在调用子组件时,只需要在子组件标签内传递参数,子组件通过props属性接收
    2、子组件向父组件传递信息;父组件向子组件传递一个函数,然后通过这个函数的回调,拿到子组件传过来的值
    3、兄弟组件之间的传递:父组件作为中间层来实现数据的互通,通过使用父组件传递
    4、父组件向后代组件传值:使用context提供的组件通信的一种方式,可以实现数据的共享,Provider组件通过value属性传递给后代组件
    5、非关系组件传递数据:将数据进行一个全局的资源管理,从而实现组件间的通信功能,例如redux
​

7、 说说你对受控组件和非受控组件的理解?应用场景?

1、受控组件:在React中,可变状态通常保存在组件的状态属性中,并且只能使用 setState() 更新,而呈现表单的React组件也控制着在后续用户输入时该表单中发生的情况,以这种由React控制的输入表单元素而改变其值的方式,称受控组件。简单说就是收到setState的控制,组件的状态全程响应外部数据
2、非受控组件:表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示最新值(使用 ref从DOM获取表单值),不受setState的控制,一般在初始化的时候接收外部的数据,然后自己在内部存储其自身的状态
应用场景:
    1、受控组件:强制输入格式、一个数据的多个输入、动态输入、提交时的验证问题
    2、非受控组件:一次性取值(提交时)、提交时的验证

8、 说说Connect组件的原理是什么?

1、Connect连接redux和react,包裹在我们容器组件外层,接收上边的Provider提供的store里state和dispatch,传给一个构造函数,返回一个对象,以属性的形式传递给我们的容器组件
2、Connect是一个高阶函数,首先传入mapStateToProps、mapDispatchToProps,然后返回Component函数,然后将真正的Component作为参数传入,从而返回一个新的组件

9、说说react 中jsx语法糖的本质?

1、Jsx的本质就是函数React.createElement的语法糖,所有的jsx语法都会最终经过babel.js转化为React.createElement这个函数调用
2、三个参数:type是指的当前的元素类型,config是jsx属性,以对象的属性和值的形式存储,children是存放在标签中的内容
3、jsx写法:必须引入babel并且设置script标签的type为text/bable babel:将jsx转化为React.createElement()这种函数的调用

10、说说你对redux中间件的理解?常用的中间件有哪些?实现原理?

1、Redux中间件就是介于应用系统和系统软件之间的一类软件,使用系统软件提供的基础服务,衔接网络上应用系统的各个部分或者是不同的应用,达到资源共享,功能共享的目的
2、常用的中间件:redux-thunk用于异步操作、redux-logger用于日志的记录
​
实现原理:所有中间件被放进一个数组中嵌套执行,判断传递过来的数据类型,最后执行store.dispatch,中间件内部middleware API可以拿到getstate和dispatch方法。

11、说说AMD、CMD、commonJS模块化规范的区别?

1、AMD:这种规范就是异步的加载模块,先定义所有依赖,然后加载完成后的回调函数中执行require([‘xxx’],function(){})
2、CMD:依赖就近原则,用的时候在写 function(require,exports,module){require(‘xxx’)}
3、commonJS:加载模块使用require(‘xxx’)
区别:
    1、AMD和CMD最大的区别就是对依赖模块的执行时机处理不同,二者均为异步加载模块
    2、AMD依赖前置,js可以方便的知道依赖模块是谁,立即加载,CMD就近依赖,需要把模块变为字符串解析
    3、commonJS是所有代码都运行在模块作用域,不会污染全局作用域,模块加载是同步的,只有加载完成后才可以执行后边的操作,requeire的值是被输出的值的拷贝,模块内容变化也不会影响这个值

12、说说package.json中版本号的规则?

^:只会执行不更改左边非零数字的更新
~:如果写入的是~0.13.0,则当运行npm update时i,会更新到补丁版本
>:接收高于指定版本的任何版本
>=:接受等于或者高于指定版本的任何版本
<=:接受等于或者低于指定版本的任何版本
<:接受低于指定版本的任何版本
=:接收确切的版本
-:接受一定范围的版本
||:组合集合
无符号:接收指定的特定版本
Latest:使用可以用的最高版本

13、说说React jsx转换成真实DOM的过程?

1、使用React.createElement或jsx编写react组件,实际上所有的jsx代码最后都会转换成React.ccreateElement(...),babel帮助我们完成转换的过程
2、createElement函数对于key和ref等特殊的props进行处理,并获取defaultProps对默认的props进行赋值,并且对传入的子节点进行处理,最终构成一个虚拟DOM对象
3、ReactDOM.render将生成好的虚拟DOM渲染到指定的容器上,其中采用了批处理,事务等机制并且对特定的浏览器进行了性能优化,最终转换为真实DOM

14、说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?

1、React-redux是官方react UI绑定层,允许React组件从redux存储中读取数据,并将操作分派到存储以更新的状态。提供了connect,Provider等API,帮助我们连接react和redux,实现的逻辑会更加的严谨高效
2、@reduxjs/tookit是对Redux的二次封装,开箱即用的一个高效的Redux开发工具,使得创建store,更新store
    区别:
    1、reduxjs/tookit相对于react-redux来说比较方便,集成了redux-devtools-extension,不需要额外的配置,非常方便
    2、reduxjs/tookit集成immutable-js的功能,不需要安装配置使用,提升了开发效率
    3、reduxjs/tookit集成了redux-thunk的功能
    4、reduxjs/tookit将types、actions、reducers放在一起组成了全新的slices,简化了我们的使用

15、 React render方法的原理,在什么时候会触发?

Render函数在react中有两种形式,在类组件中指的是render方法,在函数组件中,指的是函数组件本身,在render中我们会编写jsx,jsx通过babel编译后就会转化为我们熟悉的js格式,在render过程中,React将新调用的render函数返回的树与旧版本的树进行比较,决定如何更新DOM,然后进行diff比较,更新DOM树
    触发时机:
        1、类组件调用setState修改状态时;
        2、函数组件通过useState Hook修改状态时;
        3、类组件重新渲染时;
        4、函数组件重新渲染时;
​

16、 React性能优化的手段有哪些?

1、通过shouldComponentUpdate:对比state和props,确定是否重新渲染,默认返回true,不希望渲染返回false
2、PureComponent:通过对比state和props间比较结果来实现
3、React.memo:缓存组件的渲染,避免不必要的更新(只能用于函数组件)
4、避免使用内联函数:每次调用render时就会重新渲染一个新的函数,在组件内部创建一个函数,将事件绑定到该函数本身
5、使用React Fragments避免额外标记
6、使用Immutable:减少渲染的次数
7、懒加载组件:使用suspense和lazy组件实现代码拆分功能
8、事件绑定方式
9、服务端渲染

17、如何通过原生js实现一个节流函数和防抖函数?

1、函数节流: 频繁触发,但只在特定的时间内才执行一次代码
2、函数防抖: 频繁触发,但只在特定的时间内没有触发执行条件才执行一次代码
3、区别:两者区别在于函数节流是固定时间做某一件事,比如每隔1秒发一次请求。而函数防抖是在频繁触发后,只执行一次(两者的前提都是频繁触发)
4、节流应用场景:函数节流的应用场景一般是onrize,onscroll等这些频繁触发的函数,比如你想获取滚动条的位置,然后执行下一步动作
5、防抖应用场景:输入框搜索自动补全事件,频繁操作点赞和取消点赞等等,这些应用场景,也可以通过函数节流来实现,频繁操作点赞和取消点赞,因此需要获取最后一次操作结果并发送给服务器

18、说说你对koa中洋葱模型的理解?

1、在koa中,中间件被next()方法分成两部分,next方法上面会先执行,下边部门会在后续中间件执行全部结束后再执行,
2、在洋葱模型中,每一层相当于一个中间件,用来处理特定的功能,比如错误处理,session处理等,其处理顺序先是next()请求,然后执行next()函数,最后是next()响应,也就是说每一个中间件都有两次处理时机。
3、洋葱模型的核心原理是借助componse方法

19、说说如何借助webpack来优化前端性能?

1、压缩代码:删除多余的代码、注释、简化代码的写法等等⽅式。可以利⽤webpack的 UglifyJsPlugin 和 ParallelUglifyPlugin 来压缩JS⽂件
2、利⽤ cssnano (css-loader?minimize)来压缩css
3、利⽤CDN加速: 在构建过程中,将引⽤的静态资源路径修改为CDN上对应的路径。可以利⽤webpack对于 output 参数和各loader的 publicPath 参数来修改资源路径
4、Tree Shaking: 将代码中永远不会⾛到的⽚段删除掉。可以通过在启动webpack时追加参数 
--optimize-minimize 来实现
5、Code Splitting: 将代码按路由维度或者组件分块(chunk),这样做到按需加载,同时可以充分利⽤浏览器缓存
6、提取公共第三⽅库: SplitChunksPlugin插件来进⾏公共模块抽取,
7、利⽤浏览器缓存可以⻓期缓存这些⽆需频繁变动的公共代码

20、 说说你对webSocket的理解?

1、理解:webSocket是一种网络传输协议,位于OSI模型的应用层,可在单个TCP连接上进行双工通信,能够更好的节省服务器资源和带宽并达到实时通讯。客户端和服务器只需要完成一次握手,两者之间就可以创建出持久性的连接,并进行双向数据传输
2、特点:
    1、全双工(通信允许数据在两个方向上同时传输)
    2、二进制帧(采用二进制帧的结构,语法语义与HTTP完全不兼容,更侧重与实时通信)
    3、协议名(引入ws和wss分别代表明文和密文的websoket协议,且默认端口使用80或者443,几乎与http完全一致)
    4、握手(有一个握手过程然后正式收发数据)

21、bind、call、apply 区别?如何实现一个bind?

Call、bind、apply作用都是改变函数执行时的this指向
    区别:
    1、apply接收两个参数,第一个参数是this指向,第二个参数是函数接收的参数,以数组的形式传入
    2、Call方法的第一个参数也是this指向,后面传入的是一个参数列表
    3、Bind方法和call相似,第一个参数也是this指向,后边传入的也是一个参数列表(这个列表可以分多次传入),bind是返回绑定this之后的函数,apply和call是立即执行
如何实现一个bind:修改this指向,动态的传递参数,兼容new关键字
使用function.prototype.mybind = function(context){
    判断调用对象是否为函数
    If(typeof this !== ‘function’){throw new TypeError(“error”)}
    获取参数
    Const args = [...arguments].slice(1)
    Fn = this
    Return function Fn(){
根据调用方式,传入不同的绑定值
    Return fn.apply(this instanceof Fn ? new fn(...arguments):context,args.concat(...arguments))
}
}

22、 什么是防抖和节流?有什么区别?如何实现?

节流:n秒内只允许一次,如果在n秒内重复触发,只有一次生效
防抖:n秒后在执行该事件,如果在n秒内被重复触发,则重新计时
区别:
    1、函数防抖在一段连续操作结束以后,处理回调,利用clearTimeout和setTimeout实现;函数的节流,在一段连续操作中,每一段事件只执行一次,频率较高的事件中使用来提高性能
    2、函数防抖关注一定时间连续触发的时间,只在最后执行一次,而函数节流一段时间内只执行一次

23、怎么理解回流跟重绘?什么场景下会触发?

回流:布局引擎会根据各种样式计算每个盒子在页面上的位置和大小
重绘:当计算好盒模型的位置、大小以及其他属性后,浏览器根据每个盒子的特性进行重新绘制
触发时机:
    回流:添加或删除可见的DOM元素;元素位置发生变化、元素的尺寸发生变化、内容发生变化,比如文本变化或者图片被代替;页面一开始渲染的时候、浏览器的窗口尺寸变化
    重绘:触发回流时一定触发重绘,另外还有颜色的修改、文本方向的修改、阴影的修改等

24、VUE路由的原理?

路由分为两种模式:hash模式和history模式
原理:
    Hash:url中的hash值是客户端的一种状态,当向服务器端发送请求时,hash部分不会被发送,hash的改变,都会在浏览器的访问历史中增加一个记录,因此我们可以通过浏览器的回退,前进按钮控制hash的切换,通过改变hash值来进行页面的跳转
    History:在history的模式下,前端的url必须和实际向后端发起请求的url一致,pushState和replaceState两个API来操作实现url的变化,可以在页面不刷新的情况下,操作浏览器的历史记录,也可以使用popstate来监听url的变化,从而实现页面的跳转功能

25、你了解vue的diff算法吗?说说看?

Diff算法是一种通过同层的树节点进行比较的高效算法,有两个特点:比较只会在同层级中进行比较,变化跨层级进行比较;在diff的比较过程中,循环从两边向中间进行比较
原理:
    1、当数据发生变化时,set方法会调用Dep.notify通知所有订阅者watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图
    2、每次diff都会调用updateChildren方法来比较,然后层层递归下去,直到将旧Vnode和新Vnode中的所有子节点对比完。domDiff的过程更像是两个树的比较,每找到相同节点时,都会一层层的往下比较它们的子节点,是一个深度递归遍历比较的过程

26、说说你对keep-alive的理解?

1、Keep-alive是vue中的内置组件,能在组件切换的过程中将状态保留在内存中,防止重复渲染DOM,也就是所谓的组件缓存
2、Keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁他们
3、Keep-alive可以设置props属性:include字符串或正则表达式,只有当名称匹配时才会被缓存;
4、exclude:字符串或者正则表达式,任何名称匹配的组件都不会被缓存,max数字,最多可以缓存多少组件实例

27、什么是响应式设计?响应式设计的基本原理是什么?如何做?

    响应式网站设计:是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整
    响应式设计的基本原理:是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有meta声明viewport
实现方式:
    1、媒体查询:设置不同类型的媒体条件,并根据对应的条件,给相应符合条件的媒体调用相对应的样式表
    2、百分比:当浏览器的宽度或者高度发生变化时,通过百分比单位,可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果
    3、vw/vh:vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一
    4、rem:rem是相对于根元素html的font-size属性,默认情况下浏览器字体大小为16px,此时1rem = 16px

28、如何解决跨域问题?

出于浏览器的同源策略限制产生的跨域问题,浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
解决:
    1、jsonp跨域
    2、Nginx反向代理
    3、Php端修改header
    4、Document.domain实现不同window之间的相互访问和操作
    5、Cors解决跨域
    6、Window.name利用了浏览器的特性来做到不同域之间的数据传递;

29、如何优化webpack打包速度?

1、尽可能的减少模板上使用loader,减少loader被频繁执行的频率
2、跟上开发技术的迭代:node,yarn,npm,webpack保持最新最稳定的版本
3、Plugin尽量少并可靠,选择性能好,官方推荐的插件
4、Resolve参数的合理配置
5、使用DllPlugin提升webpack的打包速度
6、控制包文件的大小
7、Thread-loader、parallel-webpack、happypack多进程打包

30、SPA首屏加载速度慢的怎么解决?

首屏加载:浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容
    1、减小入口文件体积:,把不同路由对应的组件分割成不同的代码块,待路由被请求的时候会单独打包路由,使得入口文件变小,加载速度大大增加
    2、静态资源本地缓存:采用http缓存设置响应头,采用service worker离线缓存,合理利用localstroage
    3、UI框架按需加载
    4、组件重复打包
    5、图片资源的压缩
    6、开启GZip压缩
    7、使用SSR:服务端渲染,组件或页面通过服务器生成html字符串,再次发送到浏览器

31、说说react router有几种模式?实现原理?

两种模式:hash模式和history模式
    Hash原理:hash 值改变,触发全局 window 对象上的 hashchange 事件。所以 hash 模式路由就是利用 hashchange 事件监听 URL 的变化,从而进行 DOM 操作来模拟页面跳转
    History原理:利用了 HTML5 History Interface 中新增的 pushState () 和 replaceState () 方法。 

32、从浏览器地址栏输入url到显示页面的步骤?

1、浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP,向服务器发起请求;
2、服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图像等)
3、浏览器对加载到的资源(HTML、JS、CSS 等)进行语法解析,建立相对应的内部数据结构(如 HTML 的 DOM);
4、载入解析到的资源文件,渲染页面,完成。

33、说说JavaScript中的数据类型?存储上的差别?

基本类型:number、string、Boolean、undefined、null、symbol
复杂类型:object、array、function
存储的区别:
    1、位置不同:基本数据类型存储在栈中,引用类型的对象存储与堆中
    2、声明变量时内存地址分配:简单类型的值栈中存放的是对应的值,引用数据类型栈中存放的是指向堆的内存地址
    3、简单基本类型赋值是生成相同的值,两个对象对应不同的地址,复杂类型赋值将保存对象的内存地址赋值给另一个变量,两个变量指向堆内存中的同一个对象

34、说说对React Hooks的理解?解决了什么问题?

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性
解决问题:
    1、难以重用和共享组件中与状态相关的逻辑
    2、由于业务变动,函数组件不得不改为类组件
    3、逻辑复杂的组件难以开发和维护,当组件需要处理多个不相关的local state时,每个生命周期函数中肯能会包含各种互不相关的逻辑
    4、类组件在基于现有工具的优化上存在的些许问题
    5、hooks的出现,使函数组件的功能得到了扩充,拥有了类组件相似的功能,在我们日常使用中,使用hooks能够解决大多数问题,并且还拥有代码复用机制,因此优先考虑hooks

35、说说你对promise的了解?

    1、Promise是最早由社区提出和实现的一种解决异步编程的方案,比其他传统的解决方案(回调函数和事件)更合理和更强大。
    2、promise是为解决异步处理回调金字塔问题而产生的
    3、Promise对象的状态不受外界影响,Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending变成fulfilled或者由pending变成rejected
    4、Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
    5、Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

36、 说说webpack中常见的Loader?解决了什么问题?

1、loader 用于对模块的源代码进行转换,在import或加载模块时预处理文件
2、Style-loader:将css添加到DOM的内联样式标签style中
3、Caa-loader:将css文件通过require的方式引入,并且返回css代码
4、Less-loader:处理less
5、Sass-loader:处理sass
6、Postcss-loader:处理postcss来处理css
7、File-loader:分发文件到output目录并返回相对路径
8、Html-minify-loader:压缩html

37、说说 React 性能优化的手段有哪些?

1、通过shouldComponentUpdate:对比state和props,确定是否重新渲染,默认返回true,不希望渲染返回false
2、PureComponent:通过对比state和props间比较结果来实现
3、React.memo:缓存组件的渲染,避免不必要的更新(只能用于函数组件)
4、避免使用内联函数:每次调用render时就会重新渲染一个新的函数,在组件内部创建一个函数,将事件绑定到该函数本身
5、使用React Fragments避免额外标记
6、使用Immutable:减少渲染的次数
7、懒加载组件:使用suspense和lazy组件实现代码拆分功能
8、事件绑定方式
9、服务端渲染

38、 说说 React中的setState执行机制?

    一个组件显示形态就可以由数据状态和外部参数决定,而数据状态就是state,当需要修改值的状态就通过seState来改变,从而达到更新组件内部数据的作用
    SetState更新数据时就可以分为同步和异步更新,在组件生命周期或react合成事件中,setState就是异步的,在setTimeout或原生的dom事件中,setState就是同步的

39、 Vue组件之间的通信方式都有哪些?

这类问题 首先分类 表明了解的比较多 具体就没说完 或者漏了 面试官也不会计较很多
组件通信的四大类 父与子 子与父 子与子 跨层级
在细说各种方式 加入自己的理解
1、props和$emit父组件向子组件传递数据是通过prop传递的,子组件传递数据给父组件是通过$emit触发事件
2、$attrs和$listeners
3、中央事件总线 bus上面两种方式处理的都是父子组件之间的数据传递,而如果两个组件不是父子关系呢?这种情况下可使用中央事件总线的方式。新建一个Vue事件bus对象,然后通过bus.$emit触发事件,bus.$on监听触发的事件。
4、provide和inject父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深只要调用了
inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。
5、v-model:父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值
6、$parent和$children
说说vue中Key值的作用
说说vue中的虚拟dom和diff算法
7、boradcast和dispatch
8、vuex处理组件之间的数据交互 如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。

40、 说说React生命周期中有哪些坑?如何避免?

1、  getDerivedStateFromProps 容易编写反模式代码,使受控组件和非受控组件区分模糊
2、  componentWillMount 在 React 中已被标记弃用,不推荐使用,主要的原因是因为新的异步架构会导致它被多次调用,所以网络请求以及事件绑定应该放到 componentDidMount 中
3、  componentWillReceiveProps 同样也被标记弃用,被 getDerivedStateFromProps 所取代,主要原因是性能问题。
4、  shouldComponentUpdate 通过返回 true 或者 false 来确定是否需要触发新的渲染。主要用于性能优化。
5、  componentWillUpdate 同样是由于新的异步渲染机制,而被标记废弃,不推荐使用,原先的逻辑可结合 getSnapshotBeforeUpdate 与 componentDidUpdate 改造使用。
6、如果在 componentWillUnmount 函数中忘记解除事件绑定,取消定时器等清理操作,容易引发 bug。如果没有添加错误边界处理,当渲染发生异常时,用户将会看到一个无法操作的白屏,所以一定要添加

41、调和阶段setState干了什么?

1、  代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。
2、  经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
3、  在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染;
4、  在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

42、说说redux的实现原理是什么,写出核心代码?

1.  将应用的状态统一放到state中,由store来管理state。
2.  reducer的作用是返回一个新的state去更新store中对用的state
3.  按redux的原则,UI层每一次状态的改变都应通过action去触发,action传入对应的reducer 中,reducer返回一个新的state更新store中存放的state,这样就完成了一次状态的更新
4.  subscribe是为store订阅监听函数,这些订阅后的监听函数是在每一次dipatch发起后依次执行
5.  可以添加中间件对提交的dispatch进行重写

43、 React合成事件的原理?

    react中的事件都是合成事件,不是把每一个dom的事件绑定在dom上,而是把事件统一绑定到document中,触发时通过事件冒泡到document进行触发合成事件,因为是合成事件,所以我们无法去使用e.stopPropagation去阻止,而是使用e.preventDefault去阻止。
    合成事件:循环所有类型的eventPlugin,对应每个事件类型,生成不同的事件池,如果是空,则生成新的,有则用之前的,根据唯一key获取到指定的回调函数,再返回带有参数的回调函数。

44、 为什么react元素有一个$$type属性?

目的是为了防止 XSS 攻击。
    因为 Synbol 无法被序列化,所以 React 可以通过有没有 $$typeof 属性来断出当前的 element 对象是从数据库来的还是自己生成的。 如果没有 $$typeof 这个属性,react 会拒绝处理该元素。

45、说说你对redux中间件的理解?常用的中间件有哪些?实现原理?

    Redux中间件就是介于应用系统和系统软件之间的一类软件,使用系统软件提供的基础服务,衔接网络上应用系统的各个部分或者是不同的应用,达到资源共享,功能共享的目的
常用的中间件:redux-thunk用于异步操作、redux-logger用于日志的记录
实现原理:所有中间件被放进一个数组中嵌套执行,判断传递过来的数据类型,最后执行store.dispatch,中间件内部middleware API可以拿到getstate和dispatch方法。
​

46、说说你对事件循环event loop的理解?

JavaScript是一门单线程的语言,意味着同一时间内只能做一件事情,但是并不意味着单线程就是阻塞,而实现单线程非阻塞的方法就是事件循环
所有的任务都分为同步任务、异步任务。
    同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行
    异步任务:ajax网络请求、setTimeout定时器函数
    同步任务进⼊主线程,即主执⾏栈,异步任务进⼊任务队列,主线程内的任务执 ⾏完毕为空,会去任务队列读取对应的任务,推⼊主线程执⾏。那么上述过程的不断重复就称为事件循环。

47、前端跨域的解决方案?

1、  Jsonp跨域:利用script标签没有跨域限制,src属性发送带有callback参数的get请求,服务端接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从前端拿到数据
2、  跨域资源共享:允许浏览器向跨源服务器发出XMLhttpRequest请求,克服了ajax只能同源使用的限制
3、  Nginx代理跨域
4、  Node.js中间件代理跨域
5、  Localtion.hash+iframe跨域

48、数组常用方法及作用,至少15个?

1、  Array.join():将数组中的元素连接成一个字符串
2、  Array.push(): 将新元素追加到数组的最后一个位置中
3、  Array.splice(): 根据数组的下标在数组中的任意位置添加或者删除元素 形参1代表根据数组的下标,从第几个元素开始添加或删除。
4、  Array.slice(): 根据数组下标裁切出一个新的数组
5、  Array.forEach(): 该数组方法接收三个形参,第一个形参为数组中的每一项; 第二个形参为数组中每一项的索引下标; 第三个形参为数组本身。
6、  Array.map():循环,分配内存空间存储新数组并返回
7、  Array.filter(): 创建一个新的数组,新数组中的元素是通过filter方法检查后再指定数组中符合条件的所有元素并且它不会改变原始数组。
8、  Array.reduce(): 接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减(递增),最终为一个值。
9、  Array.every(): 检查所有数组值是否通过测试。
10、 Array.some():检查某些数组值是否通过测试
11、 Array.indexOf():在数组中搜索元素值并返回其位置
12、 Array.find():通过测试函数的第一个数组元素的值
13、 Array.pop():从数组中删除最后一个元素
14、 Array.shift():删除首个数组元素,并把所有的其他元素位移到哦更低的索引
15、 Array.unshift():在开头向数组添加新元素,并反向位移旧元素

49、说说你对vue中mixin的理解?

1、  Mixin是面向对象程序设计语言中的类,提供了方法的实现,其他类可以访问mixin的方法而不必成为其子类
2、  Vue中的mixin是一种非常灵活的方式,用来分发vue组件的可复用功能
3、  本质上就是一个js对象,可以包含组件中的任意功能选项,比如说data、components、methods、created等
4、  将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来

50、for...in循环和for...of循环的区别?

1、  For in 和 for of 都是可以用于遍历
2、  For in 遍历的是数组的索引index;for of 遍历的是数组的元素值
3、  For in 更适合遍历对象,当然也可以遍历数组,但是会存在一些问题;for of 可以遍历数、数组对象、字符串等拥有迭代器对象的集合
4、  For in 会遍历数组的所有可枚举属性,包括原型;For of 遍历的只是数组内的元素,不包括原型属性和索引
5、  For in 总是得到对象的key或数组、字符串的下标;for of得到的对象的value或数组、字符串的值

51、Js数据类型判断都有哪几种方式?至少说出5种?它们的区别是什么?

1、  Typeof方法:返回表示数据类型的字符串,无论引用对象是什么类型,都返回Object
2、  Instanceof方法:由构造类型判断出数据类型
3、  Constructor方法:是prototype对象上的属性,指向构造函数
4、  Object.prototype.toString方法:object对象返回的是[Object object],其他类型需要call,apply来调用
5、  Jquery.type()方法

52、说说你对Object.defineProperty()的理解?

    1、Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。IE8不兼容。
    2、对象中目前存在的属性描述符有两种形式:数据描述符和存取描述符
    3、数据描述符就是一个具有值的属性,该值可写也不可写;存取描述符是由get和set函数所描述的属性
    4、数据描述符有value和writeable,存取描述符是由一堆getter和setter函数功能来描述的属性,get返回值被用作属性值,set方法接受唯一参数,并将该参数的新值分配给该属性
    5、当使用get或者set方法时,不能使用writable和value两个属性,反之也一样

53、Vue中自定义指令的理解,应用场景有哪些?

1、  指令系统也是计算机硬件的语言系统,也叫机器语言,是系统程序员看到的计算机主要属性
2、  自定义指令也像组件那样存在的钩子函数,bind、inserted、update、componentUpdated、unbind
3、  场景:表单防止重复提交、图片的懒加载、一键copy的功能

54、说说javascript内存泄漏的几种情况?

1、  意外的全局变量
2、  忘记释放的计时器
3、  多处引用,当多个变量引用同一个对象时,有引用没有被清除
4、  闭包的不合理使用
5、  Console.log打印信息内存不被释放

55、大文件如何做断点续传?

由于大文件上传时,像服务器处理数据的能力、请求超时、网络波动等变量会影响我们的用户体验,那么我们就会需要对大文件上传做单独的处理
1、分片上传:就是将所需要上传的文件,按照一定的大小,将整个文件分割成多个数据块来进行分片上传,在上传完成以后再由服务器对上传的文件进行汇总整合成原始的文件
2、断点续传:断点续传指的是再下载或者上传时,将下载或者上传的任务认为的划分为几个部分,每一个部分采用一个线程进行上传或者是下载,如果碰到网络故障问题,用户可以从已经上传或者下载的部分开始继续上传或者下载未完成的部分,而没有必要从头开始上传下载,用户可以节省时间,提高速度。
3、断点续传一般实现方式有两种,服务器端返回,告知从哪开始;浏览器端自行处理。

56、原生js如何实现上拉加载下拉刷新?

上拉加载及下拉刷新都依赖于用户交互
1、上拉加载:
    1、scrollTop:滚动视窗的高度距离window顶部的距离,它会随着往上滚动而不断增加,初始值是0,它是一个变化的值
    2、clientHeight:它是一个定值,表示屏幕可视区域的高度;
    3、scrollHeight:页面不能滚动时也是存在的,此时scrollHeight等于clientHeight。    4、scrollHeight表示body所有元素的总长度(包括body元素自身的padding)
一个触底公式:scrollTop + clientHeight >= scrollHeight
2、下拉刷新:
下拉刷新的本质是页面本身置于顶部时,用户下拉时需要触发的动作
    1、监听原生touchstart事件,记录其初始位置的值,e.touches[0].pageY;
    2、监听原生touchmove事件,记录并计算当前滑动的位置值与初始位置值的差值,大于0表示向下拉动,并借助CSS3的translateY属性使元素跟随手势向下滑动对应的差值,同时也应设置一个允许滑动的最大值;
    3、监听原生touchend事件,若此时元素滑动达到最大值,则触发callback,同时将translateY重设为0,元素回到初始位置

57、说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别?

1、无缩放情况下,1个CSS像素等于1个设备独立像素
2、 设备像素由屏幕生产之后就不发生改变,而设备独立像素是一个虚拟单位会发生改变
3、 PC端中,1个设备独立像素 = 1个设备像素 (在100%,未缩放的情况下)
4、 在移动端中,标准屏幕(160ppi)下 1个设备独立像素 = 1个设备像素
5、 设备像素比(dpr) = 设备像素 / 设备独立像素
6、 每英寸像素(ppi),值越大,图像越清晰

58、谈谈你对BFC的理解?

1、  Bfc就是块级格式化上下文,它是页面中一块渲染区域,并且有一套属于自己的渲染规则
2、  Bfc的目的就是形成一个相对于外界的完全独立的空间,让内部的子元素不会影响到外部的元素
3、  Bfc就是页面上一个隔离的独立容器,容器里边的子元素不会影响外部的元素,反之也是
4、  Bfc的区域不会和浮动的元素区域重叠

59、说说TCP为什么需要三次握手和四次握手?

三次握手是为了建立可靠的数据传输通道,四次挥手则是为了保证等数据完成的被接收完再关闭连接。
1、  三次握手就是指建立一个TCP连接时,需要客户端和服务器总共发送三个包,主要作用就是为了确认双方的接受能力和发送能力是否正常,指定自己的初始化序列为后边的可靠性传送做准备
2、  四次挥手就是指tcp终止一个连接,需要四次挥手,当服务器在收到客户端断开连接的报文后,并不会立即关闭连接,而是先发送一个ACK包告诉客户端收到关闭连接的请求,只有当服务器的所有报文发送完毕以后,才断开连接

60、前端性能优化的手段有哪些?

1、  资源压缩合并,减少http请求
2、  图片优化,使用png体积小
3、  非核心代码异步加载
4、  利用浏览器缓存,资源文件存在本地,下次调用直接从缓存中取出
5、  使用CDN可以分配负载,提高性能
6、  DNS预解析
7、  开启Gzip代码压缩
8、  减少不必要的cookie

61、最少说出三种前端清除浮动的方法?

1、  额外标签法:在需要清除浮动的元素前面放一个空的div,并给这个空div设置属性 clear:both
2、  给父元素设置 overflow 属性 为 hidden 或者 auto
3、  :after利用伪元素清除有浮动的标签->在有浮动的标签前面添加一个块级元素

62、什么是强缓存和协商缓存?

浏览器首次请求资源后,需要再次请求时,浏览器会首先获取该资源缓存的header信息,然后根据Cache-Control和expires来判断该资源在本地缓存否过期。若没过期则直接从本地缓存中获取资源信息,浏览器就不再向服务器重新请求资源,如过期则需重新发送请求,重新缓存资源,更新缓存时间。
1、强缓存是利用http请求头中的Expires和Cache-Control两个字段来进行控制,用来表示资源的缓存时间。Expires是http1.0的规范,它的值是一个GMT格式的绝对时间字符串。
2、协商缓存是服务器用来确定缓存资源是否可用过期。因为服务器需要向浏览器确认缓存资源是否可用,二者要进行通信,而通信的过程就是发送请求,所以在header中就需要有专门的标识来让服务器确认请求资源是否可以缓存访问

63、说说你对栈、队列的理解?应用场景?

1、  栈(stack)又名堆栈,它是一种运算受限的线性表,限定仅在表尾进行插入和删除操作的线性表
2、  栈按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据,具有记忆作用
3、  队列时跟栈十分相似,队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作
4、  队列因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出
5、  场景:栈可以使用在函数调用和递归时,还有编译器在对输入的语法进行分析时;队列可以使用遍历一个二叉树时

64、说说你对git rebase 和git merge的理解?区别?

1、  在使用 git 进行版本管理的项目中,当完成一个特性的开发并将其合并到 master 分支时,会有两种方式是git merge和git rebase
2、  git rebase 与 git merge都有相同的作用,都是将一个分支的提交合并到另一分支上,但是在原理上却不相同
3、  git merge将当前分支合并到指定分支:git merge xxx;git rebase合并分支或合并到指定的commit上:git rebase -I 
4、  通过merge合并分支会新增一个merge commit,然后将两个分支的历史联系起来; rebase会将整个分支移动到另一个分支上,有效地整合了所有分支上的提交

65、说说git常用的命令有哪些?

1、  git status :时刻掌握仓库当前的状态,是否进行了修改变化 
2、  git diff 小说.txt :查看修改的内容操作
3、  git reflog :查看版本号
4、  git log :查看提交历史
5、  git reset --hard 版本号 :穿梭到那个版本号
6、  git checkout -- 小说.txt:可以丢弃工作区的修改
7、  rm 文件名:删除文件(没有提交至工作区的文件)
8、  git rm 文件名:删除版本库中的文件
9、  git branch dev :创建dev分支
10、 git branch -a :查看分支以及当前处于哪个分支
11、 git checkout dev :切换到dev分支
12、 git merge dev:将当前分支与dev分支进行合并

66、Vue组件通信?

组件通信指的是发送者通过某种媒体以某种格式来传递信息到收信者以达到某个目的
分类:父子组件之间的通信、兄弟组件之间的通信、祖孙与后代组件之间的通信、非关系组件间之间的通信
vue中8种常规的通信方案:
    1、通过 props 传递:子组件设置props属性,定义接收父组件传递过来的参数,父组件在使用子组件标签中通过字面量来传递值
    2、通过 $emit 触发自定义事件:子组件通过$emit触发自定义事件,$emit第二个参数为传递的数值,父组件绑定监听器获取到子组件传递过来的参数
    3、使用 ref:父组件在使用子组件的时候设置ref,父组件通过设置子组件ref来获取数据
    4、EventBus:创建一个中央事件总线EventBus,兄弟组件通过$emit触发自定义事件,$emit第二个参数为传递的数值
另一个兄弟组件通过$on监听自定义事件
    5、$parent 或$root:通过共同祖辈$parent或者$root搭建通信桥连
    6、attrs 与 listeners:设置批量向下传属性$attrs和 $listeners,包含了父级作用域中不作为 prop 被识别 (且获取) 的特性绑定 ( class 和 style 除外)。可以通过 v-bind="$attrs" 传⼊内部组件
    7、Provide 与 Inject:在祖先组件定义provide属性,返回传递的值,在后代组件通过inject接收组件传递过来的值
    8、Vuex:作用相当于一个用来存储共享变量的容器

67、说说你对vuex的理解?写出其原理的核心代码?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
vuex五大核心属性:state,getter,mutation,action,module
    1、state:存储数据,存储状态;在根实例中注册了store 后,用this.$store.state来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。
    2、getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
    3、mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
    4、action:包含任意异步操作,通过提交 mutation 间接更变状态。
    5、module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块。

68、props和state相同点和不同点?render方法在哪些情况下会执行?

不同点:
1.props不可以在组件内部修改,但state可以在组件内部修改
2.可以从父组件修改自组件的props,而不能从父组件修改自组件的state
相同点:
1.props和state都是导出HTML的原始数据。
2.props和state都是确定性的,如果我们写的组件为同一props和state的组合3.生成了不同的输出,那木我们肯定在哪里做错了
4.props和state都会触发渲染更新
5.props和state都是纯JS对象(用typeof来判断,结果都是object)
6.可以从父组件得到初始值props和state的初始值
render在哪些情况下执行?
    1、类组件调用setState修改状态时
    2、函数组件通过useState Hook修改状态时
    3、类组件重新渲染时
    4、函数组件重新渲染时

69、react新出来两个钩子函数是什么?和删掉的will系列有什么区别?

React新增的两个生命周期钩子函数?
1、getDerviedStateFromProps
作用:从props中获取衍生的state
2、getSnapshotBeforeUpdate
作用:在组件更新前获取快照,一般结合componentDidUpdate使用,getSnapBeforeUpdate中返回值将作为第三参数传递给componentDidUpdate
它和componentDidUpdate将render夹在中间,其实它的核心作用就是在render改变dom之前,记录更新前的dom信息传递给componentDidUpdate。
二、React新的生命周期去除的钩子函数?
1、componentWillMount
2、componentWillReceiveProps
3、componentWillUpdate
总结
    1、componentWillMount中可能需要做的事(一些数据初始化的操作就应该放在这个钩子中处理),constructor与componentDidMount也能做,甚至做的更好,此方法被废弃。
    2、componentWillReceiveProps实际行为与命名并不相符,由于不稳定性已由getDerivedStateFromProps代替;
    3、而componentWillUpdate同等理由被getSnapshotBeforeUpdate代替

70、CDN的特点及意义?

1、CDN 意为内容分发网络,是基于现有网络的智能虚拟网络,分布在世界各地的边缘服务器上。基本思路是避免互联网上可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输更快更稳定。
2、CDN 表示将数据从原始服务器复制到其他服务器。当用户访问时,他们可以在复制了数据内容的服务器上进行访问。其目的是使用户能够更快更好地获取所需内容,解决网络拥塞情况,提高用户访问网站的响应速度。CDN 加速成本低,速度快,适合访问量比较大的网站。
特点:
1.本地缓存加速:提高了企业网站(尤其是包含大量图片和静态页面的网站)的访问速度,大大提高了上述网站的稳定性。
2.镜像服务:消除了不同运营商之间互联瓶颈带来的影响,实现了跨运营商的网络加速,保证了不同网络的用户都能获得良好的接入质量。
3.远程加速:远程访问用户根据DNS负载均衡技术智能自动选择缓存服务器,选择最快的缓存服务器加速远程访问。
4.带宽优化:自动生成服务器的远程镜像缓存服务器。远程用户访问时,可以从缓存服务器读取数据,减少远程访问的带宽,分担网络流量,减轻原WEB服务器的负载。
5.集群抗攻击:广泛分布的CDN 节点加上节点间的智能冗余机制,可以有效防止黑客入侵,降低各种D.D.o.S攻击对网站的影响,同时保证更好的服务质量。

71、什么是闭包,应用场景是什么?

1、闭包就是能够读取其他函数内部变量的函数,说白了闭包就是个函数,只不过是处于其他函数内部而已。
2、由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数“
应用场景:
    1、模仿块级作用域:计时器的应用、打印一组li标签的下标
    2、埋点计数器:产品做一些常用的数据采集方法
    3、柯里化:将一个多参数的函数转换为单参数函数的办法

72、介绍一下你对浏览器内核的理解?

内核主要分为渲染引擎和js引擎
1、渲染引擎:负责取得网页的内容(HTML,XML和图像等),整理讯息(例如css),以及计算网页的显示方式,然后输出到显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不同。所有网页浏览器、电子邮件客户端以及它需要编辑、显示网络内容的应用程序都需要内核
2、JS引擎:解析和执行JavaScript来实现网页的动态效果
最开始渲染引擎和js引擎并没有区分很明确,后来js引擎越来越独立,内核就倾向与只指渲染引擎

73、 清除浮动的几种方式?各自的优缺点?

清除浮动:为了解决父元素因为子级元素浮动引起的内部高度塌陷的问题
方式:
1、额外标签法(在最后一个浮动标签后,新添加一个标签,给它设置clear:both;)优点:通俗易懂更加方便;缺点:添加无意义标签,语义化差
2、父级添加overflow属性(父元素添加overflow:hidden) 优点:代码简洁;缺点:内容增多时容易造成不会自动换行导致内容被隐藏掉,无法显示要溢出的元素
3、使用after伪元素清除浮动  优点:符合闭合浮动思想,结构语义化正确;缺点:IE6-7不支持伪元素
4、使用before和after双伪元素清除浮动  优点:代码更加简洁;缺点:用zoom:1触发haslayout

74、 如果需要手动写动画,你认为最小时间间隔是多久,为什么?

多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms。为了浏览器的渲染和用户体验的话,最小设置0.1-0.3s最佳

75、说说Real DOM和Virtual DOM的区别?优缺点?

1、Real DOM,真实DOM, 意思为文档对象模型,是一个结构化文本的抽象,在页面渲染出的每一个结点都是一个真实DOM结构
2、Virtual Dom,本质上是以 JavaScript 对象形式存在的对 DOM 的描述
3、创建虚拟DOM目的就是为了更好将虚拟的节点渲染到页面视图中,虚拟DOM对象的节点与真实DOM的属性一一照应
4、两者的区别如下:
    虚拟DOM不会进行排版与重绘操作,而真实DOM会频繁重排与重绘
    虚拟DOM的总损耗是“虚拟DOM增删改+真实DOM差异增删改+排版与重绘”,真实DOM的总损耗是“真实DOM完全增删改+排版与重绘”
优缺点?
    真实DOM的优势:易用
    缺点:
        1、效率低,解析速度慢,内存占用量过高
        2、性能差:频繁操作真实DOM,易于导致重绘与回流
    使用虚拟DOM的优势如下:
        1、简单方便:如果使用手动操作真实DOM来完成页面,繁琐又容易出错,在大规模应用下维护起来也很困难
        2、性能方面:使用Virtual DOM,能够有效避免真实DOM数频繁更新,减少多次引起重绘与回流,提高性能
        3、跨平台:React借助虚拟DOM, 带来了跨平台的能力,一套代码多端运行
    缺点:
        1、在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化
        2、首次渲染大量DOM时,由于多了一层虚拟DOM的计算,速度比正常稍慢

76、说说react的事件机制?

1、react自身实现了一套自己的事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等,虽然和原生的是两码事,但也是基于浏览器的事件机制下完成的。
2、React 上注册的事件最终会绑定在document这个 DOM 上,而不是 React 组件对应的 DOM(减少内存开销就是因为所有的事件都绑定在 document 上,其他节点没有绑定事件)
3、React 自身实现了一套事件冒泡机制,所以这也就是为什么我们 event.stopPropagation()无效的原因。
4、React 通过队列的形式,从触发的组件向父组件回溯,然后调用他们 JSX 中定义的 callback
5、React 有一套自己的合成事件 SyntheticEvent

77、说说你对fiber架构的理解?解决了什么问题?

React Fiber 是 Facebook 花费两年余时间对 React 做出的一个重大改变与优化,是对 React 核心算法的一次重新实现。
在react中,主要做了以下的操作:
    1、为每个增加了优先级,优先级高的任务可以中断低优先级的任务。然后再重新,注意是重新执行优先级低的任务
    2、增加了异步任务,调用requestIdleCallback api,浏览器空闲的时候执行
dom diff树变成了链表,一个dom对应两个fiber(一个链表),对应两个队列,这都是为找到被中断的任务,重新执行
    3、从架构角度来看,Fiber 是对 React核心算法(即调和过程)的重写
    4、从编码角度来看,Fiber是 React内部所定义的一种数据结构,它是 Fiber树结构的节点单位,也就是 React 16 新架构下的虚拟DOM

78、说说react diff的原理是什么?

1、跟Vue一致,React通过引入Virtual DOM的概念,极大地避免无效的Dom操作,使我们的页面的构建效率提到了极大的提升而diff算法就是更高效地通过对比新旧Virtual DOM来找出真正的Dom变化之处
运作流程主要分为三层:tree层、component层、element层
    1、tree层:tree层对于DOM节点的跨层级移动的操作忽略,只对相同层级的DOM节点进行比较,一旦发现节点不存在,直接删除该节点以及以下的所有子节点
    2、component层:遇到同一个类型的组件遵循tree diff,进行层级对比,遇到不同类型的组件,直接将这个不同的组件判断为脏组件,并且替换该组件之下的所有的子节点,当知道这个组件的虚拟DOM没有任何变化,就可以手动使用,shouldComponentUpdate来判断是否需要进行diff,进一步提升了diff效率和性能
    3、element层:低于同一层级,面对全新节点,可以实现插入的操作;面对多余的节点,执行删除操作;面对换位的节点,执行移动的操作

79、如何使用css实现一个三角形?

1、border:给定一个宽度和高度都为 0 的元素,其 border 的任何值都会直接相交,我们可以利用这个交点来创建三角形。也就是说,border属性是三角形组成的,如果想要一个指向右面的三角形,可以让 border 的左边可见,其他边都设置为透明:
2、linear-gradient:linear-gradient 需要结合 background-image 来实现三角形,下面就来逐步使用渐变实现一个三角形。
3、clip-path:clip-path 就是使用它来绘制多边形(或圆形、椭圆形等)并将其定位在元素内。实际上,浏览器不会绘制 clip-path 之外的任何区域,因此我们看到的是 clip-path 的边界。
4transform: rotate 配合 overflow: hidden 绘制三角形

80、shouldComponentUpdate有什么作用?

1、根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。
2、eact中props,state值的变化,会导致组件重新渲染。使用shouldComponentUpdate就是为了减少render不必要的渲染。 返回布尔值,然后做 Virtual DOM 比较,并得出是否需要做真实 DOM 更新

81、说说你对git rebase 和git merge的理解?区别?

1、在使用git管理版本的项目中,当完成一个特性的开发,并将其合并到master分支,就会使用到git rebase 和git merge
2、两个都有相同的作用:将一个分支的提交合并到另一个分支上,但是原理不一样
3、Git merge将当前分支合并到指定分支:git merge xxx;git rebase合并到指定的commit上:git rebase -I 
4、通过merge合并的分支会新增一个merge commit,,然后将两个分支的历史联系起来;rebase会将整个分支移动到另一个分支上,有效的整合了所有分支上的提交

82、在使用redux过程中,如何防止定义的action-type的常量重复?

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。
    Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

83、说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关系?

1、实际上它只是一层对真实DOM的抽象,以JavaScript对象(VNode节点)作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作时这棵树映射到真实环境上,创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应
2、通过JS模拟网页文档节点,生成JS对象树(虚拟DOM),然后再进行一步生成真实的DOM树,再绘制到屏幕。如果后面有内容发生改变,React会重新生成一棵全新的虚拟DOM树,再与前面的虚拟DOM树进行比对diff,把差异的部分打包成patch,再应用到真实DOM,然后渲染到屏幕浏览器。
在虚拟dom计算的时候diff和key之间有什么关系:
    1、React需要同时维护两棵虚拟DOM树:一棵表示当前的DOM结构,另一棵在React状态变更将要重新渲染时生成。React通过比较这两棵树的差异,决定是否需要修改DOM结构,以及如何修改。这种算法称作Diff算法。
    2、key 当同一层级的某个节点添加了对于其他同级节点唯一的key属性,当它在当前层级的位置发生了变化后。react diff算法通过新旧节点比较后,如果发现了key值相同的新旧节点,就会执行移动操作(然后依然按原策略深入节点内部的差异对比更新),而不会执行原策略的删除旧节点,创建新节点的操作。这无疑大大提高了React性能和渲染效率。

84、React的props.children使用map函数来遍历会收到异常显示,为什么?应该 如何遍历?

1、当前组件没有子节点数据类型就是undefined,
2、有一个子节点数据类型就是object 。
3、有多个子节点的时候才会是array ,只有在多个节点的时候才可以直接调用map方法,react资深提供了一个react.children.map()方法,可以安全遍历子节点对象。

85、谈谈你对immutable.js的理解?

1、Immutable.js就是react中用来做性能优化的
2、在react中使用immutable可以减少页面的一些不必要的渲染,不需要像react中进行深度对比而进行渲染
3、immutable可以直接快速的进行对比,完成渲染,提升了渲染的效率,降低了性能的消耗
4、Immutable不可改变的,在计算机中,即指一旦创建,就不能再被更改的数据
对 Immutable对象的任何修改或添加删除操作都会返回一个新的 Immutable对象
Immutable 实现的原理是 Persistent Data Structure(持久化数据结构):
    1、用一种数据结构来保存数据
    2、当数据被修改时,会返回一个对象,但是新的对象会尽可能的利用之前的数据结构而不会对内存造成浪费

86、redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的 实现原理是什么?

1、Redux-thunk这个中间件支持异步操作
2、执行异步的操作首先需要下载一个thunk,通过thunk来进行异步的一个操作,支持异步操作,可以使用dispatch和getState来进行数据的获取或状态
3、Redux是一个状态管理库,redux的核心是store,actions,reducers三个部分
4、通过dispatch发放到任务的actions中,在actions中返回一个promise对象,再通过dispatch派发到reducers中
5、在reducers中通过传递type和data来进行判读

87、redux中同步action与异步action最大的区别是什么?

1、同步action:执行了dispatch函数之后,对应的reducer纯函数立即得到执行,reducer执行完了之后,state立即就改变了,此时用store.getState函数,取到的是最新的state值;
2、异步action:原则上redux并没有提供异步action的处理方案,异步的action需要依赖第三方的中间件解决(如redux-thunk),dispatch了一个异步action(本质上是dispatch的一个函数)之后,目标state并不会立即响应,而是要看异步函数内部的逻辑,来决定state什么时候响应。
3、区别:
    首先区别redux和react-redux,redux是一个单独的模块,在其他框架中也能使用,而react-redux是为react管理数据而生。
    redux的设计思想:web应用是一个状态机,视图与状态是一一对应的,所有的状态,保存在一个对象里面

88、redux-saga和redux-thunk的区别与使用场景?

1、使用redux-thunk的代码,当我们返回的是函数时,store会帮我们调用这个返回的函数,并且把dispatch暴露出来供我们使用。对于redux-thunk的整个流程来说,它是等异步任务执行完成之后,我们再去调用dispatch,然后去store去调用reduces
2、使用了redux-saga的代码,当我们dispatch的action类型不在reducer中时,redux-saga的监听函数takeEvery就会监听到,等异步任务有结果就执行put方法,相当于dispatch,再一次触发dispatch。对于redux-saga的整个流程来说,它是等执行完action和reducer之后,判断reducer中有没有这个action
区别:
    1、redux-thunk和redux-saga处理异步任务的时机不一样。对于redux-saga,相对于在      2、redux的action基础上,重新开辟了一个 async action的分支,单独处理异步任务
    3、saga 自己基本上完全弄了一套 asyc 的事件监听机制,代码量大大增加,从我自己的使用体验来看 redux-thunk 更简单,和 redux 本身联系地更紧密。

89、为什么普通的for循环比forEach循环性能要高?

1、for循环就是通过下标,对循环中的代码反复执行,功能强大,可以通过index取得元素。处理比较复杂的处理的时候比较方便
2、forEach()循环方法用于调用数组的每个元素,并将元素传递给回调函数。foreach有的也叫做增强for循环,forEach其实是for循环的一个特殊简化版。forEach循环对于空的数组是不会执行回调函数的。
区别:
    1、遍历:for循环按照顺序进行遍历,forEach使用iterator迭代器遍历
    2、数据结构:for循环是随机访问元素,foreach是顺序链表访问元素
    3. 性能上:对于数组arraylist来说,是顺序表,使用for循环可以进行顺序访问,速度比较快;使用foreach循环会比for循环稍微慢一点。对于linedlist来说,是单链表,使用for循环每次都要从第一个元素读取next域来读取,速度非常慢;使用foreach可以直接读取当前的节点,数据较快。

90、移动端1像素的解决方案?

在移动端web开发中,UI设计稿中设置边框为1像素,前端在开发过程中如果出现border:1px,测试会发现在某些机型上,1px会比较粗,即是较经典的移动端1px像素问题
方案:
1、小数:0.5px,相信浏览器肯定是会慢慢支持的;目前而言,如果能用的话,可以hack一下;
2、阴影,border-img的方案不建议使用
3、背景图片和缩放可以在项目中配合使用,如单个线条使用缩放,四条框用背景图片模拟,额,如果要圆角的话,无能无力了
4、建议采用transform和伪类

91、弹性盒中的缩放机制是怎样?

1、弹性盒的项目设置flex-grow属性定义项目的放大比例,默认值为0,值越大,放大越厉害,且不支持负值;
2、而flex-shrink属性定义项目的缩小比列,默认值为1,数值越大,缩小越厉害,同样不支持负值;
3、flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间。他的默认值为auto,也就是项目的本来大小。

92、说说你对vue中mixin的理解?

1、  Mixin是面向对象程序设计语言中的类,提供方法的实现,其他1的类可以访问mixin中的方法而不必称为其子类
2、  Vue中mixin是用来分发vue组件的可复用功能
3、  本质上就是一个js对象,可以包含组件中的任意功能选项,比如说data、component、methods、created等
4、  将公用的功能以对象的方式传入mixins选项中,当组件使用mixins对象时,所有的mixins对象的选项都被混入该组件本身的选项中

93、for...in循环和for...of循环的区别?

For in和for of都属于遍历
1、for in 遍历时数组的索引index,for of遍历的时数组的元素值
2、for in更适合遍历对象,也可以遍历数组,会存在一些问题;for of 数组,对象等一些拥有迭代器对象的集合
3、for in 总是得到对象的键或者数组、字符串的下标;for of得到的对象的值或者数组、字符串的值

94、什么是发布订阅模式,写出其核心实现代码?

1、发布订阅模式:订阅者(Subsciber)通过事件注册(Subscribe)将订阅事件提交到调度中心(Topic),调度中心保存好订阅者的注册信息(回调函数),每当发布者(Publisher)发布事件的时候,通过事件发布(Publish)将发布的消息提交到调度中心,然后调度中心统一处理订阅者注册该事件的消息(执行注册时的回调函数)
2、实现:
    //实例化一个发布订阅模式,多个new,可以做到事件隔离,正常一个项目一个就够了
    const pub1 = new Pubsub()
    //调用 示例 
    pub1.topic("on-sleep)  //创建一个睡觉的订阅主题
    //同学1 订阅睡觉
    pub1.subscribe("on-sleep",(a)=>{
        console.log("sleep")
        console.log(a)
    })
    //同学2 订阅睡觉  回调不同
    pub1.subscribe("on-sleep",(a)=>{
        console.log("sleep2”)
        console.log(a)
    })
 
    setTimeout(()=>{
        //时间差不多了,通知他们该睡觉了!
        pub1.publish("on-sleep",{info:"该睡觉啦!"})
    },2000)

95、说一说你对视口的理解?

1、在一个浏览器中,看到的区域就是视口(viewport)
2、在PC端页面中,不需要对视口进行区分,因为布局视口和视觉视口是同一个
3、但在移动端,你布局的视口和可见的视口是不一样的因为移动端的网页窗口往往比较小,我们可能会希望一个大的网页在移动端可以完整的显示;
4、所以在默认情况下,移动端的布局视口是大于视觉视口的
5、所以在移动端,我们将视口分成三种情况
    1、布局视口(layout viewport)
    2、视觉视口(visual layout)
    3、理想视口(ideal layout)

96、说说你对useEffect的理解,可以模拟哪些生命周期?

1、使用钩子函数useEffect可以实现组件的副作用。useEffect(希望执行的动作, [组件状态的列表]);第二个参数用来处理useEffect调用的时机,是一个数组,数组内是组件状态的列表。
2、useEffect模拟componentDidMount:当useEffect的第二个参数传入空列表时,相当于模拟生命周期函数componentDidMount。这个副作用仅在组件第一次挂载ui的时候调用一次。用它来模拟组件初次挂载时,访问api、获得数据:
3、useEffect模拟componentDidUpdate:如果在使用useEffect时不带上第二个参数,就相当于模拟了生命周期函数componentDidUpdate。每次渲染结束的时候都会被调用。
4、useEffect模拟componentWillUnmount,在useEffect中返回一个函数用于模拟component WillUnMount

97、说说React中setState和replaceState的区别?

1、setState用于设置状态对象
2、两个参数:nextState,将要设置的新状态,该状态会和当前的state合并;callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用。
3、合并nextState和当前state,并重新渲染组件。setState是React事件处理函数中和请求回调函数中触发UI更新的主要方法。
4、replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除
5、两个参数:nextState,将要设置的新状态,该状态会替换当前的state。callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。
​
-----------------------------------------------------------------------
1. setState 是修改其中的部分状态,相当于 Object. assign,只是覆盖,不会减少原来的状态;
2. replaceState 是完全替换原来的状态,相当于赋值,将原来的 state 替换为另一个对象,如果新状态属性减少,那么 state 中就没有这个状态了。

98、说说react中onClick绑定后的工作原理?

当组件元素绑定onClick事件之后:
1、react会对事件先进行注册,将事件统一注册到document上
2、根据组件唯一的表示key来对事件函数进行存储
3、统一的指定,dispatchEvent回调函数
4、存储事件回调:react会将click这个事件统一存放在一个对象中,回调函数中存储采用键值对的方式存储在对象中,key是组件唯一标识id,value对应的事件就是回调函数,通过组件的key就能回到相对应的函数了。

99、什么是垂直外边距合并?说说合并后的几种情况?

1、垂直外边距合并:当两个存志外边距相遇时,将形成一个外边距,合并后的外边距高度等于两个发生合并的外边距的高度中的较大者
2、注意:只有普通的文档流中的块级元素的垂直外边距才会发生外边距合并,行内框,浮动框或者绝对定位之间的外边距不会合并
情况:
1、当相邻的元素垂直外边距合并时候:如果上边的元素有下外边距,下边的元素有上外边距,那么他们之间的垂直间距不是bottom和top之间的和,而是两者中较大者,这种现象被称为外边距塌陷
2、当嵌套块元素垂直外边距合并:如果父元素没有上内边距以及边框,那么父元素上外边距会与子元素的上外边距发生合并,合并后的外边距为两者中的较大者,就是父元素的上外边距为0,也会合并
解决方法:可以为父元素定义1像素的上边框或上内边距

100、useEffect的依赖为引用类型如何处理?

1、使用 ‘use-deep-compare-effect’ :他可以进行深比较,使用方法也很简单, import useDeepCompareEffect from ‘use-deep-compare-effect’ 之后用useDeepCompareEffect 替换掉 原有的 useEffect 即可。
2、也可以使用 useRef这个钩子来解决上述问题,useRef的特性是跨渲染周期保存数据
3、用useRef保存了之前的数据, useEffect中的依赖以然为引用类型, 每次obj发生改变都会调用执行函数,但是执行函数中多了一个判断, prevObj是上一次渲染时obj的值, 用prevObj中的某个key与此次obj中的某个key做对比,满足条件后做其他操作

101、知道react里面的createPortal么,说说其使用场景?

1、Portal ,将子节点渲染到存在于父组件以外的 DOM 节点。
2、ReactDOM.createPortal(child, container)
第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或 fragment。第二个参数(container)是一个 DOM 元素。
2、Portals 适合脱离文档流(out of flow) 的组件,特别是 position: absolute 与 position: fixed的组件。比如模态框,通知,警告,goTop 等

2.0版本(更新内容)

1、说说你对Event Loop的理解?

1、Event Loop是JavaScript中的一种机制,用于处理异步事件和回调函数,它是JavaScript运行时环境的一个循环,不断从任务队列中取出任务并执行,直到任务队列为空。 2、Event Loop工作原理: a、执行同步代码,将异步操作放入任务队列中 b、当主线任务空闲的时候,Event Loop会检查任务队列中是否有任务 c、如果有任务,则取出任务并且执行 d、执行完成任务以后,再次检查任务队列,重复b和c的操作 3、Event Loop是JavaScript中非常重要的一个概念,它使得JavaScript可以处理异步操作,提高了程序的性能和用户体验。

2、说说你对BOM的理解,常见的BOM对象你了解哪些?

1、BOM就是指浏览器对象模型,提供了独立于内容与浏览器窗口进行交互的对象 2、它的作用就是跟浏览器做一些交互效果,比如如何进行页面的后退、前进、刷新、浏览器的窗口发生变化、滚动条的滚动,以及获取客户的一些信息,像浏览器品牌版本,屏幕分辨率 3、window:BOM的核心对象是window,它表示浏览器的一个实例,在浏览器中,window对象有双重角色,也就是浏览器窗口的一个接口,又是全局对象,因此,所有在全局作用域中声明的变量,函数都会编程window对象的属性和方法 4、local: 5、navigator:主要用来获取浏览器的属性,区分浏览器类型。属性较多,且兼容性比较复杂 6、screen:保存的纯粹是客户端能力信息,也就是浏览器窗口外面的客户端显示器的信息,比如像素宽度和像素高度 7、history:对象主要用来操作浏览器URL的历史记录,可以通过参数向前,向后,或者向指定URL跳转

3、浏览器的内核都有哪些,什么区别?

常见的浏览器内核有以下几种:

  1. Trident内核:是微软开发的浏览器内核,主要用于Internet Explorer浏览器。

  2. Gecko内核:是Mozilla Firefox浏览器的内核,也被其他浏览器所采用。

  3. WebKit内核:是苹果公司开发的浏览器内核,主要用于Safari浏览器和Chrome浏览器。

  4. Blink内核:是Google公司基于WebKit内核开发的浏览器内核,主要用于Chrome浏览器和Opera浏览器。 5、区别: 1、主要在于其渲染引擎的不同,从而导致了浏览器的性能、兼容性、安全性等方面的差异。 2、Trident内核在处理CSS和JavaScript方面相对较慢 3、Gecko内核则更加注重安全性和隐私保护 4、WebKit内核则以其快速的渲染速度和良好的兼容性著称 5、Blink内核则在性能和稳定性方面有所提升。

4、说说浏览器的渐进增强和优雅降级的区别?

1、浏览器的渐进增强和优雅降级都是为了解决不同的浏览器或者设备之间的兼容性问题 2、渐进增强就是指在设计和开发网站或应用程序的时候,首先考虑基本功能的实现,然后逐步添加更加高级的功能和交互的效果,以适应不同的浏览器和设备的能力 3、渐进增强更加注重于向前兼容性,就算在比较老的浏览器上也可以正常使用 4、优雅降级就是指在设计和开发网站或者应用程序的时候,首先考虑高级功能和交互效果的实现,然后逐步降低要求,用来适应较老或者不支持这些功能的浏览器和设备 5、优雅降级就是强调向后兼容性,也就是说在较新的浏览器上能够享受更好的用户体验

5、 网站性能优化的方案都有哪些?

1、尽量减少HTTP的请求次数:合并js、css等 2、 压缩文件:压缩CSS、JavaScript、HTML等文件,减少文件大小,提高网页加载速度。 3、 图片优化:使用适当的图片格式,压缩图片大小,减少图片数量,提高网页加载速度。 4、CDN加速:使用CDN(内容分发网络)加速网站访问速度,将网站内容分发到全球各地的服务器上,使用户可以从最近的服务器获取内容。 5、缓存优化:使用浏览器缓存和服务器缓存,减少重复请求,提高网站访问速度。 6、前端优化:减少HTTP请求,使用CSS Sprites、合并JavaScript文件等技术,减少页面加载时间。 7、数据库优化:优化数据库查询语句,使用索引,减少数据库查询时间,提高网站访问速度。 8、服务器优化:使用高性能服务器,优化服务器配置,提高网站访问速度。 9、去除冗余代码:去除无用的代码,减少页面大小,提高网站访问速度。 10、响应式设计:使用响应式设计,使网站可以适应不同的设备和屏幕大小,提高用户体验。

6、Link和@import之间有什么区别?

1、Link和@import都是用于引入外部资源的方法 2、不同: 1、加载顺序的不同:Link标签在加载页面的时候就会同时加载外部的资源,而@import在页面加载完毕之后才会加载外部资源 2、兼容性的不同:Link标签在所有浏览器中都被支持,而@import在一些旧的版本浏览器中可能不被支持 3、作用范围不同:Link标签可以用于引入各种类型的资源,包括CSS、JavaScript、图像等,而@import只能用于引入css文件 4、优先级不同:Link标签的优先级高于@import,因此如果同一个样式表这两种方法都使用的话,那么Link就会覆盖@import的样式

7、说说你对BFC的理解,触发条件有哪些?

1、BFC就是块级格式化上下文,是指的独立的渲染区域,其中的元素按照一定的规则进行布局和渲染
2、BFC特点:
    1、内部元素在垂直方向上一个接一个的排列,形成一个垂直流
    2、BFC区域不会与浮动元素重叠
    3、BFC区域不会与外部元素的margin发生重叠
    4、BFC区域可以包含浮动元素
    5、BFC区域可以防止元素被父元素的边框所覆盖
3、触发条件:
    1、根元素或者包含根元素的元素
    2、浮动元素float不等于none
    3、绝对定位position为absoulute或者fixed
    4、display是inline-block、table-cell、table-caption、flex、inline-flex
    5、overflow不为visible的块级元素

8、null,undefined 的区别?

1、在js中,null和undefined都是表示没有值 2、区别: 1、undefined表示一个变量声明了但是没有被赋值,或者对象属性不存在 2、null表示一个变量已经被赋值为null,或者对象属性被赋值为null 3、在条件语句中,undefined和null都会被转换为false,但是在比较运算符中,行为不同,undefined与任何值包括本身比较都是false,但是null只在和undefined比较是为true

9、说说css中元素脱离文档流的方式有哪些?定位的方式有哪些以及区别?

1、CSS中元素脱离文档流的方式有以下几种: 1. 浮动(float):将元素从文档流中移出来,使其能够与其他元素并排显示。 2. 绝对定位(position: absolute):将元素从文档流中移出来,并相对于其最近的已定位祖先元素进行定位。 3. 固定定位(position: fixed):将元素从文档流中移出来,并相对于浏览器窗口进行定位。 4. 弹性布局(display: flex):通过设置父元素为弹性容器,使其子元素能够脱离文档流,并按照一定的规则进行排列。 5. 网格布局(display: grid):通过设置父元素为网格容器,使其子元素能够脱离文档流,并按照一定的规则进行排列。 2、定位的方式有以下几种: 1. 相对定位(position: relative):相对于元素在文档流中的位置进行定位,不会影响其他元素的位置。 2. 绝对定位(position: absolute):相对于最近的已定位祖先元素进行定位,如果没有已定位的祖先元素,则相对于文档的 body 元素进行定位。 3. 固定定位(position: fixed):相对于浏览器窗口进行定位,不会随着页面滚动而移动。

3、区别: 相对定位和绝对定位的区别在于,相对定位不会脱离文档流,而绝对定位会脱离文档流。固定定位与绝对定位类似,但它相对于浏览器窗口进行定位,不会随着页面滚动而移动。

10、同步和异步的区别?

1、同步和异步是指在进行任务处理的时候,任务的执行方式不同 2、同步任务指的是任务按照顺序依次执行,每个任务必须等待前一个任务完成之后才能执行,在同步执行中,任务的执行是阻塞的,也就是说在执行任务的时候会一直等待任务完成后才会继续执行下一个任务 3、异步执行是指任务不按照顺序依次执行,每一个任务可以独立执行,不需要等待前一个任务完成。在异步任务的执行中,任务的执行是非阻塞的,也就是执行任务是不会等待任务完成,而是继续执行下一个任务 4、同步和异步的区别就在于任务的执行方式,同步执行就是按照顺序依次执行,而异步执行时独立执行,不需要等待前一个任务的完成,在实际中,异步执行通常能够提高程序的响应速度和效率

11、伪类和伪元素的区别有哪些? Css3新增了哪些选择器?

伪类和伪元素的区别: 1. 伪类用于描述元素的一些特殊状态,如:hover、:active、:focus等,而伪元素用于创建一些不在文档树中的元素,如::before、::after等。 2. 伪类在CSS2中以单冒号(:)表示,伪元素以双冒号(::)表示。 3. 伪类可以用于任何元素,而伪元素只能用于某些特定的元素。 4. 伪类可以用于选择器的任何位置,而伪元素只能用于选择器的最后一个位置。 CSS3新增的选择器包括: 1. 属性选择器:[attr=value]、[attr~=value]、[attr|=value]、[attr^=value]、[attr$=value]、[attr*=value] 2. 伪类选择器::nth-child()、:nth-last-child()、:nth-of-type()、:nth-last-of-type()、:first-child、:last-child、:first-of-type、:last-of-type、:only-child、:only-of-type、:not() 3. 伪元素选择器:::before、::after、::first-letter、::first-line、::selection 4. 组合选择器:A B、A > B、A + B、A ~ B

12、说说Promise和async/await的区别是?

Promise和async/await都是用于处理异步操作的方式,但是它们之间有一些区别。

  1. 语法:Promise是一种基于回调函数的异步编程方式,使用.then()和.catch()方法来处理异步操作的结果。而async/await是ES2017引入的异步编程方式,使用async和await关键字来处理异步操作的结果。

  2. 可读性:async/await相对于Promise来说更加易读易懂,代码更加简洁明了。

  3. 错误处理:在Promise中,错误处理需要使用.catch()方法来捕获错误。而在async/await中,可以使用try/catch语句来捕获错误。

  4. 链式调用:Promise可以链式调用多个异步操作,而async/await只能在一个异步操作完成后再进行下一个异步操作。 总的来说,async/await是一种更加直观、易读、易懂的异步编程方式,但是在某些情况下,Promise也是非常有用的。

13、说说重排和重绘的区别?触发条件有哪些?

重排和重绘是浏览器渲染页面时的两个重要概念。 重排(reflow)是指当页面中的元素发生布局变化时,浏览器需要重新计算元素的位置和大小,并重新排列页面的布局。重排会导致页面的重新布局和重新渲染,是一种比较耗费性能的操作。 重绘(repaint)是指当页面中的元素的样式发生变化时,浏览器需要重新绘制元素的样式。重绘不会改变页面的布局,只会重新绘制元素的样式,因此比重排的性能开销要小。 触发重排的条件包括: 1. 页面初次渲染 2. 浏览器窗口大小发生变化 3. 元素的位置、大小、内容发生变化 4. 元素的样式发生变化 5. 页面滚动 触发重绘的条件包括: 1. 元素的样式发生变化 2. 元素的背景色、边框颜色、文本颜色等属性发生变化 3. 元素的透明度发生变化 4. 元素的文本内容发生变化 总的来说,重排和重绘都会影响页面的性能,因此在开发过程中需要尽量避免频繁触发重排和重绘。可以通过合理的布局设计、使用 CSS3 动画代替 JavaScript 动画等方式来优化页面性能。

14、Javascript如何实现继承?

1、原型链继承:通过将子类的原型对象指向父类的实例对象来实现继承。 2、构造函数继承:指通过在子类构造函数中调用父类构造函数来实现继承。 3、组合继承:组合继承指的是将原型链和构造函数继承结合起来的一种继承方式,实现方式就是通过在子类构造函数中调用父类构造函数来继承父类的属性,并将子类的原型对象指向一个新的父类实例对象来继承的方法。 4、ES6中的class继承:通过使用extends关键字来继承父类,并使用super来调用父类的构造函数和方法。

15、说说什么是严格模式,限制都有哪些?

严格模式是 JavaScript 的一种执行模式,它强制执行一些限制,以帮助开发者编写更加健壮的代码。在严格模式下,一些不安全的行为会被禁止,一些错误也会被抛出。 严格模式下的限制包括: 1. 禁止使用未声明的变量。 2. 禁止删除变量、函数或函数参数。 3. 禁止使用 eval() 函数创建变量或函数。 4. 禁止使用 with 语句。 5. 禁止在函数内部使用 arguments.callee 和 arguments.caller。 6. 禁止对只读属性赋值。 7. 禁止扩展内置对象的原型。 8. 禁止在函数内部重复声明变量。 严格模式可以通过在代码的开头添加 "use strict"; 来启用。在严格模式下编写代码可以帮助开发者避免一些常见的 JavaScript 错误,并提高代码的可读性和可维护性。

16、如何快速的让一个打乱一个数组的顺序,比如 var arr = [1,2,3,4,5,6,7,8,9,10]?

  1. 从数组的最后一个元素开始,向前遍历数组。

  2. 随机生成一个 0 到当前遍历的索引值之间的整数。

  3. 将当前遍历的元素与随机生成的索引所对应的元素交换位置。

  4. 继续向前遍历数组,重复步骤 2 和 3,直到遍历到数组的第一个元素为止。

17、Vue的自定义指令钩子函数有哪些?你用自定义指令做过什么?

Vue的自定义指令钩子函数包括:bind、inserted、update、componentUpdated、unbind。 1、 bind:只调用一次,指令第一次绑定到元素时调用,可以在这里进行一次性的初始化设置。 2、 inserted:被绑定元素插入父节点时调用,但可能在其父节点还未插入到DOM中。 3、 update:被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。 4、 componentUpdated:被绑定元素所在模板完成一次更新周期时调用。 5、 unbind:只调用一次,指令与元素解绑时调用。 我曾经使用自定义指令实现了一个点击外部区域关闭弹窗的功能。具体实现方式是在bind钩子函数中绑定一个document的click事件,当点击事件触发时判断点击的区域是否在弹窗内部,如果不是则关闭弹窗。在unbind钩子函数中解绑该事件。

18、从A页面跳转到B页面,缓存A组件,从A组件跳转到C组件,取消缓存,如何实现?

1、keep-alive 可以通过当前页面的BeforeRouter(to,from,next) 当to ===“B” & from ===”A” keep-alive的meta中参数为true 当to ===“C” & from ===”A” keep-alive的meta中参数为false 2、生命周期,获取 this.router.meta 修改页面的meta里面的参数,keep-alive回根据meta中的参数决定是否对组件进行缓存

19、Vue2和Vue3中响应式原理及区别?

1、Vue2和Vue3中的响应式原理都是基于Object.defineProperty实现的。当数据发生变化时,会自动触发视图的更新。但是Vue3中对响应式原理进行了优化,使用了Proxy代理对象来替代了Object.defineProperty,使得响应式系统更加高效和灵活。 2、Vue2中的响应式原理是在实例化Vue对象时,会对data中的每个属性进行递归地遍历,将每个属性都转换为getter和setter,当属性被访问或修改时,会触发getter和setter方法,从而实现响应式更新。 3、Vue3中的响应式原理使用了Proxy代理对象,它可以拦截对象的访问和修改操作,从而实现响应式更新。Vue3中的响应式系统还支持了reactive函数,可以将一个普通对象转换为响应式对象,使得开发者可以更加灵活地使用响应式系统。 4、总的来说,Vue3中的响应式系统相比Vue2更加高效和灵活,但是在使用上也有一些区别,需要开发者进行适当的学习和调整。

20、Vue是如何实现实现权限管理的,按钮级别权限如何实现?

1、将所有权限按照等级,划分为一级权限和二级权限,生成相对的tree数,获取每个权限的id,将每个id放到一个列表中,赋值给角色的权限外键 2、按钮权限是,每个按钮绑定一个处理方法,当登录的用户,返回的角色id没有对应这个按钮的权限方法时候,会对按钮进行隐藏处理



第一周

21、Vue2和Vue3的区别至少说5点?

  1. 性能优化:Vue3在性能方面进行了大量的优化,包括编译器优化、响应式系统优化、虚拟DOM优化等,使得Vue3的性能比Vue2更快。

  2. Composition API:Vue3引入了Composition API,它是一种新的API风格,可以更好地组织和重用组件逻辑,使得代码更加清晰和易于维护。

  3. TypeScript支持:Vue3对TypeScript的支持更加完善,可以更好地进行类型检查和代码提示,提高代码的可靠性和可维护性。

  4. 更好的Tree-Shaking:Vue3采用了更加现代的ES模块语法,可以更好地支持Tree-Shaking,减小打包体积。

  5. 更好的适配性:Vue3对Web和移动端的适配性更加优秀,可以更好地支持PWA和SSR等技术。

  6. 更好的错误处理:Vue3引入了错误处理机制,使得开发者能够更加容易地定位和解决错误。

22、 Vue3中组件通信的流程【父传子,子传父】?

1、vue3中组件通信的流程分为父传子、子传父两种方式
2、父传子:
    父组件通过props向子组件传递数据,子组件通过props接收数据。父组件可以在模板中使用子组件,并且通过v-bind指令将数据传递给子组件,子组件可以在props中声明接收的数据类型和默认值
3、子传父:
    子组件通过$emit的方法向父组件发送事件,父组件通过v-on指令监听子组件发送的事件,子组件可以通过$emit方法来传递给父组件

23、Apply/call/bind的原理是什么?

1、Apply、call和bind都是JavaScript中用于改变函数执行上下文的方法。 2、allpy和call的作用都是一样的,都是改变函数的执行上下文,就是改变函数内部的this指向,它们的区别就在于传参的方式不同,apply接收一个数组作为参数,call接收多个参数 3、bind方法也是用于改变函数的执行上下文,但是他不会立即执行函数,而是返回一个新的函数,这个新的函数的this指向被绑定的对象 4、总的来说,apply、call和bind都是用于改变函数执行上下文的方法,它们的区别在于传参的方式和返回值。apply和call会立即执行函数,而bind会返回一个新的函数。

24、说说你对原型和原型链的理解?

1、原型是JavaScript中的一个重要概念,它是一个对象,其他对象可以通过它来实现属性和方法的继承。每个JavaScript对象都有一个原型对象,它定义了该对象的属性和方法。如果在当前对象中找不到某个属性或方法,JavaScript引擎会自动查找该对象的原型对象,直到找到为止。 2、原型链是由原型对象组成的链式结构,它是JavaScript中实现继承的一种方式。当一个对象需要访问另一个对象的属性或方法时,JavaScript引擎会沿着原型链向上查找,直到找到该属性或方法为止。如果在整个原型链中都找不到该属性或方法,则返回undefined。 3、在JavaScript中,每个对象都有一个proto属性,它指向该对象的原型对象。当我们访问一个对象的属性或方法时,JavaScript引擎会先查找该对象自身是否有该属性或方法,如果没有,则会沿着原型链向上查找,直到找到为止。如果在整个原型链中都找不到该属性或方法,则返回undefined。 4、总之,原型和原型链是JavaScript中非常重要的概念,它们可以帮助我们实现对象之间的继承和共享属性和方法。

25、说说你对ES6中Generator的理解?

1、ES6中的Generator是一种特殊的函数,它可以在执行过程中暂停并保存当前的状态,然后在需要的时候恢复执行。Generator函数通过yield关键字来实现暂停和恢复执行的功能。 2、Generator函数可以用于异步编程,可以通过yield关键字来暂停异步操作的执行,等待异步操作完成后再继续执行。Generator函数还可以用于实现迭代器,可以通过yield关键字来返回一个值,然后在下一次调用时继续执行。 3、另外,Generator函数还可以接受参数,可以在调用Generator函数时传入参数,然后在函数内部使用这些参数。 4、总之,Generator函数是一种非常强大的工具,可以用于实现异步编程、迭代器等功能,可以大大简化代码的编写和维护。

26、说说浏览器事件循环和nodeJs的事件循环的区别?

浏览器事件循环和Node.js的事件循环有以下几个区别: 1. 浏览器事件循环是单线程的,而Node.js的事件循环是多线程的。 2. 浏览器事件循环中的任务分为宏任务和微任务两种,而Node.js的事件循环中只有宏任务。 3. 浏览器事件循环中的微任务包括Promise、MutationObserver和process.nextTick,而Node.js的事件循环中没有process.nextTick,但有setImmediate。 4. 浏览器事件循环中的宏任务包括script、setTimeout、setInterval、I/O、UI rendering等,而Node.js的事件循环中的宏任务包括I/O、定时器、setImmediate等。 5. 浏览器事件循环中的任务执行顺序是先执行所有微任务,再执行一个宏任务,而Node.js的事件循环中的任务执行顺序是先执行所有的I/O和定时器任务,再执行setImmediate任务。 总的来说,浏览器事件循环和Node.js的事件循环都是基于事件驱动的模型,但是它们的实现方式和任务执行顺序有所不同。

27、说说你对浏览器缓存机制的理解?

浏览器缓存机制是指浏览器在访问网页时,会将一些静态资源(如图片、CSS、JS等)缓存到本地,以便下次访问同一网页时可以直接从本地缓存中读取,从而提高网页加载速度和用户体验。 1、浏览器缓存机制分为两种:强缓存和协商缓存。 2、强缓存是指浏览器在第一次请求资源时,会将资源的过期时间(Expires)或最大缓存时间(Cache-Control)存储在本地,下次请求时会先判断本地缓存是否过期,如果没有过期则直接从本地缓存中读取资源,不会向服务器发送请求。 3、协商缓存是指浏览器在第一次请求资源时,会将资源的标识(ETag或Last-Modified)存储在本地,下次请求时会向服务器发送请求,服务器会根据资源的标识判断资源是否有更新,如果没有更新则返回304状态码,浏览器直接从本地缓存中读取资源。 4、浏览器缓存机制可以有效减少网络请求,提高网页加载速度和用户体验,但也可能导致资源更新不及时,需要在开发中合理使用缓存机制,避免出现问题。

28、说说你对浏览器内核的理解?

浏览器内核又可以分为两个部分:渲染引擎和JS引擎 1、渲染引擎:负责取得网页的内容(HTML,XML,图像等等)、整理讯息(加入css等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器内核的不同对于网页的语法解释会有所不同,所以渲染的效果也不同 2、JS引擎:则是解析JavaScript语言,执行JavaScript语言来实现网页的动态效果 浏览器内核的不同会影响浏览器的渲染效果、速度、兼容性等方面,因此选择合适的浏览器内核对于浏览器的性能和用户体验都非常重要。

29、说说你对Vue的响应式原理的理解?

Vue的响应式原理是通过数据劫持来实现的。当一个Vue实例被创建时,Vue会对其所有的数据进行监听,当数据发生变化时,Vue会自动更新视图。具体实现方式如下: 1. Vue会在实例化时对data对象进行遍历,将每个属性转换为getter/setter,这样当属性被访问或修改时,Vue能够监听到。 2. 当数据发生变化时,Vue会通过setter方法监听到变化,并通知所有依赖该数据的组件进行更新。 3. Vue使用了一个Dep类来管理所有的依赖关系,每个数据都会对应一个Dep实例,当数据发生变化时,Dep会通知所有依赖该数据的Watcher实例进行更新。 4. Watcher实例是Vue中的一个重要概念,它会在组件渲染时被创建,并且会在数据发生变化时被通知进行更新。每个Watcher实例都会与一个Dep实例关联,当数据发生变化时,Dep会通知所有关联的Watcher实例进行更新。 总的来说,Vue的响应式原理是通过数据劫持、Dep类和Watcher实例来实现的,它能够自动监听数据变化并更新视图,大大简化了开发过程。

30、Methods watch computed区别是什么?

1、Methods 和 watch 都是 Vue.js 中用于监听数据变化的方式 2、Methods 是 Vue.js 中的一个选项,用于定义组件中的方法。它可以接受参数,执行一些操作,并返回结果。当组件中的数据发生变化时,如果需要重新计算某些数据,就需要在方法中重新计算并返回结果。 3、Watch 是 Vue.js 中的一个特殊选项,用于监听数据的变化并执行一些操作。它可以监听一个或多个数据的变化,并在数据变化时执行指定的回调函数。当需要在数据变化时执行一些异步操作或复杂的计算时,就需要使用 watch。 4、区别在于: 1、Methods 是用于定义组件中的方法,可以接受参数并执行一些操作,返回结果。而 watch 是用于监听数据变化并执行一些操作,不能接受参数,也不能返回结果。 2、Methods 通常用于计算属性或处理事件等简单的操作,而 watch 通常用于处理复杂的异步操作或计算,或者需要监听多个数据变化的情况。

  1. Computed是Vue.js中的一个计算属性,它也可以在模板中调用,但是它的实现方式和Methods不同。Computed是基于依赖缓存的,也就是说,只有当依赖的数据发生变化时,才会重新计算。如果依赖的数据没有发生变化,那么Computed会直接返回缓存中的结果,从而提高了性能。

31、说说你对Virtual DOM的理解?

Virtual DOM是一种用于优化Web应用程序性能的技术。它是一个轻量级的JavaScript对象,它模拟了真实DOM的层次结构和属性,并且可以在内存中进行操作,而不是直接操作真实DOM。当Virtual DOM发生变化时,它会与真实DOM进行比较,只更新需要更新的部分,从而减少了DOM操作的次数,提高了应用程序的性能。 Virtual DOM的优点包括: 1. 提高应用程序的性能:由于Virtual DOM只更新需要更新的部分,因此减少了DOM操作的次数,提高了应用程序的性能。 2. 简化应用程序的开发:由于Virtual DOM可以在内存中进行操作,因此可以更轻松地进行应用程序的开发和测试。 3. 提高应用程序的可维护性:由于Virtual DOM可以更轻松地进行应用程序的开发和测试,因此可以提高应用程序的可维护性。 总之,Virtual DOM是一种非常有用的技术,可以帮助我们提高Web应用程序的性能和可维护性。

32、说说你对nextTick的理解和作用?

1、nextTick是Vue.js中的一个异步方法,它的作用是在下一次DOM更新循环结束之后执行指定的回调函数。nextTick的主要作用是在Vue.js更新DOM之后,立即执行一些操作,例如更新数据后立即获取DOM元素的尺寸或位置等。 2、nextTick的实现原理是利用了JavaScript的事件循环机制。当Vue.js更新DOM时,它会将所有的DOM更新操作放入一个队列中,然后等待下一次事件循环时执行。而nextTick方法就是将指定的回调函数放入这个队列中,等待下一次事件循环时执行。 3、nextTick的使用场景比较广泛,例如在Vue.js中使用$nextTick方法可以在DOM更新后立即执行一些操作,例如获取DOM元素的尺寸或位置等。另外,在Vue.js中使用nextTick方法也可以解决一些异步更新数据的问题,例如在更新数据后立即获取更新后的数据。 4、总之,nextTick是Vue.js中非常重要的一个异步方法,它可以帮助我们在DOM更新后立即执行一些操作,从而提高应用程序的性能和用户体验。

33、说说你对webpack的理解?

Webpack是一个现代化的JavaScript应用程序打包工具。它可以将多个JavaScript文件、CSS文件、图片等静态资源打包成一个或多个bundle文件,以便于在浏览器中加载和使用。

Webpack的主要功能包括: 1. 模块化管理:Webpack支持CommonJS、AMD、ES6等多种模块化规范,可以将多个模块打包成一个文件,减少HTTP请求次数,提高页面加载速度。 2. 代码转换:Webpack可以将ES6、TypeScript、CoffeeScript等高级语言转换成浏览器可识别的JavaScript代码。 3. 代码分割:Webpack可以将应用程序分割成多个chunk,实现按需加载,提高页面加载速度。 4. 资源管理:Webpack可以处理CSS、图片、字体等静态资源,将它们打包成一个或多个文件,并且可以对它们进行压缩、优化等操作。 5. 插件系统:Webpack提供了丰富的插件系统,可以实现各种自动化操作,如代码压缩、文件复制、HTML生成等。 总之,Webpack是一个非常强大的工具,可以帮助开发者更好地管理和打包JavaScript应用程序,提高开发效率和用户体验。

34、谈谈GET和POST的区别?

1、GET和POST是HTTP协议中常用的两种请求方法 2、区别: 1. GET请求方法是用于获取资源,而POST请求方法是用于提交数据。 2. GET请求方法的数据会附加在URL后面,以问号“?”分隔,参数之间以“&”符号分隔,而POST请求方法的数据则包含在请求体中。 3. GET请求方法的数据传输量较小,一般不超过2KB,而POST请求方法的数据传输量较大,可以传输任意大小的数据。 4. GET请求方法的数据可以被缓存,可以被收藏为书签,可以被浏览器历史记录记录,而POST请求方法的数据不会被缓存,也不能被收藏为书签,也不会被浏览器历史记录记录。 5. GET请求方法的安全性较低,因为数据会被暴露在URL中,容易被截获和篡改,而POST请求方法的安全性较高,因为数据不会被暴露在URL中,只有请求体中的数据才能被截获和篡改。

35、说说HTTP和HTTPS的区别,HTTPS加密原理是?

1、HTTP是超文本传输协议,是一种用于传输数据的协议,它是明文传输的,数据容易被窃听和篡改。 2、而HTTPS是在HTTP的基础上加入了SSL/TLS协议,通过加密和认证技术保证数据的安全性。HTTPS使用的是加密传输,数据传输过程中会进行加密,保证数据的机密性和完整性。 3、具体来说,HTTPS在传输数据之前会先进行SSL/TLS握手,建立安全通道,然后再进行数据传输。SSL/TLS协议使用了非对称加密和对称加密两种加密方式,非对称加密用于建立安全通道,对称加密用于加密数据传输。 4、在SSL/TLS握手过程中,服务器会向客户端发送自己的公钥,客户端使用该公钥加密一个随机数,然后发送给服务器,服务器使用自己的私钥解密该随机数,然后使用该随机数生成对称密钥,用于加密数据传输。 5、HTTPS相对于HTTP来说,具有更高的安全性和保密性,适用于需要保护用户隐私和敏感信息的网站,如银行、电商等网站。

36、TCP为什么要三次握手?

TCP协议需要进行三次握手来建立连接,主要是为了确保通信双方都能够正常收发数据。 具体原因如下: 1. 第一次握手:客户端向服务器发送连接请求报文段,服务器收到请求后会回复一个确认报文段,表示已经收到了客户端的请求。 2. 第二次握手:服务器收到客户端的请求后,会向客户端发送一个确认报文段,表示已经收到了客户端的请求,并准备好了与客户端进行通信。 3. 第三次握手:客户端收到服务器的确认报文段后,会向服务器发送一个确认报文段,表示已经收到了服务器的确认,并准备好了与服务器进行通信。 4、通过三次握手,可以确保通信双方都能够正常收发数据,并且可以避免因网络延迟或丢包等问题导致连接失败或数据传输错误的情况发生。同时,三次握手还可以防止因网络中的恶意攻击或误传等问题导致的安全问题。

37、说说Proxy代理的原理?

Proxy代理是一种网络应用程序,它充当客户端和服务器之间的中介。它的原理是在客户端和服务器之间建立一个代理服务器,客户端向代理服务器发送请求,代理服务器再将请求转发给服务器,服务器响应后将结果返回给代理服务器,代理服务器再将结果返回给客户端。

Proxy代理的工作流程如下: 1. 客户端向代理服务器发送请求。 2. 代理服务器接收请求,并将请求转发给服务器。 3. 服务器响应请求,并将结果返回给代理服务器。 4. 代理服务器接收到结果,并将结果返回给客户端。

Proxy代理的作用主要有以下几个方面: 1. 提高访问速度:代理服务器可以缓存请求结果,当下次有相同的请求时,直接返回缓存结果,从而提高访问速度。 2. 访问控制:代理服务器可以对客户端的请求进行过滤和控制,例如限制访问某些网站或者限制某些客户端的访问。 3. 隐藏客户端信息:代理服务器可以隐藏客户端的真实IP地址,从而保护客户端的隐私。 4. 负载均衡:代理服务器可以将请求分发到多个服务器上,从而实现负载均衡,提高服务器的性能和可靠性。 总之,Proxy代理是一种非常有用的网络应用程序,它可以提高访问速度、保护隐私、实现负载均衡等多种功能。

38、说说内存泄漏的理解?内存泄漏的情况有哪些?

内存泄漏指程序在运行过程中,申请的内存空间没有被正确释放,导致系统中的可用内存不断减少,最终导致程序崩溃或系统崩溃的现象。内存泄漏通常是由于程序中存在一些错误的内存管理操作,例如未释放动态分配的内存、重复释放内存、使用已经释放的内存等。

内存泄漏的情况有以下几种: 1. 动态分配内存后未释放:程序在运行过程中使用了动态分配的内存,但在使用完毕后未将其释放,导致内存泄漏。 2. 循环引用:当两个或多个对象相互引用时,如果它们之间的引用关系没有被正确处理,就会导致内存泄漏。 3. 文件未关闭:程序在使用文件时,如果没有正确关闭文件,就会导致内存泄漏。 4. 缓存未清理:程序在使用缓存时,如果没有正确清理缓存,就会导致内存泄漏。 5. 程序错误:程序中存在一些错误的内存管理操作,例如使用已经释放的内存、重复释放内存等,都会导致内存泄漏。

内存泄漏会导致程序运行速度变慢,甚至会导致程序崩溃或系统崩溃,因此在程序开发中,需要注意内存管理,及时释放不再使用的内存空间。



第三周

39、说说箭头函数和普通函数的区别?

箭头函数和普通函数的区别主要有以下几点: 1. 箭头函数没有自己的this,它的this是继承自外层作用域的。而普通函数的this是在函数被调用时动态绑定的,它的值取决于函数的调用方式。 2. 箭头函数不能使用arguments对象,也不能使用new关键字调用。而普通函数可以使用arguments对象,也可以使用new关键字调用。 3. 箭头函数没有prototype属性,因此不能作为构造函数使用。而普通函数可以作为构造函数使用,创建新的对象实例。 4. 箭头函数的语法更加简洁,可以省略函数体中的return关键字和花括号。而普通函数必须使用return关键字返回值,并且函数体必须用花括号括起来。 5、总的来说,箭头函数适合用于简单的函数,可以让代码更加简洁易读。而普通函数则更加灵活,可以应对各种不同的场景。

40、SPA首屏加载速度慢怎么解决?

  1. 代码优化:检查代码中是否存在冗余、重复或不必要的代码,尽可能减少代码量,优化代码结构和算法,以提高页面加载速度。

  2. 图片优化:对于图片过大的情况,可以使用图片压缩工具进行压缩,减小图片大小,从而提高页面加载速度。

  3. 懒加载:对于页面中的图片、视频等资源,可以使用懒加载技术,只有当用户滚动到相应位置时才加载,从而减少首屏加载时间。

  4. CDN加速:使用CDN(Content Delivery Network)加速服务,将静态资源分布在全球各地的服务器上,从而提高页面加载速度。

  5. 缓存优化:使用浏览器缓存技术,将页面中的静态资源缓存到本地,下次访问时直接从缓存中读取,从而减少服务器请求,提高页面加载速度。

  6. 服务器优化:对于服务器响应速度慢的情况,可以考虑使用更高配置的服务器,或者使用负载均衡技术,将请求分散到多个服务器上,从而提高页面加载速度。

41、说说webpack中常见的Loader?解决了什么问题?

  1. babel-loader:将ES6/ES7/JSX等语法转换为ES5语法,解决了浏览器兼容性问题。

  2. css-loader:解析CSS文件,处理其中的依赖关系,例如@import和url()等,使得CSS文件可以被打包到JS文件中。

  3. style-loader:将CSS代码注入到HTML页面中的