目录
1.bind、call、apply 区别?如何实现一个bind?
2.什么是防抖和节流?有什么区别?如何实现?
3.怎么理解回流跟重绘?什么场景下会触发?
4.VUE路由的原理
5.你了解vue的diff算法吗?说说看
6.说说你对keep-alive的理解
7.什么是响应式设计?响应式设计的基本原理是什么?如何做?
8.说说 React 生命周期有哪些不同阶段?每个阶段对应的方法是?
9.如何解决跨域问题?
10.如何优化webpack打包速度
11.说说react router有几种模式?实现原理
12.从浏览器地址栏输入url到显示页面的步骤
13.说说JavaScript中的数据类型?存储上的差别
14.说说对React Hooks的理解?解决了什么问题
15.说说你对promise的了解
16.说说webpack中常见的Loader?解决了什么问题
17.说说 React中的setState执行机制
18.Vue组件之间的通信方式都有哪些
bind、call、apply 区别?如何实现一个bind?
call、apply、bind都是用于实现this指向改变的方式
区别:
call(参数1,参数2,参数3,......) 参数1代表this指向改变的方向,后面的参数代表传递的参数
apply(参数1,[a,b,c])参数1代表this指向改变的方向,第二个参数是一个数组,数组中的内容代表要传递的参数
bind(参数1,...args)参数1代表this指向改变的方向,第二个参数代表传递的参数,可以分批传入,有函数作为返回值,需要调用后才会生效
实现一个bind:
//this指向window
function fn() {
console.log(this);
}
let a = 123
// this指向预改变
const changeFn = fn.bind(a);
changeFn() // 调用返回函数,this指向a
fn()
什么是防抖和节流?有什么区别?如何实现?
本质上就是对事件触发频率的优化,降低计算的频率
防抖:n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
节流:n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
区别:
计时刷新的频率不同,防抖是规定时间内只执行一次,不论规定时间内点击了多少次,都以第一次的点击为准,到时间输出结果;节流是当我们点击按钮就会开始计时,在规定时间内,如果再次点击,就会重置计时,重新开始计算,直到正常走完规定的时间才会输出结果
如何实现:
防抖:
const debounce = (func, wait = 50) => {
let timer = 0
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, args)
}, wait)
}
}
节流:
export const throttle = function (fn, wait = 500) {
let flg = true
return function () {
if (!flg) return;
flg = false
setTimeout(() => {
fn.apply(this, arguments)
flg = true
}, wait);
}
}
怎么理解回流跟重绘?什么场景下会触发?
回流:在布局之后对元素的大小、位置进行改变,会触发回流
例如:当我们对 DOM
的修改引发了 DOM
几何尺寸的变化时,浏览器需要重新计算元素的几何属性,
然后再将计算的结果绘制出来
触发场景:
(1)DOM结构发生改变
(2)布局发生改变
(3)窗口大小发生改变
(4)调用getComputedStyle方法获取尺寸、位置信息
(5)内容发生变化
(6)页面一开始渲染
重绘:在第一次绘制完页面后,重新绘制的过程
例如:当我们对 DOM
的修改导致了样式的变化,并未影响其几何属性时,浏览器不需重新计算元素
的几何属性、直接为该元素绘制新的样式,这里就仅仅触发了重绘
触发场景:
(1)修改网页内容的样式
(2)触发回流一定会触发重绘
VUE路由的原理?
Vue的路由实现:hash模式 和 history模式
hash模式:
在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对
于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history模式:
history采用HTML5的新特性;且提供了两个新方法:pushState()、replaceState(),可以对浏览器
历史记录栈进行修改,以及popState事件的监听到状态变更
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.co
m/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。
你了解vue的diff算法吗?说说看?
diff算法是一种通过同层的树节点进行比较的高效算法,具有以下特点:
(1)不会跨层比较
(2)从两边向中间比较
(3)深度优先
diff算法在很多场景中都有涉及到,在vue中,作用于虚拟 dom
渲染成真实 dom
的新旧 VNode
节点比
较;在react中,作用于后端数据发生更新,前端需要随之更改页面,新旧虚拟dom的比较
说说你对keep-alive的理解?
什么是响应式设计?响应式设计的基本原理是什么?如何做?
响应式设计:
一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整
基本原理:
通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有meta声明viewport
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no”>
其中:
width=device-width: 是自适应手机屏幕的尺寸宽度
maximum-scale:是缩放比例的最大值
inital-scale:是缩放的初始化
user-scalable:是用户的可以缩放的操作
如何做:
媒体查询
//当视口在375px - 600px之间,设置特定字体大小18px
@media screen (min-width: 375px) and (max-width: 600px) {
body {
font-size: 18px;
}
}
//当视口在1920时,设置背景颜色为红色
@media screen and (max-width: 1920px) {
body{
background-color:'red'
}
}
百分比
vw/vh
rem
说说 React 生命周期有哪些不同阶段?每个阶段对应的方法是?
创建阶段:
constructor
getDerivedStateFromProps
render
componentDidMount
更新阶段:
getDerivedStateFromProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
componentDidUpdate
销毁阶段:
componentWillUnmount
如何解决跨域问题?
前端方法就用jsonp
后端使用cors跨域
Nginx反向代理
修改header
移动端使用window.postMessage
如何优化webpack打包速度
使用监听模式或热更新热替换
开发环境不做无意义的操作
选择一个合适的devtool属性值
代码压缩用ParallelUglifyPlugin代替自带的 UglifyJsPlugin插件
代码压缩用ParallelUglifyPlugin代替自带的 UglifyJsPlugin插件
使用fast-sass-loader代替sass-loader
babel-loader开启缓存
不需要打包编译的插件库换成全局<script>标签引入的方式
使用 DllPlugin 和 DllReferencePlugin
提取公共代码
使用HappyPack来加速构建
优化构建时的搜索路径
理一下打包构建涉及的模块,分析看有哪些包是不需要打包的,只打包需要的模块(导出编
译JSON文件)
使用ModuleConcatenationPlugin插件来加快JS执行速度
使用noParse
使用异步的模块加载
以模块化来引入
说说react router有几种模式?实现原理?
react router有两种模式:
hash 模式、history 模式
实现原理:
路由描述了URL与UI之间的映射关系,这种映射是单向的,即 URL 变化引起 UI 更新(无需刷新页
面),以hash模式为例子,改变hash值并不会导致浏览器向服务器发送请求,浏览器不发出请
求,也就不会刷新页面;hash 值改变,触发全局 window 对象上的 hashchange 事件。所以 hash
模式路由就是利用 hashchange 事件监听 URL 的变化,从而进行 DOM 操作来模拟页面跳转
react-router也是基于这个特性实现路由的跳转
从浏览器地址栏输入url到显示页面的步骤
浏览器根据请求的 URL 交给 DNS 域名解析真实ip,向服务器发起请求
服务器将请求交给后台处理,处理完成后将处理好的数据返回,浏览器接收文件
浏览器对加载到的资源进行语法解析,建立相对应的内部数据结构
载入解析到的资源文件,完成页面的渲染
说说JavaScript中的数据类型?存储上的差别
Number、String、Boolean、Undefined、null、symbol
存储上的差别:
Number:
整数类型格式则为十进制,还可以设置八进制(零开头)、十六进制(0x开头)
浮点类型则在数值汇总必须包含小数点,还可通过科学计数法表示
String:
字符串可以使用双引号(")、单引号(')或反引号(`)标示
字符串是不可变的,意思是一旦创建,它们的值就不能变了
Boolean:
布尔值类型有两个字面值:true和false
通过布尔值可以将其他类型的数据转化成布尔值
Undefined:
Undefined类型只有一个值,就是特殊值 undefined。当使用var或let声明了变量但没有初始化时,就相当于给变量赋予了undefined值
null:
null类型同样只有一个值,即特殊值 null
逻辑上讲, null 值表示一个空对象指针,这也是给typeOf传一个 null会返回"object"的原因
undefined值是由 null值派生而来
symbol:
Symbol (符号)是原始值,且符号实例是唯一、不可变的。符号的用途是确保对象属性使用唯一
标识符,不会发生属性冲突的危险
说说对React Hooks的理解?解决了什么问题
Hook是 React 16.8 的新增特性,可以让你在不编写class的情况下使用state以及其他的React特性
解决的问题:
难以重用和共享组件中的与状态相关的逻辑
逻辑复杂的组件难以开发与维护
类组件中的this增加学习成本
类组件在基于现有工具的优化上存在些许问题
由于业务变动,函数组件不得不改为类组件等等
说说你对promise的了解
是什么:
Promise是最早由社区提出和实现的一种解决异步编程的方案,主要用于解决回调地狱问题
特点:
(1)执行状态不受外部影响
(2)Promise的状态一旦改变,就不会再变
(3)状态不可以逆
用法:
(1)promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,为两个
函数。resolve是在异步任务执行成功时调用,reject是在失败时调用。
(2)promise实例生成以后,可以通过then方法指定resolved状态和rejected状态的回调函数。
then方法可以接受两个回调函数作为参数:第一个回调函数是Promise对象的状态变为resolved时
调用,第二个回调函数是Promise对象的状态变为rejected时调用。这两个函数都接受Promise对象
传出的值作为参数
(3)promise对象还可以实现链式调用
说说webpack中常见的Loader?解决了什么问题?
常见loader:
css-loader:分析css 模块之间的关系,并合成⼀个css
style-loader:把css-loader生成的内容,用style标签挂载到页面的head中
less-loader:开发中,我们也常常会使用less、sass、stylus预处理器编写css样式,使开发效率提
高,这里需要使用less-loader
raw-loader:在webpack中通过import方式导入文件内容,该loader并不是内置的,所以首先要安
装,然后在 webpack.config.js 中进行配置
file-loader:把识别出的资源模块,移动到指定的输出⽬目录,并且返回这个资源在输出目录的地
址(字符串)
url-loader:可以处理理file-loader中的所有事情,但是遇到图片格式的模块,可以选择性的把图片
转成base64格式的字符串,并打包到js中,对小体积的图片比较合适,大图片不合适
说说 React中的setState执行机制
在react合成事件中,是异步的;如果在dom原生事件中,是同步的
在合成事件中,也可以是同步的,当setState中设置回调函数时,该函数是同步的
Vue组件之间的通信方式都有哪些
方式:
通过 props 传递
通过 $emit 触发自定义事件
使用 ref
EventBus
$parent 或$root
attrs 与 listeners
Provide 与 Inject
Vuex
场景:
父子关系的组件数据传递选择 props
与 $emit
进行传递,也可选择ref
兄弟关系的组件数据传递可选择$bus
,其次可以选择$parent
进行传递
祖先与后代组件数据传递可选择attrs
与listeners
或者 Provide
与 Inject
复杂关系的组件数据传递可以通过vuex
存放共享的变量