最近前端面试题整理

1、解释一下CSS的盒子模型? ☆

答:1)盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border)

2)有两种, IE 盒子模型、标准 W3C 盒子模型;IE的content部分包含了 border 和 padding;

image
2、CSS水平垂直居中 ☆☆☆

方法一:

绝对定位方法:不确定当前div的宽度和高度,采用 transform: translate(-50%,-50%); 当前div的父级添加相对定位(position: relative;)

图片展示:

img

代码如下:

div{
    background:red;
    position: absolute;
    left:50%;
    top:50%;
    transform: translate(-50%, -50%);
}

方法二:

绝对定位方法:确定了当前div的宽度,margin值为当前div宽度一半的负值

图片展示: 如方法一的图片展示

代码如下:

div{
    width:600px;
    height: 600px;
    background:red;
    position: absolute;
    left:50%;
    top:50%;
    margin-left:-300px;
    margin-top:-300px;
}

方法三:

绝对定位方法:绝对定位下top left right bottom 都设置0

图片展示: 如方法一的图片展示

代码如下:

div.child{
    width: 600px;
    height: 600px;
    background: red;
    position:absolute;
    left:0;
    top: 0;
    bottom: 0;
    right: 0;
    margin: auto;
}

方法四:

flex布局方法:当前div的父级添加flex css样式

展示图如下:

img

代码如下:

.box{
    height:800px;
    -webkit-display:flex;
    display:flex;
    -webkit-align-items:center;
    align-items:center;
    -webkit-justify-content:center;
    justify-content:center;
    border:1px solid #ccc;
}
div.child{
    width:600px;
    height:600px;
    background-color:red;
}

方法五:

table-cell实现水平垂直居中: table-cell middle center组合使用

展示图如下:

img

代码如下:

.table-cell {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
    width: 240px;
    height: 180px;
    border:1px solid #666;
}

方法六:

绝对定位:calc() 函数动态计算实现水平垂直居中

展示图如下:

img

代码如下:

.calc{
  position: relative;
  border: 1px solid #ccc;
  width: 400px;
  height: 160px;
}
.calc .child{
  position: absolute;
  width: 200px;
  height: 50px;
  left:-webkit-calc((400px - 200px)/2);
  top:-webkit-calc((160px - 50px)/2);
  left:-moz-calc((400px - 200px)/2);
  top:-moz-calc((160px - 50px)/2);
  left:calc((400px - 200px)/2);
  top:calc((160px - 50px)/2);
}  
3、CSS 如何取消浮动

答:https://www.cnblogs.com/wush-1215/p/10623243.html

4、CSS flex布局(问:解释什么是flex)

答:Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
布局的传统解决方案,基于盒状模型,依赖display属性+ position属性+ float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

简单的分为容器属性和元素属性
容器的属性:

· flex-direction:决定主轴的方向(即子item的排列方法)
.box {
flex-direction: row | row-reverse | column | column-reverse;
}

· flex-wrap:决定换行规则
.box{
flex-wrap: nowrap | wrap | wrap-reverse;
}

· flex-flow:
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}

· justify-content:对其方式,水平主轴对齐方式

· align-items:对齐方式,竖直轴线方向

项目的属性(元素的属性):

· order属性:定义项目的排列顺序,顺序越小,排列越靠前,默认为0

· flex-grow属性:定义项目的放大比例,即使存在空间,也不会放大

· flex-shrink属性:定义了项目的缩小比例,当空间不足的情况下会等比例的缩小,如果定义个item的flow-shrink为0,则为不缩小

· flex-basis属性:定义了在分配多余的空间,项目占据的空间。

· flex:是flex-grow和flex-shrink、flex-basis的简写,默认值为0 1 auto。

· align-self:允许单个项目与其他项目不一样的对齐方式,可以覆盖align-items,默认属性为auto,表示继承父元素的align-items

比如说,用flex实现圣杯布局

<!-- DOM结构 -->
<div id="container">
  <div id="center"></div>
  <div id="left"></div>
  <div id="right"></div>
</div>
#container {
    display: flex;
}

#center {
    flex: 1;
}

#left {
    flex: 0 0 200px;
    order: -1;
}

#right {
    flex: 0 0 150px;
}

注:https://www.runoob.com/cssref/css3-pr-flex.html

5、变量提升

答:
注:https://www.jianshu.com/p/864b0003d7a9?tdsourcetag=s_pcqq_aiomsg
https://blog.csdn.net/weixin_44022064/article/details/103821052

6、闭包 ☆☆

答:
(1)什么是闭包:
闭包是指有权访问另外一个函数作用域中的变量的函数。

闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配。当在一个函数内定义另外一个函数就会产生闭包。

(2)为什么要用:

匿名自执行函数:我们知道所有的变量,如果不加上var关键字,则默认的会添加到全局对象的属性上去,这样的临时变量加入全局对象有很多坏处,比如:别的函数可能误用这些变量;造成全局对象过于庞大,影响访问速度(因为变量的取值是需要从原型链上遍历的)。除了每次使用变量都是用var关键字外,我们在实际情况下经常遇到这样一种情况,即有的函数只需要执行一次,其内部变量无需维护,可以用闭包。

结果缓存:我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。

function f1(){
    var n = 999;
    nAdd = function(){
        n+=1
    }
    function f2(){
        alert(n)
    }
    return f2
}
var result = f1();
result();
nAdd();
result();
7、原型链

答:原型本身也是一个对象,这个对象就是Object的实例,所以原型也可以调用到Object的原型,这样就组成了一个链式结构,这个就是原型链。
注:https://www.cnblogs.com/shuiyi/p/5305435.html

8、Event Loop(介绍node中的事件循环) ☆☆

答:链接:https://www.nowcoder.com/questionTerminal/6c17f460e32d4baeaf66c20223354f97
来源:牛客网

Event Loop:

    1.遇到sciprt之后开始第一个宏任务

    2.执行过程中遇到异步请求,会将其压入任务队列,交由异步事件引擎处理

    3.执行完宏任务后,检测是否存在微任务,有的话会先执行微任务

    4.执行第二个宏任务

new Promise((resolve, reject) => {

    console.log(1)

}).then(_ => {

    console.log(2)

})

setTimeout(_ => {

    console.log(3)

}, 300)

执行顺序: 1 -> 2->3

promise属于微任务, setTimeout属于宏任务

注:https://segmentfault.com/a/1190000012925872?utm_source=tag-newest

9、promise

答:promise表示一个异步操作的最终结果,与之交互的方式主要是then方法,该方法主要注册了二个回调函数,用于接收promise的最终结果和不能执行的原因。
promise的状态主要有三种:等待、执行、拒绝
1、等待pending 等待进入执行或拒绝状态
2、执行 resolve不能进入其他状态,有一个不可变的最终结果
3、拒绝rejected 不能进入其他状态,有一个不可变的拒绝原因

10、$nextTick ☆☆

答:因为vue是异步更新的,$nextTick用来知道什么时候DOM更新完成。

当修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值,
你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。
11、vue的双向绑定原理 ☆☆☆☆☆

答:vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法。
https://www.cnblogs.com/sweeeper/p/10829887.html

12、vue生命周期(考察生命周期某个阶段做了什么) ☆☆

答:每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做 生命周期钩子 的函数,这给了用户在不同阶段添加自己的代码的机会。(ps:生命周期钩子就是生命周期函数)例如,如果要通过某些插件操作DOM节点,如想在页面渲染完后弹出广告窗, 那我们最早可在mounted 中进行。

注:vue的生命周期是:vue实例从创建到摧毁,也就是开始创建、初始化数据、编译模板、挂载DOM → 渲染、更新 → 渲染、卸载等一系列过程。

13、vue-router 有哪几种导航钩子 ☆☆☆

答:三种,
第一种:是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。
第二种:组件内的钩子
第三种:单独路由独享组件
参考地址:https://www.cnblogs.com/goloving/p/9211295.html

14、 await和async与promise区别 ☆

注:https://www.jianshu.com/p/463280af23ef

15、vue和angular区别 ☆

注:https://www.imooc.com/article/71832?block_id=tuijian_wz

16、ES6新特性 ☆☆


模块化
箭头函数
函数参数默认值
模板字符串
解构赋值
延展操作符(展开操作符)
对象属性简写
Promise
Let与Const

17、有没有用过Directive指令 ☆☆

https://cn.vuejs.org/v2/guide/custom-directive.html

18、vue-router路由的两种模式 ☆☆☆
答:
1、hash模式:vue-router默认hash模式,
   使用URL的hash来模拟一个完整的URL,于是当URL改变时,页面不会重新加载。
2、history模式:这种模式充分利用history.pushState API来完成URL跳转而无需重新加载页面。
//设置mode属性,设置路由模式
const router = new VueRouter({
  mode:'history',
  routes:[..]
})
19、vue如何优化首屏加载 ☆☆
20、vue性能优化
21、js 实现sleep函数

https://blog.csdn.net/qq_36711388/article/details/89787637

22、module.export、exports、export default、export有什么区别

https://www.cnblogs.com/little-baby/p/12783006.html

23、如何设计前端灰度发布

https://www.jianshu.com/p/1329b38ef5d4

24、每页返回10000条数据,如何优化前端渲染和交互体验

1、异步加载
2、碎片化
注:可能会问到滚动条的问题
https://blog.csdn.net/weixin_34116110/article/details/87946321
☆☆

25、移动端300ms延迟以及点击穿透 ☆☆
1、禁用缩放
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
2、改变视口宽度
<meta name="viewport" content="width=device-width" /> 
3、touch-action
设置 touch-action 属性,该设置会禁用掉该元素上的浏览器代理的任何默认行为,包括缩放,移动,拖拽等.它把所有的触摸类型的交互事件都禁止掉了,导致页面也不能滚动.感觉在稍微复杂点的实际开发中,应该不会这么设置吧.
html {
  touch-action: none;
}
4、引用fastclick库

参考地址:https://juejin.im/post/6854573211317698568

26、面试官:我这样this.xxx[xxx] = xxx,在data里添加一个数据,vue能不能侦测到?为什么?(有类似的问题) ☆☆

答:不能,在new Vue()初始化的时候,在实例的data初始化的数据,才能被侦测到;因为在生命周期beforeCreate到create钩子之间会进行将data中的数据进去双向绑定的侦测;实例初始化完之后再添加的数据,无办法完成侦测初始化

27、JS防抖与节流(性能优化) ☆☆

防抖:动作停止后的时间超过设定的时间时执行一次函数。注意:这里的动作停止表示你停止了触发这个函数,从这个时间点开始计算,当间隔时间等于你设定时间,才会执行里面的回调函数。如果你一直在触发这个函数并且两次触发间隔小于设定时间,则函数一直不会执行。

简单实现:

function debance(fn, delay) {
  let timer = null;
  return () => { 
   if (timer) { 
     clearTimeout(timer);
  }
  timer = setTimeout(() => {
    fn();
  }, delay);
};
} 
window.addEventListener( 
 "scroll",
  debance(() => { 
   console.log(111); 
 }, 1000) ); 

防抖应用场景:

  1. search搜索联想,用户在不断输入值时,用防抖来节约请求资源
  2. window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次

节流:一定时间内执行的操作只执行一次,也就是说即预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。

简单实现: 
//方法一:设置一个标志 
function throttle(fn, delay) { 
  let flag = true;
 return () => { 
  if (!flag) return; 
  flag = false;
   timer = setTimeout(() => { 
    fn();
   flag = true; }, delay);
 };
 }
 //方法二:使用时间戳 
function throttle(fn, delay) { 
  let startTime=new Date()
 return () => { 
  let endTime=new Date()
   if (endTime-startTime>=delay){ 
    fn() 
    startTime=endTime
   }else{ 
    return
   } 
  }; 
  }
 window.addEventListener(
   "scroll", 
  throttle(() => {
   console.log(111); 
  }, 1000) 
  ); 

节流应用场景:

  1. 鼠标不断点击触发,mousedown(单位时间内只触发一次)
  2. 监听滚动事件,比如是否滑到底部自动加载更多(懒加载)
28、get和post区别,哪个容易造成跨域问题,怎么解决跨域 ☆
GET请求会被浏览器主动cache,而POST不会,除非手动设置
get把请求的参数放在url上,即HTTP协议头上 post把参数放在HTTP的包体内
 Get 方式传输的数据量非常小,一般限制在 2 KB 左右,但是执行效率却比 >Post 方法好;而 Post 方式传递的数据量相对较大,它是等待服务器来读取数>据,不过也有字节限制(实际上IIS4中最大量为80KB,IIS5中为100KB),这是为>了避免对服务器用大量数据进行恶意攻击 
GET请求只能进行url编码,而POST支持多种编码方式 
GET产生的URL地址可以加入书签,而POST不可以 
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
 GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
29、前端安全 ☆☆

一、XSS攻击(跨站脚本攻击)
防御:
1、转义字符
2、白名单
二、CSRF(跨站请求伪造)
防御:
1、增加token在请求中放入攻击者不能伪造的信息
2、通过Referer识别
3、网站重要操作增加验证码

30、强缓存和协商缓存 ☆
31、获取当前页面中所有HTML tag的名字,以数组形式输出,不包含重复的标签

const getTagNameNum = () => {
  return new Set([...document.querySelectorAll('*')].map(el => el.tagName)).size
}

参考地址:https://blog.csdn.net/weixin_30386713/article/details/98829121

31、Vue模板编译过程

首先会先将模版通过解析器,解析成AST(抽象语法树),然后再通过优化器,遍历AST树,将里面的所有静态节点找出来,并打上标志,这样可以避免在数据更新进行重新生成新的Vnode的时候做一些无用的功夫,和diff算法对比时进行一些无用的对比,因为静态节点这辈子是什么样就是什么样的了,不会变化。接着,代码生成器会将这颗AST编译成代码字符串,这段字符串会别Vdom里面的createElement函数调用,最后生成Vnode。

32、computed和watch
33、说下v-if跟v-show区别
34、组件中的data为什么是一个函数

答:一个组件被复用多次的话,也就会创建多个实例。本质上,这些实例用的都是同一个构造函数。如果data是对象的话,对象属于引用类型,会影响到所有的实例。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数。

35、说一下v-model的原理

答:v-model本质就是一个语法糖,可以看成是value + input方法的语法糖。 可以通过model属性的prop和event属性来进行自定义。原生的v-model,会根据标签的不同生成不同的事件和属性。

36、Vue中组件生命周期调用顺序说一下

答:组件的调用顺序都是先父后子,渲染完成的顺序是先子后父。

组件的销毁操作是先父后子,销毁完成的顺序是先子后父。

加载渲染过程

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

子组件更新过程

父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新过程

父 beforeUpdate -> 父 updated

销毁过程

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

37、SSR了解吗 ☆ ☆

答:SSR也就是服务端渲染,也就是将Vue在客户端把标签渲染成HTML的工作放在服务端完成,然后再把html直接返回给客户端。

SSR有着更好的SEO、并且首屏加载速度更快等优点。不过它也有一些缺点,比如我们的开发条件会受到限制,服务器端渲染只支持beforeCreate和created两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境。还有就是服务器会有更大的负载需求。

38、Vue-router跳转和location.href有什么区别 ☆ ☆

答:使用location.href='/url'来跳转,简单方便,但是刷新了页面;
使用history.pushState('/url'),无刷新页面,静态跳转;
引进router,然后使用router.push('/url')来跳转,使用了diff算法,实现了按需加载,减少了dom的消耗。
其实使用router跳转和使用history.pushState()没什么差别的,因为vue-router就是用了history.pushState(),尤其是在history模式下。

39、params和query的区别 ☆ ☆
答:用法:query要用path来引入,params要用name来引入,接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name。
url地址显示:query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示
注意点:query刷新不会丢失query里面的数据
params刷新 会 丢失 params里面的数据。
40、vue-router 是什么?它有哪些组件

答:vue用来写路由一个插件。router-link、router-view
参开地址:https://juejin.im/post/6844903945530245133

41、怎么定义 vue-router 的动态路由? 怎么获取传过来的值?

答:在router目录下的index.js文件中,对path属性加上/:id。 使用router对象的params.id。

42、Promise.all 和 Promise.race

Promise.all是支持链式调用的,本质上就是返回了一个Promise实例,通过resolve和reject来改变实例状态。

Promise.myAll = function(promiseArr) {
  return new Promise((resolve, reject) => {
    const ans = [];
    let index = 0;
    for (let i = 0; i < promiseArr.length; i++) {
      promiseArr[i]
      .then(res => {
        ans[i] = res;
        index++;
        if (index === promiseArr.length) {
          resolve(ans);
        }
      })
      .catch(err => reject(err));
    }
  })
}

Promise.race = function(promiseArr) {
  return new Promise((resolve, reject) => {
    promiseArr.forEach(p => {
      // 如果不是Promise实例需要转化为Promise实例
      Promise.resolve(p).then(
        val => resolve(val),
        err => reject(err),
      )
    })
  })
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260