前端面试总结

171 阅读6分钟

1,MVVM框架 M是model,也就是数据 V是view,也就是视图 VM是viewmodel,是一个中介者 model数据驱动视图,通过viewmodel渲染视图view view事件监听,通过viewmodel改变数据model 从而实现数据双向绑定 vue就是典型的一个mvvm框架

2,vue数据双向绑定

底层通过Object.definedPropoty()里面的get和set方法来拿取数据实现数据双向绑定的

3,vue生命周期

beforCreate:元素创建,但data和methods还没有初始化 created:data和methods初始化 beforeMounte:el实例也就是dom还没有挂载 mounted:el实例也就是dom挂载,可以操作dom beforeUpdate:没有更新 updated:更新 beforedestory:还没销毁 destoryed:销毁

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

4,vue组件之间的传值

父给子:props,this.$parent.属性和方法 子给父:emit,ref 兄弟:vuex 祖孙:provide,inject

5,vuex五个属性

vuex单向数据流: 数据存储在实例里,组件中触发 Action,Action 提交 Mutations,Mutations 修改 State。 组件根据 State 或 Getters 来渲染页面。

state:数据 getters:类似于计算属性 multations:同步的,提交更改数据的方法,通过commit触发 actions:异步的,提交multions,但是不直接更改,是异步的操作,包裹着multions,通过dispatch触发 modules:模块化

6,闭包

函数中的函数,里面的函数可以访问外面函数的变量 优点:可以让变量长期保存在内存中 缺点:导致内存泄漏,影响网页性能,原因是把变量变成了全局变量 解决:使用完后,立刻释放资源,引用变量指向null 或者不用闭包

7,作用域

变量只能向上访问,访问到window,不能向下访问

8,原型链

属性写在构造函数里,方法挂在原型上 每构建一个函数,就会有一个原型,调用函数属性时,自身没有找到,就会顺着原型一直往上找,到object.prototype.proto=null就不往上找了

9,继承

原型链继承:要继承的原型链等于被继承的实例化对象 在构造函数中:用call,apply方法继承 es6用extends

10,变量提升和函数提升

提升都是要先声明变量和函数 不同点: 变量提升中,只是变量声明被提升了,变量赋的值不会被提升, 函数提升中,函数体一起被提升, 函数表达式里,只提升声明,不提升函数体

11,let和const和var

let,const生成块级作用域,声明的变量不会被变量提升,不能重复定义 var不会产生块级作用域,有变量提升 const是常量,不可以修改,必须初始化

12,this指向

谁调用指向谁 全局指向window 回调函数指向window apply,call,bind调用这个函数的对象 构造函数指向实例化对象

更改this指向:apply,call,bind call 是第一个参数是this值没有变化,变化的是其他参数都直接传递给函数,传递函数的参数必须逐个列举出来 apply是使用一个参数数组,而不是参数列表 bind是新创建一个函数,与被调用函数有一个相同的函数体,被调用时指向bind绑定的第一个参数上

13,线程和进程

线程是最小的执行单元 进程是最小的资源管理单元 一个线程只能属于一个进程 一个进程可以有多个线程,但至少有一个线程 js是单线程,否则会出现以谁为准的问题,有利于提高效率 浏览器是多线程,网页占有率低,多个网页共同进行 js可以实行异步函数原理:ja单线程,依赖浏览器的多线程,同时进行

14,get和post

get参数放在url中,大小受浏览器限制2k-8k,安全性差, post参数放在header中,最小2M大小无上限,安全性强

15,ajax原理

创建小黄人对象,open打开请求,send发送请求,接收响应,200请求成功

16,readyState中五步

0请求初始化,1请求已提出,2请求已发送,3返回部分数据,4请求完成接收全部数据

17,jsonp 利用script标签的src属性中的链接,可以访问跨域的js脚本

18,优化

懒加载,精灵图,代码压缩合并,减少http请求和dom操作

19,网页输入网址到渲染的过程

输入网址 发送到dns服务器,获取对应的web 服务器对应的ip地址 与web服务器建立tcp连接 浏览器向web服务器发送http请求 web服务器响应请求返回数据 浏览器下载服务器返回的数据,解析html文件 生成dom树,解析css,js文件直到页面渲染完成

20,虚拟dom

会用js对象结构表示dom结构,用这个结构一个真正的dom结构在文档中,状态变更就比较差异,将不同的构建到真正dom树上,让视图更新

21,document.load和ready区别

load是等页面图片,样式等所有的东西等加载完才执行js,没有简写 ready是dom树加载完就执行js,多种简写

22,null和undeifned

null是没有对象,转为数值是0 undefined是缺少值,转为数值是NaN

23,数据类型

基本类型:number,null,undefined,boolean,string 引用类型:object,array,function 新增加的:symblo

引用类型和基本类型的区别:

1)存储位置不同 基本类型的是将变量存储在栈内存中,比如在一个函数里声明一个变量,当执行完这个函数,这个变量会自动销毁 引用类型的变量名放在栈内存中,但是值放在堆内存中,变量不会自动销毁,没有引用变量引用它时,系统垃圾回收机制会处理它 2)复制方式不同 基本类型是深复制,直接将值复制走,彼此就不会互相影响 引用类型是浅复制,值互相影响 3)基本类型不能添加属性和方法,但引用类型可以 4)基本类型的比较是比较值,引用类型是比较地址值

24,深拷贝,浅拷贝

深拷贝就是A复制一个B的值,B发生改变了,A不改变 深拷贝方式:Json.stringify和Json.parse,for…in 浅拷贝就是B改变了,A也会跟着改变 浅拷贝方式:object.assign 解决浅拷贝方法就是:1)一个一个复制赋值2)转为字符串再转json 3)递归函数,将要拷贝的对象循环遍历到一个新对象里

25,重构就是重绘,回流 重绘:元素的外观发生改变,不会影响整体布局大小 回流:元素大小,布局等发生一系列改变,需要重新渲染页面触发浏览器的行为

每个页面都会在第一次加载时触发回流 回流一定会触发重绘,但是重绘不一定触发回流

减少重绘回流方法: 减少一个一个的更改样式,用className更改 离线处理,用display:none设置好再显示

26,computed 和watch区别

computed:计算,是页面中某个数据依赖其他数据而改变时,可以使用computed,在data中没有声明的数据也可以在computed中写入,适用场景是一个数据受多个数据影响  具有缓存能力,所以只有当数据再次改变时才会重新渲染,否则就会直接拿取缓存中的数据。

watch:观察,一个数据变化同时需要异步操作时可以使用watch,但没有声明的不能使用,适用场景时一个数据影响多个数据 deep:true 当你需要在数据变化响应时,执行异步操作,或高性能消耗的操作,那么watch为最佳选择

对象和数组都是引用类型,引用类型变量存的是地址,地址没有变,所以不会触发watch。这时我们需要进行深度监听,就需要加上一个属性 deep,值为 true

27,promise和async await

promise: 两个参数resolve 和reject 成功走resolve,失败走reject 能连续打点调then then接收的必须是resolve catch接收的是reject 缺点是不够简洁,需要一层一层的将返回值传递给下一层,异常不会向上抛出没有写catch 就不会自动向外抛出,代码调试每个then都必须设置断点

promise.all([fn1,fn2]),等所有数据都返回后才正常显示,返回一个数组,数组里的数据顺序按照接受参数顺序排序 promise.race([race]),比赛,哪个快返回哪个结果,不管成功还是失败

所以async await应运而生 async await: 是await后面跟一个promise函数,必须等promise有返回值了才执行下面的代码 代码简介,可以捕捉异常

28,常用的css3动画属性

css3新属性:背景图,动画,过渡,文字阴影等 @keyframs 动画名{动画时长,次数,曲线程度等) transition transform rorate animation

@keyframes changeOpacity { from { opacity: 1; } to { opacity: .2; } } animation: changeOpacity 1.04s ease infinite animation-delay: 0.13s;

29,webpack

设置loader: css:style-loader,css-loader 图片:url-loader,file-loader js:babel-loader

css-loader和style-loader模块是为了打包css的 abel-loader和babel-core模块时为了把ES6的代码转成ES5 url-loader和file-loader是把图片进行打包的。

设置单个和多个文件入口: //入口文件的配置项 entry:{ entry:'./src/entry.js' }, //出口文件的配置项 output:{ //输出的路径,用了Node语法 path:path.resolve(__dirname,'dist'), //输出的文件名称 filename:'bundle.js' }, //入口文件的配置项 entry:{ entry:'./src/entry.js', //这里我们又引入了一个入口文件 entry2:'./src/entry2.js' }, //出口文件的配置项 output:{ //输出的路径,用了Node语法 path:path.resolve(__dirname,'dist'), //输出的文件名称 filename:'[name].js' },

30,vue打包之后产生的source .map

source map文件是js文件压缩后,文件的变量名替换对应、变量所在位置等元信息数据文件

productionSourceMap:false 把这个改为false。不然在最终打包的文件中会出现一些map文件

map文件的作用:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。 有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。

31,项目中遇到的问题 1)移动端底下tab栏切换时会有上一屏还没移除完下一屏就出来的现象 用mode=“out-in”

2)element-ui的table中每一行每一格进行特殊样式编辑 用template标签

3)问卷调查才能查看自己的信息,但是改地址栏就不用问卷调查了 用路由导航守卫beforeRouterEnter(to,from,next){next()}

32,cookie sessionStorage和localStorage区别

相同点 都存储在客户端。 不同点 1.存储大小 cookie数据大小不能超过4k。 sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。 2.有效时间 localStorage:存储持久数据,浏览器关闭后数据不丢失除非主动删除数据。 sessionStorage:数据在当前浏览器窗口关闭后自动删除。 cookie:设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 3. 数据与服务器之间的交互方式 cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端 sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

33,导航守卫

全局守卫beforeEach 后置守卫afterEach 路由独享守卫beforeEnter 组建内守卫beforeRouteEnter/Update/Leave

34,axios封装

1,axios的环境,测试环境,上线环境网址设置,可以复制粘贴 2,被then和catch处理前拦截 请求拦截axios.interceptors.request,在查看前拦截提供登录的账号密码 响应拦截axios.interceptors.response,在输入一些信息后拦截跳到登陆注册 3,axios.post和get的方法封装

35,不兼容 h5新标签用shim.js,底层是document.createElement

36,跨域

浏览器访问其他服务器的东西 解决: 1.jsonp:原理-动态生成script标签,生成src属性加载,缺点-只支持get,不支持post,应用-第三方数据接口 2.中间服务器代理:前后端端口不同,后台写一个服务器和前端端口一样,然后实现跨域,后台服务器不会出现跨域问题 3.cros跨域资源共享:服务器端进行配置,加一个响应头,最常用的!! res.header(Access-Control-Allow-Origin,“*”) =》vue中在vue.config.js中devServer中proxy设置,写一个虚拟服务器,可以在网上复制粘贴~

37,export和export default的区别

共同点:均可以导出常亮,文件,函数以及模块等,在其他文件模块中通过import+(变量,函数,文件,模块)名的方式,将其导入,来进行使用

不同点:1.在一个文件或模块中,export、import可以有多个,export default仅有一个 2.通过export方式导出的,import加{},export default则不需要

38,route和router区别

this.routerVueRouter的实例方法,相当于一个全局的路由器对象,里面含有很多属性和子对象,用router是VueRouter的实例方法,相当于一个全局的路由器对象,里面含有很多属性和子对象,用.router.push和router-link在history中添加一个路由记录

this.$route是一个当前正在跳转的路由对象,每一个路由都有一个route对象,可以获取对应的name,path,params,query等

39,css中hack

CSS hack是通过在CSS样式中加入一些特殊的符号,让不同的浏览器识别不同的符号(什么样的浏览器识别什么样的符号是有标准的,CSS hack就是让你记住这个标准),以达到应用不同的CSS样式的目的。

40,axios的拦截器

// 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); });

// 添加响应拦截器 axios.interceptors.response.use(function (response) { // 对响应数据做点什么 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); });

//移除拦截器 var myInterceptor = axios.interceptors.request.use(function () {}); axios.interceptors.request.eject(myInterceptor);

//自定义添加拦截器 var instance = axios.create(); instance.interceptors.request.use(function (){});

41,异步函数执行完再执行下一步

对于一些采用非AJAX异步获取数据的函数,要保证异步加载完成后再继续执行下一步可以采用jq提供的Deferred()的函数。

//定义Deferred()函数 var dtd = .Deferred();//Deferred()函数格式,when()当函数异步加载成功后执行done里面的函数;函数异步加载失败时执行fail里面的函数。when()里面不能定义变量。when()里面可以写多个函数。.Deferred(); //Deferred()函数格式 ,when()当函数异步加载成功后执行 done里面的函数;函数异步加载失败时执行 fail里面的函数。when()里面不能定义变量。when()里面可以写多个函数。 .when(wait(bb, dtd))   .done(function(aa) { alert(aa); alert("哈哈,成功了!"); })   .fail(function() { alert("出错啦!"); });

42,delete和vue.delete区别

delete只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。

Vue.delete 直接删除了数组 改变了数组的键值。

43,去重

for in,set,indexOf,filter

var arr = [1,2,2,2,3,3,null,null]; var newArr = Array.from(new Set(arr)); console.log(newArr);//[1,2,3,null]

44,hash和history区别

在hash模式下,前端路由修改的是#中的信息,而浏览器请求时不会将 # 后面的数据发送到后台,所以没有问题。 但是在history下,你可以自由的修改path,当刷新时,如果服务器中没有相应的响应或者资源,则会刷新出来404页面。

45,axios特点

1.从浏览器中创建XMLHttpRequests 2.node.js创建http请求 3.支持Promise API 4.拦截请求和响应 5.转换请求数据和响应数据 6.取消请求 7.自动换成json axios中的发送字段的参数是data跟params两个 两者的区别在于params是跟请求地址一起发送的,data的作为一个请求体进行发送 params一般适用于get请求 data一般适用于post put 请求

46,路由的几种方式

router-link,this.router.pushthis.router.push,this.router.push中的query,this.$router.push中的params

query和params区别 query是参数写在url上,用path写路由名 params是参数不在url,用name写理由名

47,为什么在项目中data需要使用return返回数据呢?

不使用return包裹的数据会在项目的全局可见,会造成变量污染;使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。

48,loader,plugin

loader是加载的意思,是打包的,loader是运行在NodeJS中,loader运行在打包文件之前(loader为在模块加载时的预处理文件) 由于webpack 本身只能打包commonjs规范的js文件,所以,针对css,图片等格式的文件没法打包,就需要引入第三方的模块进行打包。css-loader和style-loader模块是为了打包css的,babel-loader和babel-core模块时为了把ES6的代码转成ES5,url-loader和file-loader是把图片进行打包的。

plugin功能多,打包压缩和插件,是作用于webpack本身上的。 plugins在整个编译周期都起作用 从打包优化和压缩,到重新定义环境变量,功能强大到可以用来处理各种各样的任务。webpack提供了很多开箱即用的插件1.CommonChunkPlugin主要用于提取第三方库和公共模块,避免首屏加载的bundle文件,或者按需加载的bundle文件体积过大,2.针对html文件打包和拷贝(还有很多设置)的插件:html-webpack-plugin。

49,判断数据类型 js中的typeof,instanceof和jq中的.typejq.type jq的.type更精准

50,媒体查询屏幕大小

@media screen and (min-width:1200px) @media screen and (min-width:992px) @media screen and (min-width:768px) @media screen and (min-width:480px)

51,垂直居中的方法

1.子绝父相,拉回宽高的一半 left/top:50%,margin-top/left:-宽高一半 2.transform宽高的一半 transform: translate(-50%,-50%); 3.弹性盒模型, justify-content:center,align-items:center

52,防抖和节流

防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。 节流:高频事件触发,但在n秒内只会执行一次,节流会稀释函数的执行频率。 区别:节流不管事件触发有多频繁,都会保证在规定时间内执行一次真正的事件处理函数,而防抖只是在最后一次事件后才触发一次函数。

53.数组去重

1,splice,利用两个for循环,arr[i]==arr[j]比较同一数组的值,相同的移除本身arr.splice (j,1) 2,indexOf,找到对应字符串的索引位置,没有返回-1,一个空数组,利用for循环,arr[i].indexOf==-1,push进空数组 3,sort,sort排序之后,利用for循环,arr[i]==arr[i+1]比较值,相同移除a rr.splice(i,1) 4,对象属性,建一个空对象,空数组,判断键有没有对应的值,没有就是push进数组

54,数组和伪数组区别

伪数组能打点调length,有索引,但是只是长得像数组,没有数组的方法 伪数组通过循环遍历进一个新数组,Array.prototype.slice.call()和Array.from()三种方法转换成数组

55,宏任务和微任务

宏任务是宿主环境提供的,setTimeout,setInterval 微任务是语言提供好的,promise

56,es6中数组的新方法

Array.from,find,findIndex,includs

57,vue-cli2和vue-cli3区别

cli2初始化项目是vue init webpack 项目名,需要手动配置一些东西, cli3初始化项目是vue create 项目名,无需手动配置

cli2运行是npm run dev cli3运行是 npm run derve

cli2是static文件 cli3是public文件

cli3安装完项目没有了build,config等,有需要自己去写

58,mpvue缺点

mpvue中不支持vue的filters过滤器,slot不能写动态数据

59,箭头函数和普通函数的区别

箭头函数是没有this指向的,指向定义的,没有prototype 普通函数有this指向,谁调用指向谁

60,keep-alive

缓存组件,两个参数:include,exclude,生命周期:activated,deactivated

include:只有匹配的组件会被缓存 exclude:任何匹配的组件都不会被缓存

exclude优先级大于include

activated:组件被激活时调用,组件第一次渲染也会被调用,之后每次keep-alive激活时调用 deactivated:组件被停用时调用

61,for in,for of,forEach,filter,map

for in遍历的是数组的索引,可以遍历到methods for of遍历的是数组的值,不能遍历到methods forEach不能终止循环 filter返回符合条件的true的 map创建一个新数组,一对一的映射

62,eval,json.parse

eval要求不严格,字符串格式不是json格式也可以,加括号 json.parse要求严格,不符合格式就会报错,省略空格