心得:通过自己的一些经验自己总结了一些面试问的问题及自己遇到的笔试题
希望对大家有所帮助,有总结不到位的,希望大家能帮忙指正,谢谢。
笔试题:
1.通过对变量的递增,来进行操作
let a=1;
console.log(a++);//1
console.log(++a);//3
2.封装方法,操作闭包
function person() {
person.name=‘xiaoming’;
person.age=19;
function test() {
person.name=‘xiaohong’;
person.age=24;
}
return test;
}
p1=person.age=12;
var p2=person(p1);
console.log(p1);//12
console.log(p2);//ƒ test() {
// person.name=‘xiaohong’;
// person.age=24;
// }
3.数组去重(实现的几种方法)?
一.new set()方法
思路:set ES6提供了新的数据结构,它类似与数组,但是成员的值都是唯一的,没有重复的值(不包括空对象)
缺点:不考虑兼容的情况下,使用代码少,但是不能去重空对象。
let arr=[1,4,5,6,7,2,5,6,7,8];
let arr1=new Set(arr);
console.log(arr1);//Set(7) {1, 4, 5, 6, 7, …}
//封装的函数,执行new Set方法
function delR(arr) {
return Array.from(new Set(arr));
}
console.log(delR(arr));//(7) [1, 4, 5, 6, 7, 2, 8]
二.push()方法
利用对象的属性名不能重复的原理来去重 去重效率最高的一种
思路:js对象是一种复合类型 它允许你通过变量名存储和访问,换一种思路就是一个无序的属性集合。
//集合中的每一项都有名称和值组成.
function delRepeat(arr){
var obj={};//储存对象
var newArr=[];//储存数组
for(var i=0;i<arr.length;i++){
if(!obj[arr[i]]){//利用对象属性名不能重复,判断当前的对象中有没有这个属性值
obj[arr[i]]=1;//如果当前对象没有这个值,就给这个对象里面的属性赋值为"1",{arr[i]:1}
newArr.push(arr[i]);//push方法可向数组的末尾添加一个或多个元素并返回新的长度,这里是把
//找到的数组值放到一个新的数组(arr1)中
}
}
return newArr;
}
console.log(delRepeat(arr));//(7) [1, 4, 5, 6, 7, 2, 8]
三.splice()方法
思路:双重循环嵌套然后splice去重。
function unique(arr){
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]==arr[j]){//第一个等同于第二个 splice方法删除第二个
arr.splice(j,1);
j--;
}
}
}
return arr;
}
console.log(unique(arr));//(7) [1, 4, 5, 6, 7, 2, 8]
四.indexOf()方法
indexOf:返回的是元素的所在下标,如果不存在则返回-1
思路:定义一个空数组去储存,当indexOf方法返回的每一项为真,就用push方法返回新数组。
function uniq(arr) {
if(!Array.isArray(arr)){
console.log('type error!');
return
}
var arr1=[];//储存数组
for(var i=0;i<arr.length;i++){
if(arr1.indexOf(arr[i])===-1){
arr1.push(arr[i])
}
}
return arr1;
}
console.log(uniq(arr));//(7) [1, 4, 5, 6, 7, 2, 8]
4.排序的几种方法?
(1)默认排序
var arr2=[1,4,5,9,7,3,2,8,6];
arr2.sort();
console.log(arr2);//(9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
(2)冒泡排序
var bubSort=function(arr2){
var len=arr2.length;//获取长度
for(var i=0;i<len;i++){
for(var j=0;i<len-1-i;i++){
if(arr2[j]>arr2[j+1]){//相邻元素两两对比
var temp=arr2[j+1];//元素交换
arr2[j+1]=arr2[j];
arr2[j]=temp;
}
}
}
return arr2;
};
console.log(bubSort(arr2));//(9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
(3)插入排序
var inSort=function(arr2) {
var len=arr2.length;//数组长度
var parIndex,current;//变量声明
for(var i=1;i<len.length;i++){
parIndex=i-1;//变量赋值
current=arr2[i];//变量赋值
while (parIndex>=0&&arr2[parIndex]>current) {
arr2[parIndex+1]=arr2[parIndex];
parIndex--;//递减
}
arr2[parIndex+1]=current;//赋值
}
return arr2;//返回值
};
console.log(inSort(arr2));//(9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
面试题:
1.项目打包Android、ios、 用什么方法打包上线?
Cordova打包vue项目 Xcode提交AppStore
参考路径:https://www.cnblogs.com/jeremy5810/p/8467258.htm
参考路径2:https://segmentfault.com/a/1190000018087837
(xcode提供的是:应用的图标、启动图、权限声明、证书、版本等)
2.vue双向数据绑定原理?
vue采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,
在数据变动时发布消息给订阅者,触发相应的监听回调。
3.vuex的状态管理核心概念?
1.state:vuex的基本数据,用来存储变量。
2.geeter:基本数据(state)派生的数据,相当于state的计算属性。
3.mutation:提交数据更新的方法,只能是同步的.如果是异步使用(action).每个mutation都有一个字符串的数据类型(type)和一个回调函数(hanlder),回调函数就是我们实际状态更改的地方,并且它接受并且它接受state作为第一个参数,提交载荷作为第二个参数。
4.action: action和mutation功能大致相同,不同之处在于action提交的就是mutation,而不是直接变更状态, action可以包含任意异步操作。
5.modules:模块化vuex,可以让每一个模块拥有自己的state、getter、mutation、action是结构化非常清晰,便于管理。
4.promise和setTimeout运行顺序,promise是?
顺序:(先同步>微任务>宏任务)
promise是微任务
宏任务:Script、setTimeout、setInterval、
微任务:Promise、process.NextTick
运行代码:
console.log(1);
setTimeout(function(){
console.log(3);
});
Promise.resolve().then(function() {
console.log(5);
}).then(function() {
console.log(6)
});//执行顺序是:1 5 6 3
5.工作中遇到哪些难题,如何解决?
一. 难题:浏览器在开启有道划词插件的时候,使用 AjaxFileUpload 插件上传文件报错
详细介绍:有道词典chrome(谷歌)划词插件,支持chrome浏览器的划词翻译,
原因:1.在开启插件时,该插件会在文档中添加音频元素节点
2.ajaxFillUpload插件在上传文件处理方式是,获取返回的实体内容,直接进行eval解析,
解析失败报错,无法上传
解决:
1.要么停止使用或停用插件
2.或者FormDate对象进行异步上传文件
二. 难题:Uncaught TypeError: jQuery.handleError is not a function
原因:使用某些旧插件的时候,会出现这个错误
插件使用了handleError这个方法,而新版的jQuery以及去除了这个方法,
解决:
1.所以这时可以弃用插件或者为JQ加回此方法
三. 难题:异步方式实现导出Excel表格
原因: 用异步的方式导出数据,用Ajax貌似不行
解决:
1.目前想到的方法就是用iframe,设置不同的src即可让后端返回相应数据
2.另外,刚发现的一个异步导出文件的方式是,直接设置当前URL为接口的路径即可
代码:window.location.href = '?p.......';
6.cdn缓存做过哪些?
–1.数据库缓存–:
当web应用关系复杂,数据表蹭蹭蹭往上涨时,可以将查询后的数据放到内存中进行缓存,下次再查询时,就直接从内存缓存中获取,
从而提高响应速度。
–2.CDN缓存–:
CDN通俗点,就是当我们发送一个web请求时,会先经过它一道手,然后它帮我们计算路径,去哪得到这些东东(representations)
的路径短且快。这个是网站管理员部署的,所以他们也可以将大家经常访问的representations放在CDN里,这样,就响应就更快了。
–3.代理服务器缓存–:
代理服务器缓存,其实跟下面即将讲的浏览器缓存性质差不多,差别就是代理服务器缓存面向的群体更广,规模更大而已。
即,它不只为一个用户服务,一般为大量用户提供服务,同一个副本会被重用多次,因此在减少相应时间和带宽使用方面很有效。
7.项目做过哪些优化?
1.首先最基本的,CSS样式表放在页面头部Head内且link链式引入,javascript放在底部body结束标签前避免阻塞。
2、js/html/css/图片都做压缩合并,图片预加载、懒加载,(图片无损极限压缩工具:TinyPng)
3、减少DOM元素数量,减少DOM的操作:
4、静态资源CDN分发:
5、域名拆分:
6、 减少http请求次数
7、 数据设置缓存
8、 站点服务端开启Gzip压缩,
9、 避免重定向,尽量减少 iframe 使用,它会阻塞主页面的渲染;
10、 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性);
11、 合理使用dns-prefetch、prefetch、 preload、 defer、async:
12.短时间内大量的触发某函数导致的性能的问题
防抖和节流插件:lodash
防抖debounce:在事件触发n秒后再执行,如果在n秒内又有新的触发,就重新计算
节流throttle:连续事件触发,在指定的时间内,不管触发几次,就只执行一次
(推荐几个工具:WebPagetest、Lighthouse、SpeedCurve、New Relic 等主动/被动监测工具)
8.闭包的理解?
闭包简单来说就是函数嵌套函数,保存变量不被垃圾机制回收
在一个函数里面嵌套另一个函数,被嵌套的那个函数的作用域是一个闭包
作用:创建一个私有变量,减少全局变量,防止变量名污染,可以操作外部作用域的变量,变量不会被垃圾回收,保存变量的值。
9.内存溢出有哪些?
1.不要使用html方法删除Dom节点,因为这样其实只是删除页面上的,内存里面的还没有删除,建 议使用:empty和remove方法
2.定时器不使用要清除,clearInterval ,clearTimeout
3.变量声明不要忘了,因为这样回容易造成全局污染,还有内存溢出,虽然消耗少,但积少成多,使用严格模式杜绝“user strict”
4.闭包问题,这个常见问题,因为闭包的变量被引用是无法垃圾回收机制回收,引用即在函数链里被使用
5.ajax也可能出现这样的问题,如果不断的请求ajax,那么就会造成ajax不断的创建XmlHttpRequest对象,有些JQ版本也存在这个问题
6.事件不在使用记得清除,使用off方法,不是事件也会被缓存下来,消耗内存。
10.项目中用过什么布局方式?
1.静态布局(即web设计,网页上所有的元素尺寸一率使用px作为单位)
在移动端开发中采用静态布局的两种方式:(来自:流布局与响应式网页设计有什么区别?)
(1)在viewport meta标签上设置width=320,页面的各个元素也采用px作为单位。通过用JS动态修改标签的initial-scale使得页面等比缩放,从而刚好占满整个屏幕。(见前端开发-web app 变革之rem)
(2)设在viewport meta标签上设置content"width=640,user-scalable=no,页面的各个元素也采用px作为单位。由于640px超出了手机宽度,浏览器会自动缩小页面至刚好全屏。(具体见content"width=640,user-scalable=no" 然后再进行固定尺寸的px设计? - 前端开发)
优点:这种布局方式对设计师和CSS编写者来说都是最简单的,亦没有兼容性问题。
缺点:显而易见,即不能根据用户的屏幕尺寸做出不同的表现。
2.流式布局(是页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。代表作栅栏系统(网格系统))
设计方法:使用%百分比定义宽度,高度大都是用px来固定住,可以根据可视区域 (viewport) 和父元素的实时尺寸进行调整,尽可能的适应各种分辨率。往往配合 max-width/min-width 等属性控制尺寸流动范围以免过大或者过小影响阅读。
3.自适应布局(自适应布局的特点是分别为不同的屏幕分辨率定义布局,即创建多个静态布局,每个静态布局对应一个屏幕分辨率范围)
设计方法:使用 @media 媒体查询给不同尺寸和介质的设备切换不同的样式。在优秀的响应范围设计下可以给适配范围内的设备最好的体验,在同一个设备下实际还是固定的布局。
4.响应式布局(:创建多个流体式布局,分别对应一个屏幕分辨率范围。可以把响应式布局看作是流式布局和自适应布局设计理念的融合)
设计方法:媒体查询+流式布局。通常使用 @media 媒体查询 和网格系统 (Grid System) 配合相对布局单位进行布局,实际上就是综合响应式、流动等上述技术通过 CSS 给单一网页不同设备返回不同样式的技术统称。
5.弹性布局(即采用Flex布局的为Flex容器,布局元素中的子元素为容器成员Flex项目)
rem(始终相对于html大小,即页面根元素)、em(em是相对其父元素)、
特点:使用em/rem做单位,可以使包裹文字的元素随着文字的缩放而缩放。
11.websocket的理解?
WebSocket端点的4个生命周期事件:
1.打开事件:此事件发生在端点建立新连接时并且在任何其他事件发生之前。
2.消息事件:此事件接收 WebSocket 对话中另一端发送的消息。它可以发生在 WebSocket 端点接收了打开事件之后并且在接收关闭事件关闭连接之前的任意时刻。
3.错误事件:此事件在 WebSocket 连接或者端点发生错误时产生。
4.关闭事件:此事件表示 WebSocket 端点的连接目前正在部分地关闭,它可以由参与连接的任意一个端点发出。
WebSocket:握手拦截器用来拦截和处理客户端和服务器端分别在握手前和握手后的事件,
我们这里添加这个拦截器是为了清晰的知道什么时候以及是否握手成功。
12.vue的三种传值方法?
1.父传子 props
2.子传父 emit
3.非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果
13.项目中怎么解决跨域?
由于浏览器的同源策略会导致跨域.跨域又分为:
一.DOM同源策略:禁止对不同源页面的Dom进行操作,主要是不同域名的iframe是限制互相访问的
二.XmlHttpRequest同源策略:禁止使用XHR对象对不同源的服务器发起http请求,只要协议,域名,端口有一个不同都被当做不同的域之跨域。
解决方法:
1.Cors资源共享 在后端头部设置Access–controls–Allow-credentials:true
2.jsonp实现跨域 :动态创建script,利用src属性进行跨域
3.nginx 代理跨域
4.node.js中间代理跨域
5.webSokect协议跨域
6.window.name+iframe 跨域
14.浏览器的兼容问题?
1.使用css hack针对不同的浏览器,不同的浏览器加入不同的符号,浏览器针对这些符号兼容不同的css样式
2.使用normalize.css不同的浏览器的默认样式存在差异,可以使用normalize.css抹平这些差异
3.不同浏览器的默认的内外补丁不同,通常使用*{margin:0;padding:0}解决差异
4.html5shiv.js解决IE9以下浏览针对新增标签不识别的问题
5.respond.js解决IE9以下浏览器不支持css3 Media Query的问题
15.vue的生命周期的理解?
1.beforeCreate:vue的元素挂载元素el和数据都为undefined,还未初始化(初始前)
2.created:vue实例的数据对象data有了,el还没有(初始后)
3.beforeMount:vue的实例的$el和data都初始化了,但是还挂载在之前的虚拟Dom节点上,data.message还未替换(载入前)
4.Mounted:vue实例挂载完成,data.message成功渲染(载入后)
5.beforeUpdate:当data变化时,会触发beforeUpdate(更新前)
6.updated:当data变化时,会触发updated(更新后)
7.beforeDestroy:vue实例之前执行的钩子函数,销毁/拆除所有的观察者,子组件和事件监听(销毁前)
8.destroyed:销毁后什么也不做,已经不存在(销毁后)
16.对未知的宽和高不固定,怎么水平和垂直居中?几种方法实现?
1.使用定位元素
position:absolute;
-webkit-transform:translate(-50%,-50%);
transform:translate(-50%,-50%)
2.通过flex弹性盒模型布局
display:flex;
align-center:center;
justify-content:center;
3.通过行内块实现
//子盒子设置
display:inline-block;
vertical-align:middle
//父盒子设置:after清除影响
17.http和https的区别?
1.http:是一种超文本传输协议 信息是明文传输 https:https协议需要ca申请证书,一般免费证书较少,是具有安全性的ssl加密传输协议
2.http和https是完全不同的连接方式用的端口也不一样:前者是80 后者是443
3.http:的连接方式是无状态的 https:协议是由SSL和tls,ssl和tls是由Http上的TCP构建的可进行加密传输、身份认证的网络协议要比http协议安全。
18.异步和同步的区别?
同步:当请求发出后,就一直等待着,直到有响应结果处理响应内容
异步:当请求发出后,可以去做别的事情,当返回结果有响应时,再来处理返回的结果.
19.什么是微任务和宏任务(举例几个)谈谈理解?
微任务:是一次性执行完的。
宏任务:需要多次事件执行完
同步->微任务>宏任务
宏任务:script setTimeout setInterval
微任务:promise process.NextTick
20.get和post的区别?
get:只能传输少量数据,只能通过路径携带传输 传输不安全(传输速率较高)
post:对于传输数据没有大小限制,独立传输 传输相对安全 (传输速率慢)
21.防抖和节流的理解?
一.理解:短时间内大量触发某事件导致的性能问题(资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器崩溃)
1.防抖:在事件触发n秒后在执行,如果n秒内又有新的触发 就重新计算。
2.节流:连续事件触发,在指定时间内不管触发几次,就只执行一次
二.使用场景:
防抖:实时搜索(keyup) 、 拖拽(mousemove)、
节流:窗口调整(resize)、页面滚动(scroll)、抢购和疯狂点击(mousedown)、
三.使用插件:lodash
22.v-if和v-show区别,谈谈理解?
v-if:如果初始条件为假,则什么也不做 直到为真时才开始渲染条件块。
v-show:不管初始条件为什么,元素总会被渲染,并且只是基于简单的css切换
区别:v-if有更高的切换开销,而v-show有更高的初始渲染开销,如果要非常频繁的切换v-show较好
如果在运行条件时很少改变则使用v-if较好。
23.v-for中为什么加入key?
1.目的是vue会根据key值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素;
2.两个相同的组件产生类似的DOM结构,可以通过唯一的id进行区分,
3.使得虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)
4.为的是做domdiff的计算
24.v-if和v-for同时执行,优先级顺序,及理解?
v-for优先级高于v-if。
当两者同时执行时v-if给v-for遍历出来的每一个元素都添加一下,容易造成性能浪费!
所以最好不要同时使用。
25.html语义化是?
当页面加载失败的时候让页面呈现清晰的结构,有利于SEO优化,利于搜索引擎收录(更便于搜索引擎的爬虫程序识别),便于项目的开发及维护,使html代码更具有可读性,便于其它设备解析。
(如果不使用语义化搜索引擎爬虫:没有他们的话搜索引擎将无法索引你的网站,用户将无法进行访问)
26.ajax的步骤?
1.创建ajax对象
var xml=new XMLHttpRequest();
2.打开链接通道
xml.open(method,url,async);// (请求方式 ,请求路径, 异步或同步) method:请求方式 get或post
// get:只能传输少量数据 通过路径携带传输 传输不安全 (传送速率快)
//post: 对于传输的数据没有大小限制 独立传输 相当安全 (传送速率慢)
//.如果是get方式提交:在xml.open("get","http://www.baidu.com?"+obj,true),send()方法不需要添加任何值
// .如果是post方式提交,那么参数就是你要提交的数据.post方式提交:是在.send(obj)
// async:(false同步或true异步)
3.发送请求
xml.send();//如果是get就不用传任何值 如果是post 参数就是提交的值
4.接收 监听
xml.onreadystatechange=function(){
if(xml.readyState==4&&xml.status==200){//readyState==4请求已完成且响应已就绪,status==200操作成功并处理。
//例子if: 1.document.write(xml.responseText);//获得字符串形式的相应数据
var str=xml.responseText;
var arr=str.split("&");//split()字符串转成数组字符串的每一项
for(var i in arr){
console.log(arr[i]);//Array[3]数组的每一项
arr[i]=arr[i].slice(arr[i].indexOf("=")+1);
}
console.log(arr);// ["zhangsan", "lisi", "wangwu""]
for(var j=0;j<lis.length;j++){
console.log(lis[j]);//
lis[j].innerHTML=arr[j];
}
}else {
//例子else: 1.body.innerHTML=""+xml.status+"
您的页面走丢了
"
// 1.console.log(xml.status);//如果错误就查看状态码 查找错误原因
}
27.v-if v-else-if v-else /v-show区别?
区别:v-if是元素是否增加到页面上,满足条件,浏览器才会生成标签并在页面中渲染,
v-show是 style的操作
1,如果频繁的操作显示和隐藏v-show比v-if的性能更高,
因为v-show只是动态的更改样式而不需要增删DOM元素
2,如果出现多种条件场景的情况下,可以使用v-if来进行判断
因为v-if能和v-else连用进行判断,v-show是不能和v-else连用的
28.例举一个用到的filter过滤的效果实现?
1.要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据(非变异方法)。可以使用filter( )方法
2.在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中(多重v-for 嵌套)) 你可以使用一个 method 方法:在返回使用过滤器之后得到的值
<li v-for="n in even(numbers)">{{n}}
data:{numbers:[1,2,3,4,5]},
methods:{
even:function(numbers){
return numbers.filter(function (number){return number %2===0})} //过滤(VUE)
3.利用vue的计算属性,过滤掉filter不需要的数据,剩下数据通过v-for循环遍历渲染出来
29.项目中实现功能的插件?
1.vue-router: 页面路由,用于做单页面应用(SPA)。
2.vuex: 数据状态管理。
3.vue-navigation: 记录路由并缓存页面,像原生APP导航一样。
4.vconsole: 移动端调试利器
5. axios: 一个很好的ajax封装集
6. fastclick: 为了能够立即响应用户的点击事件,解决移动端click 300ms延迟,才有了FastClick。
7. webpack: 用于搭建前端工程。
8. vue-lazyload :一个简单易用的 Vue 图片延迟加载插件;
9. beter-scroll:实现下拉刷新,上拉加载
beter-scroll插件坑点:
1.手指触摸了一点页面就哧溜滑动了好多,可能是给容器设置 -webkit-overflow-scrolling: touch; 样式了,删掉即可
2. 添加better-scroll 后页面需要横向滚动的地方不能滚动,添加 eventPassthrough: ‘horizontal’ 配置,具体原因参考官方文档该配置介绍
30.谈谈单向数据流?
前端开发中的单向数据流是指处理完数据到渲染在界面上的整个过程是单向不可逆的,你只能按 照规定好的一套流程去变更界面上数据的展示。相对应的,前端框架中还有双向绑定。