前端面试题总结

 

1.h5新增特性和css3新增特性

1.h5新增了header,nav,aside,footer,section等语义化标签

2.表单方面(input)增加了color,email,data,range等类型,

3.存储方面提供了sessionStorage,localStorage,和离线存储,这些方式方便数据再客户端存储和获取

4.多媒体有音频和视频元素audio和vedio,地理定位,canvas 画布,拖放,多线程编程webworker和websocket协议

5.css3新增特性有 边框如border-radius,box-shadow等

背景如background-size,background-origind等,

2D,3D转换如transform等,

动画如animation等

2.BFC的理解

bfc就是块级格式化上下文,它在页面有一套属于自己的渲染规则

内部的盒子会在垂直方向上一个接一个的位置 vvg

对于同一个bfc的两个相邻的盒子margin会发生重叠

bfc区域不会与float元素区域重叠

计算bfc高度时,浮动子元素也参与计算了

3.说说你对盒模型的理解?

首先盒模型有两种模型,分别是iE盒模型和w3c标准盒模型

ie盒模型总宽度就是 宽度=边框+内边距+内容宽度

标准盒模型总宽度=边框+内边距+宽度

4.如何实现两栏布局,右侧⾃适应?三栏布局中间⾃适应呢?

使用float左浮边栏

右边模块使用margin-left撑出内容做内容展示

在父级元素添加BFC,防止下方元素飞到上方内容

也可以使用flex弹性布局

实现三栏布局:两边使用float,中间使用margin

5.CSS如何画⼀个三⻆形?原理是什么?

div { border-top: 50px solid yellowgreen; border-bottom: 50px solid deeppink; border-left: 50px solid bisque; border-right: 50px solid chocolate; } 利用了高宽为零的容器及透明的 border 实现

(也可以是使用图片和svg完成三角形)

6.em/px/rem/vh/vw区别?

em:相对单位,基准点为父节点字体的大小,

px:绝对单位,页面按精确像素展示,

rem:相对单位,root em,相对根节点html的字体大小来计算

vh,vw:主要用于页面视口大小布局,在页面布局上更方便简单

7.Ajax原理是什么?如何实现?

ajax是一种创建交互式网页应用的网页开发技术,可以在不重新加载网页的情况下,与服务器交换数据,并且更新部分网页

首先创建ajax的核心对象xmlhttpRequest对象,通过这个对象的open()方法与服务器建立连接,构建请求简历所需的数据内容,通过xmlhttpRequest对象send()发送给服务器端,通过xmlhttpRequest对象提供的onreadystatechange事件监听服务器端的通信状态,

接受并处理服务端向客户端相应的数据结果,

将处理结果更新到html页面中

8.数组的常⽤⽅法有哪些?

push()
unshift()
splice()
concat()
pop()
shift()
slice()
indexOf()
includes()
find()
reverse()
sort()
join()
some()
every()
forEach()
filter()
map()

9.bind、call、apply** **区别?如何实现⼀个bind?

这三个都可以改变函数的this对象指向,第一个参数都是this要指向的对象,没有这个参数或参数为undefined或null,默认指向全局window,

都可以传参,apply是数组,call是参数列表,他俩都是一次性传入参数,bind可以分多次传入,bind是返回绑定this之后的函数,apply和call是立即执行

实现bind有三部分

修改this指向 ,传递动态参数 , 兼容new关键字

10.Javascript本地存储的⽅式有哪些?区别及应⽤场景

在h5之前都是采用cookie,使用cookie需要进行二次封装

localstorage和sessionstorage都是h5新增的两个api方法.localstorage称之为数据持久化

sessionstorage称之为会话存储。

他们和cookie最大的区别就是cookie有过期时间,这两个本地存储的方法不手动清除就会一直存储,使用起来更加简洁和方便

11.说说你对闭包的理解?闭包使⽤场景

闭包就是打通了一条在函数外部访问函数内部作用域的通道,通常是访问不到的

优点:可以隔离作用域,不造成全局污染

缺点:闭包长期驻留,会导致内存泄漏,将暴露全外部的闭包变量置为null就可以解决

使用场景:封装组件,for循环和定时器结合

for循环和dom事件结合,优化的过程中

节流防抖函数的使用,导航栏获取下标的使用

12.深拷贝和浅拷贝

浅拷贝就是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝

深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

实现深拷贝:

-.cloneDeep()

jquery.extend()

json.stringify()

13.说说JavaScript中的数据类型?存储上的差别?

在js中分为两种数据类型,

基本类型。复杂类型

基本数据类型存储在栈中

引用类型的对象存储于堆中

基本类型主要分为6种

number

string

boolean

undefined

null

symbol

复杂类型统称为object

object

array

function

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

防抖:所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

节流:所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数

相同点:都可以使用setTimeout实现

目的都是,降低回调执行频率,节省计算资源

不同点:函数防抖关注一定事件连续触发事件,只能最后执行一次,函数节流一段时间只执行一次

如何实现:防抖在连续的事件,只触发一次回调的场景有:搜索框搜索输入,需要用户最后一次输入完,再发送请求

手机号邮箱验证输入检测窗口大小 resize,只需窗口调整完成后,计算窗口大小,防止重复渲染。

15.解释下什么是事件代理?应⽤场景

事件代理:把一个元素响应事件的函数委托另一个元素

事件委托:把一个或者一组元素的事件委托到它的父层或者外层元素上,真正绑定事件的是外层元素,不是目标元素

应用场景:一个列表种有大量的列表项,我们就可以在点击列表项的时候响应一个事件

16.说说你对事件循环(Event Loop)的理解?

js是一门单线程的语言,同一时间只能做一件事,

在js中,所有的人物都可以分为

同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行

异步任务:异步执行的任务,比如ajax网络请求,setTimeout定时函数等

17.Javascript如何实现继承

js继承主要分为es5和es6继承

es5实现继承主要基于prototype来实现三种方法

1.原型链继承

2.构造函数继承

3.组合继承

es6是class继承

18.说说 JavaScript 中内存泄漏的⼏种情况?

内存泄漏就是计算机科学中,由于疏忽或错误造成程序未能释放已经不在使用的内存

常见内存泄漏情况:

意外的全局变量

定时器也常会造成内存泄漏

没有清理对dom元素的引用同样造成内存泄漏

19.说说new操作符具体⼲了什么?

new操作符用于创建一个给定构造函数的实列对象

new的实列可以访问构造函数里的属性也能访问原型上的方法

20.说⼀下JavaScript原型,原型链的理解?

每个对象拥有一个原型对象

每个对象的proto都是指向它的构造函数的原型对象prototype

原型链的理解:

访问一个对象属性时,会搜寻对象的原型,还有该对象的原型的原型,层层搜索,直到找到一个名字匹配的属性

21.如何实现上拉加载,下拉刷新?

这两个都依赖用户交互

上拉加载的本质是页面触底,或者快要触底是的动作下拉刷新

下拉刷新的本质是页面置于底部,用户下拉时需要触发的动作

22.说说ES6新增特性都有哪些?

es6新增特性 let/const,箭头函数,模板字符串,解构赋值,扩展操作符,模块的导入和导出,promise,数组字符串扩展方法

23.你对作⽤域链的理解?

作用域:即变量和函数生效的区域或集合

分为:全局作用域

函数作用域

块级作用域

全局作用域下声明的变量可以在程序任意位置访问

函数作用域也是局部作用域,一个变量在函数内部声明他就在一个函数作用域下面,只能在函数内部使用,不能函数以外访问

块级作用域:let和const关键字,在大括号中使用let和const声明的变量存在于块级作用域,大括号之外不能访问这些变量

24.谈谈this对象的理解?

谁调用this,this就指向谁

在构造函数中this指向对象实列

在全局环境里this指向window

25.你是怎么理解ES6中 Promise的?使⽤场景?

promise就是es6中的一种异步解决方案,可以解决回调地狱的问题

所谓回调地狱就是不停的操作的结果只能通过回调函数的方式接受,这个方式的写法非常臃肿,后期难以维护,promise可以通过链式调用的方法来解决

promise一共有三个状态,分别是进行中,成功和失败

成功的话可以通过resolve方法返回出去,通过.then的方法进行接收

失败的话通过rejeck的方法返回出去,通过.catch的方式接受

pending状态时进行中,一旦进行,状态不可逆

截形封装以及a页面获取b页面的结果都可以使用promise来完成

26.说说var。let。 const之间的区别?

var声明的变量存在变量提升,后两者不会

var在全局作用域声明的变量会挂载到window上,后两者不会

let和const区别不到,const声明变量后不能重新赋值

27.说说javaScript原⽣有⼏种绑定事件⽅式?具体如何实现?

主要分为三种:

1.html事件处理程序

2.dom0级事件处理程序

3.dom2级事件处理程序

其中html不用了 因为不好维护,耦合度太高

dom0级事件,pc端用的比较多,兼容性好,可以先获取dom元素绑定事件

dom2级,移动端用的多,有专门的绑定和移除方法

28.说说jQuery有哪些选择器和常⽤查找⽅法?

基本选择器

层级选择器

(过滤选择器) 基本过滤选择器 内容过滤选择器 可见性过滤选择器 属性过滤选择器 子元素过滤选择器 表单对象过滤选择器 表单对象属性过滤选择器

查找方法:

find()

children()

filter

eq()

parent()

parents()

cloest()

29.判断JS数据类型的⽅法有哪些?

基本类型

引用类型

基本类型:string,number,boolean,symbol,undefined,null


引用类型:object

typeof:判断基本数据类型

instanceof:instanceof是判断实列的,比如a是否为b的实列,如果是,则返回true,不是的话返回false,instanceof是检测原型的

object.prototype.tostring.call(''):完美的解决方案

30.web常⻅的攻击⽅式有哪些?如何防御

web攻击(webttack)他是针对用户上网和网站服务器等设备进行攻击的行为

常见的攻击方式有

xss 跨站脚本攻击 :防范:csp,转义字符,httponly cookie

csrf跨站请求伪造 : 防范:

1.get请求不到数据进行修改

2.不让第三方访问到cookie

3.组织第三方网站请求接口

31.说说地址栏输⼊ URL **敲下回⻋后发⽣了什么?

url解芯

DNS 查询

tcp 连接

http请求

响应请求

页面渲染

32.说⼀下 GET POST 的区别?还有哪些提交⽅式?

get请求只能用于获取数据

post适用于将实体提交到指定的资源

get和post区别:

get在浏览器回退是无害的。post会再次提交请求

get产生的url地址可以被bookmacrk,post不可以

get请求会被浏览器cache,post不会,除非手动设置

get请求只能url编码,post支持多种编码

get请求参数会保留到浏览器记录,post不会

get比post不安全,参数暴露在url上,不能传递敏感信息

get参数通过url传递的,post放在request body中

33.什么是HTTP? HTTP HTTPS 的区别?

http就是超文本运输协议,传递信息是以明文的方式发送内容的,这不安全,https就是解决http不安全的特性

https是用了ssl/tls协议加密处理的,http没有,前者更安全

两者连接方式不同,端口也不同,http是80,https是443

https需要设计加密和多次握手,性能不如http

34.http缓存中,强缓存和协商缓存的区别?

1.触发的先后顺序不同,判断文件是否过期,没过期触发强制缓存,浏览器直接读取本地文件

文件过期触发协商缓存,发送请求询问服务器该文件是否更新 没有的话使用浏览器本地缓存,更新过的话则返回新的文件给客户端,更新新的过期事件缓存起来

2.强制缓存不访问服务器,协商缓存访问服务器

35.说说HTTP常⻅的状态码有哪些,适⽤场景?**

状态码第一位数字决定不同的响应状态

1表示消息

2表示成功

3表示重定向

4表示请求错误

5表示服务器错误

常见的状态码 适用场景

100:客户端发送post数据给服务器,看服务器是否处理post数据,不处理,则客户端不上传post数据,处理的话,post上传数据

206:做用于断点续传,或者视屏文件等大文件的加载

301:永久重定向会缓存,新域名替换,旧的不用时

用户访问旧域名时用301重定向到新域名

302:临时重定向不会缓存,常用于未登录的用户访问用户中心重定向到登录页面

304:协商缓存,告诉客户端有缓存,直接使用缓存中的数据,返回页面的只有头部信息,没有内容

400:参数有误,请求无法被服务器识别

504:网关超时

36.说说对WebSocket的理解?应⽤场景?

websocket是一种网络传输协议,在osi模型的应用层,单个tcp脸上上进行全双工通信,节省服务器资源和带宽达到实时通讯

特点:全双工,二进制帧,协议名,握手

优点:

较少的控制开销:数据包头部协议较小,不同于http每次请求需要携带完成的头部

更强的实用性:相对于http请求需要等待客户端发起请求服务端才能响应,延迟更少

适用场景:

弹幕

媒体聊天

协同编辑

基于位置的应用

体育实况更新

股票基金报价定时更新

37.vue3介绍

1.vue3性能更高,体积小

2.vue的组合式的api可以更好的代码服用,方便构建大型项目

3.对ts支持比较好

38.Vue3的新特性

数据响应式原理重新实现

数组的更新检测等bug,优化了响应监听的性能

proxy可以直接对整个对象劫持

虚拟dom 新算法

提供了compositon api,更好的逻辑服用

模板可以有多个根元素

39.defineProperty和proxy区别

1.defineproperty是属性劫持。proxt是对代理对象

2.defineproperty无法监听对象新增属性,proxy可以

3.defineproperty无法监听对象删除属性,proxy可以

40.Proxy 相对于 Object.defineProperty 有哪些优点?

代码执行的效果更快

proxy可以监听对象而非属性

proxy可以监听数组的变化

proxy有13种拦截方法,不限apply,has等等是object.defineProperty不具备的

41.Vue 3.0 所采用的 Composition Api 与 Vue 2.x 使用的 Options Api 有什么区别?

代码更靓丽与维护封装

vue2种,在一个vue文件种data.methods.computed.watch中定义属性方法,共同处理页面逻辑

vue3中用setup函数代替了vue2中befarecreate和created

42.vue2和vue3区别

1.首先vue2和vue3的双向数据绑定原理发生了改变:

vue2的双向数据绑定利用了es5的api object.definepropert()对数据进行劫持 结合发布订阅来实现的,vue3使用了es6的proxyAPI对数据进行处理

2.vue3可以拥有多个根节点

3.建立数据data:

(1).vue2是把数据放入data中,vue3就需要使用一个新的setup()方法,此方法在组建初始化构造得时候触发

4.vue3得生命周期

setup()

onbeforemount

onmounted

onupdated

5.与模板一起使用时,需要返回一个对象

6.在setup()内使用响应式数据时,需要通过,value获取

7.setup函数只能是同步得不能是异步得

43.vue2和vue3双向数据绑定的区别

vue2使用object.defineproperty方法监听属性得get和set来实现双向绑定得

vue3使用了es6新语法,用proxy去实现监听,这样省去克隆对象得步骤,只需要定义一次proxy就可以实现对象得监听,不同分别定义

44.Vue项⽬中有封装过axios吗?主要是封装哪⽅⾯的

随着项目规模增大,每发一次http请求,就要设置超时时间。设置请求头,根据项目环境判断使用请求地址,错误处理,都要写一遍

45.Vue组件之间的通信⽅式都有哪些?

父传子:

在父组件里的子组件挂载传输得值,子组件通过props来接受参数

子传父:

在父组件里得子组件绑定事件,子组件通过$emit触发绑定在父组件中得事件

兄弟组件:

eventBus,创建空的文件,导出来,在这个文件中通过on方法接受数据,通过emit发送数据

vuex

46.Vue项⽬中你是如何解决跨域的呢?

cors:增加一些http头,让服务器能声明与允许访问来源只要后端实现了cors。

proxy:它可以允许客户端通过这个服务与另一个网络终端服务器,进行连接,可以具备网络代理功能这样有利于保障网络终端隐私和安全,防止攻击

47.为什么data属性是⼀个函数⽽不是⼀个对象?

data是函数得话 ,每复用一次就会放回新的函数,相当于给每个组件创建一个私密数据空间,这样组件都维护自己得数据

如果是对象的话,所有组件都会共享一个数据,

所以data必须是一个函数。

48.动态给vue的data添加⼀个新的属性时会发⽣什么?怎样解决

数据更新,单页面不会更新

解决方法:

vue不允许在已经创建的实例上动态添加新的响应式属性,如果想实现数据与视图同步更新,一般用Vue.set(), Object.assign(), $forcecUpdated()

49.你了解vue的diff算法吗

vue得diff算法是平级比较,不考虑跨级的话

内部采用深度递归得方式+双指针方式比较

先比较两个节点是不是相同点,相同点比较属性

父用老节点

先比较儿子节点,对比新老节点得情况,优化比较

头头,尾尾,对比查找,进行复用

50.vue指令

v-html:解昕html标签

v-text:渲染文本,不能识别html标签

v-model:双向绑定

v-bind:绑定属性得指令

v-on:用于绑定事件,简写@

v-if:判断指令

v-show:控制元素显示隐藏

v-for:循环语句

51.Vue中的过滤器了解吗?过滤器的应⽤场景有哪些?

分为全局过滤器和局部过滤器

全局过滤器在vue.filter中定义,可以在任何地方使用,局部在组件内定义

应用场景:

转换,数字打点,文本格式化,时间格式化

52.SPA⾸屏加载速度慢的怎么解决

首屏加载:

浏览器从响应用户输入网址地址,到首屏内容得时间

加载慢得原因:

网络延迟

资源文件体积大

资源重复发送请求去加载了

解决方法:

减小入口文件体积

静态资源本地缓存

ui框架按需加载

图片资源得压缩

组件重复打包

使用SSR

53.v-if和v-for的优先级是什么?

v-for比v-if优先级高,因为从v-for阶段开始渲染,

v-if还无法判断

v-if和for不能在一个元素使用,一般用div,或者template标签包裹,v-if写在标签上面,v-for写里面

54.说说你对keep-alive的理解是什么?

keep-alive是内置组件,缓存不运动得组件,组件来回切换得时候会被销毁,这个时候就可以用keep-alive来完成

55.你知道vue中key的原理吗?说说你对它的理解

key是每一个vnode得唯一id,也是diff得优化策略

可以根据key更准确,更快得找到对应得vnode节点

56.请描述下你对vue⽣命周期的理解?

vue生命周期就是从创建到销毁的过程

一共11个钩子函数

beforecreate:创建之初

created:组件实列完全创建

beforemout:组件挂载之前

mounted:组件挂载实列上去之后

beforeupdate:组件数据发生变化,更新之前

updated: 组件数据更新之后 beforeDestroy: 组件实例销毁之前 destroyed: 组件实例销毁之后 activated: keep-alive 缓存的组件激活时 deactivated: keep-alive 缓存的组件停⽤时调⽤ errorCaptured: 捕获⼀个来⾃⼦孙组件的错误时被调⽤

组件在一开始创建的时候就触发了创建前后,和挂载前后的钩子函数,而更新的钩子函数需要data中的数据发生改变才会触发,销毁的钩子函数在组件来回切换的时候就会自动被销毁

我们经常在created中请求数据,在mounted中做一些dom操作。

57.Vue.minxin的使用场景和原理?

vue.mixin 作用域抽离公共得业务逻辑,类似对象的继承

当组件初始化会调用mergeoptions方法进行合并,采用策略模式针对不同的属性进行合并

混入的数据和本身组件的数据冲突,会采用就近原则

58.Vue中的$nextTick有什么作⽤?

通过vue.$nexttick我们可以注册一个回调函数,会在下个dom节点执行完毕之后执行,这样修改了数据之后页面也不会刷新,

用dom就获取数据的话,依旧是以前的旧数据,使用$nextTick来解决

59.vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做

前端权限控制分为四个方面:

接口权限

按钮权限

菜单权限

路由权限

按钮权限:

1.按钮权限也可以用v-if判断

2.通过自定义指令进行按钮权限的判断

60.v-show和v-if有什么区别?使⽤场景分别是什么?

v-show和v-if都是控制显示隐藏的

v-if比较耗费性能,会删除对应dom节点

v-show是通过css中的dispalay来控制,如果是频繁使用显示隐藏,推荐使用v-show.不频繁则用v-if

搜索和登录的密码框中都会用到v-if和v-show

61.v-if原理

v-if 在实现上比v-show要复杂的多,因为有else else-if等条件需要处理,我们只能摘抄源码中处理v-if的一小部分

62.虚拟DOM是什么?有什么优缺点?

虚拟dom就是用js对象,是对真是dom的抽象描述

直接操作dom性能低,js操作效果高,dom操作转化成对象操作

通过diff算吗对比差异进行更新dom

优点是保证性能的下限。

63.说⼀下watch,methods和computed的区别?

watch是监听属性,属性发生改变就会变动

methods:定义方法的地方,methods方法调用才会触发,不具备缓存性

computed:计算属性,属性发生改变就会重新计算,具有缓存性

64.为什么vue采用异步渲染 ?

vue是组件级更新,当前组件数据变了,就会更新这个组件,数据更改一次就要重新渲染一次,性能不高,为了防止数据已更新就更新组件,做了异步更新渲染

65.Vue 解决了什么问题

1虚拟dom,不在使用原生dom操作节点,还了一种方式,解放了dom操作

2.视图,数据,结构分离:数据更改更简单,不需要修改,操作数据就可以了

3.组件化:单应用各种模块拆分一个一个单独组件,便于开发后期的维护

66.Vue.js 的特点

简洁:html+json+vue

数据驱动

组件化

轻量

快速

模板友好

67.插槽的理解

将所携带的内容插入子组件指定的位置,内容在父组件中子组件的标签内定义,slot是组件内部的占位符

68.vue-router 有哪几种导航钩子

全局导航钩子:

beforeEach()路由进入之前执行的函数

afterEach()路由进入之后执行的函数

beforResolve()2.5新增

单个路由

beforeEnter()

beforeLeave()

组件路由钩子

beforeRouteEnter()

beforeRouteLeave()

beforeRouteUpdate()

69.路由懒加载

可以将页面进行划分,需要的时候加载,分担加载压力,减少首页加载用时

原理:vue异步组件技术:异步加载,vue-touter配置路由,vue异步组件技术,实现按需加载

70.Vue.js 介绍

vue.js是一个轻巧高性能,组件化mvvm库,拥有容易上手得api,渐进式框架,容易学习,核心是一个响应得数据绑定系统

71.请说出 vue.cli 项目中 src 目录每个文件夹和文件的用法

assets 放静态资源

components 放组件

router 定义路由

view 视图

app.vue应用著组件

man.js入口文件

72.Vue 怎么兼容 IE

babel-polyfill插件

73.MVVM 的理解

mvvm视图和业务逻辑分开

view:试图

model:数据模型

viewmodel:两者得桥梁

74.Vue 怎么重置 data

用object.assign(). vm$data获取data

vm.$options.data获取组件初始化得data

75.组件中写 name 选项有什么作用

1.使用keep-alive时,搭配组件name进行缓存过滤

2.dom做递归组件调用自身name

3.vue-devtools调式工具显示组件名称由vue里的name决定

76.route 和 router

route 路由信息对象

router 路由实列对象

77.Vue 修饰符有哪些

.stop组织事件继续传播

.prevent阻止标签默认行为

.self只当在enent target是当前元素自身触发处理函数

.once事件只触发一次

.passive告诉浏览器不想阻止事件默认行为-

78.不需要响应式的数据应该怎么处理?

一些从始至终都没改变得数据,这些死数据,不改变,就不需要对他做响应式处理,不然只是做一些无用功消耗性能

79.virtual-dom 原理实现

virtual-dom是react框架非常重要得特性之一(简称vdom)vdom定义真实dom创建节点,删除节点,添加节点,将这些复杂得操作放在vdom进行

80.vue-cli 替我们做了哪些工作

vuecli是基于vue.js快速开发的完整系统

vue文件--->js文件

es6语法--->es5语法

sass less stylus--->css

81.axios拦截器

分两种:请求拦截器,响应拦截器

请求拦截器在请求发送前进行必要得操作,比如同意cookie,请求体加验证,设置请求头,相当于每隔接口相同操作得一个封装

相应拦截器有同样得功能,只是请求响应之后,对响应体得处理都是数据统一处理,也常判断登录失效

82.Vue2.0 响应式数据的原理

数据劫持+观察者模式

使用object.defineproperty将属性进行劫持(劫持已经存在得属性)

数组用重写数组得方法实现,页面使用对应属性都拥有自己得dep属性

存放依赖watcher(依赖收集)变化后通知自己对应的watcher去更新

(派发更新)

83.Vue如何检测数组变化

数组考虑性能原因没有用defineproperty对数组每一项进行拦截,而是选择七种数组

(push,shift,pop,splice,unshift,sort,reverse)进行重写

vue中修改数组得索引和长度无法监控,通过以上七种变异方法修改数组才触发watcher进行更新

84:双向绑定的原理?数据劫持原理

mvvm双向绑定,

1.数据劫持:

vue2用object.defineproperty()方法来实现数据劫持,为每个属性分配一个订阅者集合得管理数组dep

vu3用es6得proxy构造函数来实现数据劫持

2.添加订阅者:

在数组dep添加订阅者,v-model添加一个订阅者,v-bind也会

3.input添加监听事件

input添加监听事件修改值会为该属性赋值,触发属性set()方法,set()方法通知订阅者数组dep,

订阅者数组循环调用各订阅者得undate()方法更新试图

数据劫持核心:

object.defineproperty()方法

简单点来说就是通过此方法定义一个值

调用get方法

赋值set方法

85.v-for 为什么要加 key

vue中列表循环需加:key="唯一标识" 唯一标识尽量是item里面id等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用主要是为了高效的更新虚拟DOM。

2.key主要用来做dom diff算法用的,diff算法是同级比较,比较当前标签上的key还有它当前的标签名,如果key和标签名都一样时只是做了一个移动的操作,不会重新创建元素和删除元素。

3.没有key的时候默认使用的是“就地复用”策略。如果数据项的顺序被改变,Vue不是移动Dom元素来匹配数据项的改变,而是简单复用原来位置的每个元素。如果删除第一个元素,在进行比较时发现标签一样值不一样时,就会复用之前的位置,将新值直接放到该位置,以此类推,最后多出一个就会把最后一个删除掉。

4.尽量不要使用索引值index作key值,一定要用唯一标识的值,如id等。因为若用数组索引index为key,当向数组中指定位置插入一个新元素后,因为这时候会重新更新index索引,对应着后面的虚拟DOM的key值全部更新了,这个时候还是会做不必要的更新,就像没有加key一样,因此index虽然能够解决key不冲突的问题,但是并不能解决复用的情况。如果是静态数据,用索引号index做key值是没有问题的。

5.标签名一样,key一样这时候就会就地复用,如果标签名不一样,key一样不会复用。

86.vue-router路由钩子函数是什么执行顺序

全局守卫,路由守卫,组件守卫

87.this的指向

1.在全局作用域

=>this -> window

2.在普通函数中

=>this取决于谁调用,谁调用我,this就指向谁,跟如何定义无关

3.箭头函数中的this

箭头函数没有自己的this,箭头函数的this就是上下文中定义的this,因为箭头函数没有自己的this所以不能用做构造函数。

4.定时器中的this

定时器中的this->window,因为定时器中采用回调函数作为处理函数,而回调函数的this->window

5.构造函数中的this

构造函数配合new使用, 而new关键字会将构造函数中的this指向实例化对象,所以构造函数中的this->实例化对象

88.new关键字会在内部发生什么

//第一行,创建一个空对象obj。 var obj ={}; //第二行,将这个空对象的proto成员指向了构造函数对象的prototype成员对象. obj.proto = CO.prototype; //第三行,将构造函数的作用域赋给新对象,因此CA函数中的this指向新对象obj,然后再调用CO函数。于是我们就给obj对象赋值了一个成员变量p,这个成员变量的值是” I’min constructed object”。 CO.call(obj); //第四行,返回新对象obj。 return obj;

89.class语法糖

es6的面向是es5构造函数加原型方式生成对象的语法糖

class类

类 具有相同属性和方法的集合称为类

对象 对象是类的实例 一个类可以有多个对象 每个对象之间都是相互独立的

定义类

(1)创建一个对象; ​ (2)将构造函数的作用域赋值给新对象让this指向这个新对象; ​ (3)执行构造函数中的代码为这个新对象添加属性; ​ (4)返回新对象

继承类

在JavaScript中,继承是用来表示两个类之间的关系,子类可以继承父类的一些属性和方法,在继承以后还可以添加自己独有的属性和方法

1)定义父类和子类

2)调用父类中的方法

90.解构赋值

解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象或数组中取出,赋值给其他变量。

解构赋值有两种形式 数组 对象

能举出简单的案例

let {a,b}={"a":1,"b":2}

let [a,b]=[1,2,]

91.map和set

Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

Set 对象允许存储任何类型的唯一值,无论是原始值或者是对象引用

92.导入导出,模块化

模块化

export 和import

export default 和import

module.exports和require

1、export 和import

概念:根据功能封装模块 通过import导入 然后通过export导出

特点:

1、模块中可以导入和导出各种类型的数据,如函数,对象,字符串,数字,布尔值,类等。

2、每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域。

3、每一个模块只加载一次(是单例的), 若再去加载同目录下同文件,直接从内存中读取。

2、export default 和import

export default 是将所有的东西以一个整体的形式扔出的。import只接一个就行

在一个文件或模块中,export、import 可以有多个,export default 仅有一个。

93.首屏加载优化

1.使用CDN资源,减小服务器带宽压力 2.路由懒加载 3.将一些静态js css放到其他地方(如OSS),减小服务器压力 4.按需加载三方资源,如iview,建议按需引入iview中的组件 5.使用nginx开启gzip减小网络传输的流量大小 6.若首屏为登录页,可以做成多入口,登录页单独分离为一个入口 7.使用uglifyjs-webpack-plugin插件代替webpack自带UglifyJsPlugin插件 8.异步组件,类似路由懒加载 9.js外联文件放到body底部,css外联文件放到head内 10.http静态资源尽量用多个子域名 11.尽量减少http requests的数量 12.js/css/html/img资源压缩 13.使用css spirtes,可以减少img请求次数 14.大图使用lazyload懒加载 15.避免404,减少外联js 16.减少cookie大小可以提高获得响应的时间 17.减少dom elements的数量 18.使用异步脚本,动态创建脚本

94.promise和async和await的区别

相同点

  1. Promiseasync-await 都是优化异步编程体验的解决方案。

不同点

Promise 是应用层的解决方案,它有一个规范,不同的语言也可以实现,它只能异步的处理错误,在js 里它本质上是一个对象。

async-await 是语言层的解决方案,它可以说是 Promise的补充,可以让用户像编写同步代码一样编写异步代码,通过try-catch 可以同步地处理错误。

Promise 更多应用在函数封装中,async用在函数的使用中。

Promise链式调用相当于一个新的回调地狱, 也不能统一处理异常。 Promise 本身是同步函数,多个不会等待。

async-await用同步的写法使得可读性更强,同时方便 try-catch 捕获异常, async-await 有明确的前后关系,可读性好。

95.如何解决回调地狱

不同点 Promise 是应用层的解决方案,它有一个规范,不同的语言也可以实现,它只能异步的处理错误,在js 里它本质上是一个对象。

async-await 是语言层的解决方案,它可以说是 Promise的补充,可以让用户像编写同步代码一样编写异步代码,通过try-catch 可以同步地处理错误。

Promise 更多应用在函数封装中,async用在函数的使用中。

Promise链式调用相当于一个新的回调地狱, 也不能统一处理异常。 Promise 本身是同步函数,多个不会等待。

async-await用同步的写法使得可读性更强,同时方便 try-catch 捕获异常, async-await 有明确的前后关系,可读性好。

96.for of 和for in的区别

1.共性 for of 和 for in都是用来遍历的属性

2.区别 for...in 语句用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)。 for in得到对对象的key或数组,字符串的下标 for of和forEach一样,是直接得到值 for of不能用于对象

97.水平居中的方法

  1. 若是行内元素, 给其父元素设置 text-align:center,即可实现行内元素水平居中.

  2. 若是块级元素, 该元素设置 margin:0 auto即可.但是该元素一定要有宽度!

  3. 若子元素包含 float:left 属性, 为了让子元素水平居中, 则可让父元素宽度设置为fit-content,并且配合margin,

  4. 使用flex 布局, 可以轻松的实现水平居中, 子元素设置如下:

  5. 使用CSS3中新增的transform属性, 子元素设置如下:

98.常用的字符串数组的方法

push、pop、unshift、shift、forEach、filter、splice、findIndex、find、includes、sort

99.作用域链

一段代码起作用的范围 分为全局作用域和局部作用域

函数内部使用变量,先从当前函数查找,如果找不到,则继续向父级查找,如果还找不到继续往上一级查找,最后找到window对象,如果还找不到,则报错提示变量不存在,这种链条关系就是作用域链

100.事件

1、js事件绑定的方式有三种:

  1. 在DOM元素中直接绑定事件

  2. 在Script代码中获取节点然后绑l定事件

  3. 用 addEventListener() 或 attachEvent() 来绑定事件监听函数

2、addEventListener()事件监听函数的第三个参数默认false是冒泡 改为 true是捕获

3、vue和原生js阻止事件冒泡的方法是 e.stopPropagation() 和事件修饰符.stop()

4、事件委托

事件委托就是事件代理,把子元素的响应事件比如click委托给父元素,让父元素担当事件监听的职务

如何实现:可以用jquery里的$.on 和 js里的addEventListener()事件监听的捕获阶段

好处:1、减少内存消耗

2、动态绑定事件

101.Object.defineProperty()方法有何作用

在对象上定义一个新属性,因为vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图

102.跨域

域名的概念:ip地址的别名,域名和ip地址的关系就像人和面具

跨域是浏览器的安全策略,只有同域名 同端口号 同协议ajax才能访问,域名不同 端口号不一样 协议不一样就会跨域

用jsonp、cors、proxy解决跨域

jsonp与json

json是一种实现数据交换的轻量级的数据格式

JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题

jsonp的原理:script 的srcs属性不受同源策略的限制。

103.h5、c3新特性

h5:

语义化标签:header、nav、section、aside、footer

音频audio 和视频video

sessionStorage、localStorage

c3:

圆角:border-radius、盒子阴影 : box-shadow、盒子模型: box-sizing、背景:background-size、过渡动画 : transition 、自定义动画 animate、2D转换;transform: translate、3D转换:transform: translate3d104

104.flex

display指定 HTML 元素的盒子类型
flex-direction指定弹性盒子中子元素的排列方式
flex-wrap设置当弹性盒子的子元素超出父容器时是否换行
flex-flowflex-direction 和 flex-wrap 两个属性的简写
justify-content设置弹性盒子中元素在主轴(横轴)方向上的对齐方式
align-items设置弹性盒子中元素在侧轴(纵轴)方向上的对齐方式
align-content修改 flex-wrap 属性的行为,类似 align-items,但不是设置子元素对齐,而是设置行对齐
order设置弹性盒子中子元素的排列顺序
align-self在弹性盒子的子元素上使用,用来覆盖容器的 align-items 属性
flex设置弹性盒子中子元素如何分配空间
flex-grow设置弹性盒子的扩展比率
flex-shrink设置弹性盒子的收缩比率
flex-basis设置弹性盒子伸缩基准值

105.浏览器内核

1、IE浏览器内核:Trident内核,也是俗称的IE内核; 2、Chrome浏览器内核:统称为Chromium内核或Chrome内核,以前是Webkit内核,现在是Blink内核; 3、Firefox浏览器内核:Gecko内核,俗称Firefox内核; 4、Safari浏览器内核:Webkit内核; 5、Opera浏览器内核:最初是自己的Presto内核,后来是Webkit,现在是Blink内核; 6、360浏览器、猎豹浏览器内核:IE+Chrome双内核; 7、搜狗、遨游、QQ浏览器内核:Trident(兼容模式)+Webkit(高速模式); 8、百度浏览器、世界之窗内核:IE内核; 9、2345浏览器内核:以前是IE内核,现在也是IE+Chrome双内核;

106.this.$set实现什么功能,为什么要用它?

给对象加了一个属性,在控制台能打印出来,但是却没有更新到视图上时,也许这个时候就需要用到this.$set()这个方法了,

举个例子:

1.Vue写在template中的代码:

<div v-for="(item,index) in list" :key="index"
>{{item.name}}
</div>
<button @click="changeValue" type="primary">改变值</button>

</div>

{{item.name}}

<button @click="changeValue" type="primary">改变值</button>

2.export default{}中data数据

data(){ return { list:[ {name:'29Kun',id:1}, {name:'299Kun',id:2}, ] } }

3.点击按钮触发changeValue方法

mounted(){ this.list[2] = {name:'2999Kun',id:3} console.log(this.list[0]); }, methods: { changeValue(){ this.$set(this.list,2,{name:'2999kun',id:3}) } }

调用方法:this.$set( target, key, value ) target:要更改的数据源(可以是对象或者数组) key:要更改的具体数据 value :重新赋的值

107.什么是递归

什么是 递归

所谓的方法递归,就是在一个方法(函数)执行的内部自己调用了自己的过程,称之为 “递归”

递归分为两个子过程: 递过程:函数不断地调用自身,直到走到函数的终止条件,第一阶段结束。 归过程:函数不断地返回的过程。

对于一个大问题,给分解成多个具有相同性质的子问题,子问题再分解成多个子子问题...

最终递归触底,取得结果,然后回溯,取得上一级稍大一点的问题的结果,就这样逐步回溯,最终取得整个大问题的结果。

通常递归涉及到函数调用自身,用循环解决的问题,递归都可以解决。

使用递归,可以让我们的程序变得更优雅简洁,逻辑上可读性更强。

108.vue的生命周期

vue生命周期可以分为八个阶段,分别是:

beforeCreate(创建前)、created(创建后)、beforeMount(载入前)、mounted(载入后)、beforeUpdate(更新前)、updated(更新后)、beforeDestroy(销毁前)、destroyed(销毁后)

1、创建前(beforeCreate)

对应的钩子函数为beforeCreate。此阶段为实例初始化之后,此时的数据观察和事件机制都未形成,不能获得DOM节点。

2、创建后(created)

对应的钩子函数为created。在这个阶段vue实例已经创建,仍然不能获取DOM元素。

##beforeCreate和created函数都是在实例化Vue的阶段,在_init方法中执行的。beforeCreate和created的钩子调用是在initState函数的前后,initState的作用是初始化props、data、methods、watch、computed等属性,beforeCreate的钩子函数中就不能获取到props、data中定义的值,也不能调用methods中定义的函数,而created可以。在这俩个钩子函数执行的时候,还没有渲染 DOM,所均访问不到DOM

一般来说,如果组件在加载的时候需要和后端有交互,放在这俩个钩子函数执行都可以,如果是需要访问props、data等数据的话,就需要使用created钩子函数

3、载入前(beforeMount)

对应的钩子函数是beforemount,在这一阶段,我们虽然依然得不到具体的DOM元素,但vue挂载的根节点已经创建,下面vue对DOM的操作将围绕这个根元素继续进行;beforeMount这个阶段是过渡性的,一般一个项目只能用到一两次。

4、载入后(mounted)

对应的钩子函数是mounted。mounted是平时我们使用最多的函数了,一般我们的异步请求都写在这里。在这个阶段,数据和DOM都已被渲染出来。

##beforeMount和mounted函数执行在Vue实例挂载阶段,它们的调用时机是在mountComponent函数中。Vue组件在实例化的时候会先等待子组件的实例化完成,所以insertedVnodeQueue(保存组件的mounted钩子函数的数组)的添加顺序是先子后父

5、更新前(beforeUpdate)

对应的钩子函数是beforeUpdate。在这一阶段,vue遵循数据驱动DOM的原则;beforeUpdate函数在数据更新后虽然没立即更新数据,但是DOM中的数据会改变,这是Vue双向数据绑定的作用。

6、更新后(updated)

对应的钩子函数是updated。在这一阶段DOM会和更改过的内容同步。

##beforeUpdate和updated的钩子函数执行时机都是在数据更新的时候,beforeUpdate的执行时机是在 渲染Watcher 的before函数中,update的执行时机是在flushSchedulerQueue函数调用的时候

7、销毁前(beforeDestroy)

对应的钩子函数是beforeDestroy。在上一阶段vue已经成功的通过数据驱动DOM更新,当我们不在需要vue操纵DOM时,就需要销毁Vue,也就是清除vue实例与DOM的关联,调用destroy方法可以销毁当前组件。在销毁前,会触发beforeDestroy钩子函数。

8、销毁后(destroyed)

对应的钩子函数是destroyed。在销毁后,会触发destroyed钩子函数。

vue的生命周期的思想贯穿在组件开发的始终,通过熟悉其生命周期调用不同的钩子函数,我们可以准确地控制数据流和其对DOM的影响;vue生命周期的思想是Vnode和MVVM的生动体现和继承。

beforeDestroy和destroyed钩子函数的执行时机在组件销毁的阶段。beforeDestroy钩子函数的执行时机是在destroy函数执行最开始的地方,接着执行了一系列的销毁动作,包括从parent的children中删掉自身,删除watcher,当前渲染的VNode执行销毁钩子函数等,执行完毕后再调用destroy钩子函数 在$destroy的执行过程中,它又会执行vm.patch(vm._vnode, null)触发它子组件的销毁钩子函数,这样一层层的递归调用。所以destroy钩子函数执行顺序是先子后父,和mounted过程一样

109.vuex五大核心

Vuex有五个核心概念:

state, getters, mutations, actions, modules。

  1. state:vuex的基本数据,用来存储变量

在vue中使用 this.$store.state.userId

  1. geeter:从基本数据(state)派生的数据,相当于state的计算属性,具有返回值的方法

    在vue中使用 this.$store.getters.userIdDouble

    1. mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个符串的 事件类型 (type) 和 一个 回调函数 (handler)。 commit:同步操作,写法: this.$store.commit(‘mutations方法名’,值)

回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。

  1. action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。

    1. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

         简单来说就是可以把以上的 state、mutation、action、getters 整合成一个user.js,然后放到store.js里面

110.vue修饰符

stop 阻止冒泡(兼容) 等同于event.stopPropagation() 或 event.cancelBubble = true prevent 阻止默认行为 等同于event.preventDefault() capture 设置事件在捕获阶段执行 once 事件只执行一次,相当于addEventListener的第三个参数的passive设置为true passive 设置过passive之后不会再阻止事件的默认行为,即使有event.stopPropagation,相当于设置addEventListener的第三个参数的passive为true self 当target===this的时候执行,即当前元素本身触发点击事件时才执行

111.get set

1.什么是get和set方法。

get是获得属性的一种方法。 set是设置属性的一种方法。 get负责查询,不带任何参数。 set负责设置,是通过参数的形式传递。 2.get和set的使用方法。

get和set是方法,所以可以进行判断。 get一般是得到,需要返回。 set是创建,不需要返回。 每一个对象都有一个get和set方法。 如果调用的是对象内部的属性,命名格式是变量名前面添加。 3.get和set的定义。

在对象初始化时定义。 在对象定义后定义。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值