前端面试题合集

目录

一、css

1. 实现水平垂直居中

2. 文字如何实现水平垂直居中

3. 盒模型

4. flex布局

5. em,rem,px区别

6. 块状元素和行内元素

7. 重绘和重排

二、js

        1. 闭包的理解

2. 原型和原型链

3. new 关键字

4. cookies、sessionStorage和localstorage区别

5. 事件

6. 深拷贝,浅拷贝

7. this 指向的问题

8. 延迟加载

三、ES6

1. es6新增了哪些特性

2. 箭头函数

3. const、let与var的区别

4. 解构赋值

四、vue

1. MVC, MVVM 区别

2. 双向数据绑定原理

3. vue 生命周期

4. vue-router路由

5. vue 父子兄弟传参

6. keep-alive的作用

7. v-for 与 v-if 的优先级

8. v-show和v-if的区别

9. vue路由钩子函数

五、其他

1. ajax

2. get 和 post 的区别

3. 常见http状态码

4. http与https的区别

5. 三次握手和四次挥手


一、css

1. 实现水平垂直居中

1) 利用绝对定位absolute和margin完成元素居中,父元素添加相对定位,子元素添加绝对定位,margin负子元素宽高的一半

缺点:必须知道元素的宽和高

.box{    
    weight:200px;
    height:400px;

    <!--把元素变成定位元素-->
    position:absolute;

    <!--设置元素的定位位置,距离上、左都为50%-->
    left:50%;
    top:50%;

    <!--设置元素的左外边距、上外边距为宽高的负1/2-->
    margin-left:-100px;
    margin-top:-200px;
}

2) 给父元素加相对定位,子元素添加绝对定位,在设置元素的左、右、上、下位置为零,再利用自动居中对齐的方法margin:auto,完成元素的垂直水平居中

.box {   
    weight:200px;
    height:400px;

    position:absolute;

    left:0; 
    right:0;
    top:0;
    bottom:0;

    margin: auto;
}

 3) 设置父元素的元素类型为table-cell类型,设置表格的垂直对齐方式为居中,再给子元素添加margin:0 auto 完成元素的垂直水平居中

.box1 {
    width: 200px;
    height: 150px;
    display: table-cell;
    vertical-align: middle;
    margin-top: 100px;
}

.box2 {
    width: 50px;
    height: 50px;
    margin: 0 auto;
}

4) 给元素设置line-heght,也就是行高,完成元素的垂直居中,再然后利用文本水平对齐方式text-align方法,完成水平居中。缺点:只适合单行文本,多行文本不支持。

.box {
    line-height: 200px;
    text-align: center;
}

 5) 绝对定位加translate,不用设置宽高,用translate加绝对定位完成元素的居

.box1 {
    position: relative;
}

.box2 {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

 6) flex

让父元素形成弹性盒子,再然后设置主轴对齐方式为居中对齐,侧轴对齐方式为居中对齐从而完成元素的垂直水平居中。

.box {
    display: flex;
    justify-content: center;
    algin-items: center;
}

 或者:父元素形成弹性盒子,再然后给子元素添加margin:auto,完成元素的垂直水平居中

.box1 {
    display: flex;
}

.box2 {
    margin: auto;
}

2. 文字如何实现水平垂直居中

1) line-height对单行文本进行垂直居中

2) display和vertical-align对容器里的文字进行垂直居中

3) padding属性其实就是设置内边框的距离,并且设置上下左右边距的宽度,设置相等的边距,就会出现元素的垂直居中。

3. 盒模型

CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距(外边距)margin,边框border,填充(内边距)padding,和实际内容content。盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。

分类:W3C 盒子模型(标准模型):它的宽度和高度是 内容content 的宽度和高度。

设置:box-sizing: content-box;

IE 盒子模型:它的宽度和高度是 内容content + 内边距padding + 边框border 的宽度和高度和。

设置:box-sizing: border-box;

4. flex布局

弹性布局,为盒模型提供灵活性,当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式,目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。

首先,指定一个容器,任何一个容器都可以被指定为 flex 布局,通过对display 设置两种属性:flex 和inline-flex,(块元素如 div,使用 flex,行内元素,使用 inline-flex。)注意:当时设置 flex 布局之后,子元素的 float、clear、vertical-align 的属性将会失效。

flex 有六种属性设置在容器上:

  1. flex-direction    //属性决定主轴的方向(默认从左往右)
  2. flex-wrap          //如果一条轴线排不下,如何换行(默认不换行)
  3. flex-flow           //flex-direction属性和flex-wrap属性的简写形式(默认为row nowrap)
  4. justify-content  //定义在主轴上的对齐方式(默认左对齐)
  5. align-items       //在交叉轴上如何对齐(默认铺满)
  6. align-content    //多根轴线的对齐方式(默认轴线占满整个交叉轴)

六个属性设置在项目上:

  1. order          //定义项目在容器中的排列顺序,数值越小,排列越靠前,默认值为 0
  2. flex-basis   //在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间,默认值:auto
  3. flex-grow    //定义项目的放大比例,默认值为 0
  4. flex-shrink  //定义了项目的缩小比例,默认值: 1
  5. flex             //flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto
  6. align-self    //允许单个项目有与其他项目不一样的对齐方式,默认值为auto

(详见:Flex 布局教程:语法篇 - 阮一峰的网络日志
(flex属性:flex: 1;  //让所有弹性盒模型对象的子元素都有相同的长度,且忽略它们内部的内容。)

5. em,rem,px区别

px: 相对长度单位。像素px是相对于显示器屏幕分辨率而言的。

em: 相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。em的值并不是固定的; em会继承父级元素的字体大小。

rem: CSS3新增的一个相对单位,使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。

6. 块状元素和行内元素

块状元素<div>、<p>、<h1>...<h6>、<ol>、<ul>、<dl>、<table>、<address> 、<form>

每个块级元素都从新的一行开始,并且其后的元素也另起一行; 元素的高度、宽度、行高以及顶和底边距都可设置; 元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度。
行内元素(又叫内联元素):<a>、<span>、<br>、<i>、<label>、<q>、<code>

和其他元素都在一行上;元素的高度、宽度及顶部和底部边距不可设置;元素的宽度就是它包含的文字或图片的宽度,不可改变。
内联块状元素<img>、<input>

display:inline-block就是将元素设置为内联块状元素。和其他元素都在一行上;元素的高度、宽度、行高以及顶和底边距都可设置。

7. 重绘和重排

重绘就是重新绘制,不会影响页面布局的操作,比如更改颜色。
重排就是页面的布局改变导致需要重新构建,比如改变元素的大小或位置。

二、js

1. 闭包的理解

1、闭包的概念就是:闭包是在一个函数里声明了另外一个函数,并且这个函数访问了父函数作用域里的变量。

2、闭包可以重用一个变量,且保证这个变量不会被污染的一种机制。这些变量的值始终保持在内存中,不会被垃圾回收机制处理

3、闭包的缺点:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

4、为什么要用闭包:使用场景 : 防抖、节流、函数套函数避免全局污染

2. 原型和原型链

原型:

每一个函数天生自带一个 prototype 属性,是一个对象数据类型。当函数出现的时候,就会产生prototype;每一个对象天生自带一个属 __proto__,指向所属构造函数的prototype;当你访问对象成员的时候,首先在自己身上查找,如果没有,自动去到__proto__上查找。

总之,原型就是 构造函数天生自带的一个 prototype ,作用是由构造添加方法,专门给实例对象使用。

原型链:

当查找一个对象的某个属性时,会先从它自身的属性上查找,

如果找不到的话会从它的_proto_属性上查找,就是这个构造函数的prototype属性,

如果还没找到就会继续在_proto_上查找,直到最顶层,找不到则为undefined,

像这样一层一层去查找形成一个链式的称为原型链

3. new 关键字

new一个函数,中间发生了什么

1.开辟一个内存空间,也就是创建一个空对象,obj={}或obj=new Object()

2.将这个新对象的_proto_属性指向它构造函数的prototype

3.将构造函数this绑定为这个新对象,在空对象上挂在属性和方法(call或apply方式)

4.返回这个新对象

4. cookies、sessionStorage和localstorage区别

① 存储大小:cookie数据大小不超过4k,sessionStorage和 localstorage一般为5MB左右
② 有效时间:localStorage存储持久数据,除非被手动删除,否则会永久保存; sessionStorage仅在当前会话下有效,数据会在当前浏览器窗口关闭后自动删除。cookie一般由服务器生成,可以设置失效时间,如果设置了cookie的过期时间,cookie在过期时间之前都会有效,即使关闭窗口或浏览器。
③ 与服务器通信:cookie数据会在服务器和浏览器之间来回传递,sessionStorage和localstorage不会把数据发送给服务器,仅在本地保存。

5. 事件

事件是文档和浏览器窗口中发生的特定的交互瞬间,事件就发生了。一是直接在标签内直接添加执行语句,二是定义执行函数。 DOM事件分为两种类型

事件类型分两种:事件捕获、事件冒泡。 事件捕获就是:网景公司提出的事件流叫事件捕获流,由外往内,从事件发生的顶点开始,逐级往下查找,一直到目标元素。 事件冒泡:IE提出的事件流叫做事件冒泡就是由内往外,从具体的目标节点元素触发,逐级向上传递,直到根节点。

什么是事件流?事件流就是,页面接受事件的先后顺序就形成了事件流。

自定义事件:就是自己定义事件类型,自己定义事件处理函数。

6. 深拷贝,浅拷贝

深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。

1.浅拷贝:

将原对象或原数组的引用直接赋给新对象,新数组,新对象只是对原对象的一个引用,而不复制对象本身,新旧对象还是共享同一块内存

如果属性是一个基本数据类型,拷贝就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,

2.深拷贝:

创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

深拷贝就是把一个对象,从内存中完整的拷贝出来,从堆内存中开辟了新区域,用来存新对象,并且修改新对象不会影响原对象

3、赋值:

当我们把一个对象赋值给一个新的变量时,赋的是该对象在栈中的内存地址,而不是堆中的数据。也就是两个对象


7. this 指向的问题

在全局的环境下this是指向window 的

普通函数调用直接调用中的this 会指向 window, 严格模式下this会指向 undefined,自执行函数 this 指向 window,定时器中的 this 指向 window

在对象里调用的this,指向调用函数的那个对象,

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

方法中的this谁调用就指向谁。

箭头函数没有自己的 this,箭头函数的this在定义的时候,会继承自外层第一个普通函数的this

8. 延迟加载

JavaScript会阻塞DOM的解析,因此也就会阻塞DOM的加载。所以有时候我们希望延迟JS的加载来提高页面的加载速度。

1.把JS放在页面的最底部;

2.script标签的defer属性:脚本会立即下载但延迟到整个页面加载完毕再执行。该属性对于内联脚本无作用 (即没有 「src」 属性的脚本)。

3.是在外部JS加载完成后,浏览器空闲时,Load事件触发前执行,标记为async的脚本并不保证按照指定他们的先后顺序执行, 该属性对于内联脚本无作用 (即没有 「src」 属性的脚本)。

4.动态创建script标签,监听dom加载完毕再引入js文件。

三、ES6

1. es6新增了哪些特性

新增了块级作用域(let,const)

提供了定义类的语法糖(class)

新增了一种基本数据类型(Symbol)

新增了变量的解构赋值

函数参数允许设置默认值,引入了 rest 参数,新增了箭头函数

数组新增了一些 API,如 isArray / from / of 方法;数组实例新增了entries(),keys() 和 values() 等方法

对象和数组新增了扩展运算符

ES6 新增了模块化(import/export)

ES6 新增了 Set 和 Map 数据结构

ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例

ES6 新增了生成器(Generator)和遍历器(Iterator)
 

2. 箭头函数

箭头函数,就是在 ES6 的语法中对函数表达式的简写,但是对声明式函数不能使用,在某些规则上又和以前的函数有一些不一样。

函数表达式,又叫做 匿名函数,也就是我们不需要单独定义函数,直接使用的位置。

箭头函数的写法:在书写函数时,省略 function 不写,在小括号和大括号之间书写箭头。

1、 箭头函数是匿名函数不能作为构造函数,不能使用new;

2、 箭头函数不绑定arguments,取而代之用rest参数…解决,

3、 this指向不同,箭头函数的this在定义的时候继承自外层第一个普通函数的this;

4、 箭头函数通过call()或apply()调用一个函数,只传入了一个参数,对this并没有影响。

5、 箭头函数没有prototype(原型),所以箭头函数本身没有this,箭头函数内的 this 就是外部作用域的 this;

6、 箭头函数不能当做Generator函数,不能使用yield关键字、

7、 写法不同,箭头函数把function省略掉了 ()=> 也可以吧return 省略调 写法更简洁

8、箭头函数不能通过call()、apply()、bind()方法直接修改它的this指向。

3. const、let与var的区别

var、let 是用来声明变量的,而const是声明常量

1)let / const 与 var 的区别:

  • var 会进行预解析,let 和 const 不会进行预解析;
  • var 可以声明两个重名的变量,let 和 const 不能定义重名变量
  • var 没有块级作用域, let 和 const 有块级作用域 

2) let 和 const 的区别:

  • let 可以定义变量的时候  进行赋值,const 在定义时必须赋值。
  • let 定义的变量可以被修改,const 定义的常量一经赋值不能被修改。

4. 解构赋值

解构赋值:快速从 对象 或者 数组 中获取成员

解构赋值分成两种:数组的解构赋值,对象的解构赋值

四、vue

1. MVC, MVVM 区别

MVVM分为:M(model数据)、V(view试图)、VM(viewModel控制数据的改变和控制试图), MVVM与MVC最大的区别就是:它实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作Dom元素,来改变View的显示,而是改变属性后该属性对应View层显示会自动改变。ViewModel层的核心是Vue中的双向数据绑定,即Model变化时VIew可以实时更新,View变化也能让Model发生变化。

2. 双向数据绑定原理

是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调从而达到数据和视图同步。

MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

3. vue 生命周期

beforeCreate() 创建前,这个时候data中的数据,还未定义,所以不能使用。
created()创建后, 最早开始使用 data和methods中数据的钩子函数。

beforeMount()挂载前, 指令已经解析完毕内存中已经生成dom树,但是尚未挂载到页面中去,此时页面还是旧的。
mounted()挂载后, dom已经渲染完毕,此时页面和内存中都是最新的数据,最早可以操作DOM元素钩子函数。

 beforeUpdate()更新前, 当视图层的数据发生改变会执行这个钩子 内存更新,但是DOM节点还未更新,数据没有与页面同步。
 updated()更新后, 数据更新完成以后触发的方法,DOM节点已经更新。

 beforeDestroy()即将销毁, data和methods中的数据此时还是可以使用的,可以做一些释放内存的操作。
 destroyed()销毁完毕,  组件已经全部销毁,Vue实例已经被销毁,Vue中的任何数据都不可用。

4. vue-router路由

在vue-router单页面应用中,则是路径之间的切换,实际上就是组件的切换。路由就是SPA(单页应用)的路径管理器。再通俗的说,vue-router就是我们WebApp的链接路径管理系统。

路由有两种模式 hash和history模式 默认是hash

vue-router的实现原理(核心):更新视图但不重新请求页面。

1、hash ——即地址栏 URL 中的#符号,它的特点在 于:hash 虽然出现 URL 中,但不会被包含在 HTTP 请求中,对后端完全没有影 响,因此改变 hash 不会重新加载页面。

2、history ——利用了 HTML5 History api 在浏览器中没有# 有浏览器兼容问题

3、history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,否则返回 404 错误。

路由跳转的方式:

1、<router-link to="需要跳转到页面的路径">

2、this.$router.push()跳转到指定的url,并在history中添加记录,点击回退返回到上一个页面

3、this.$router.replace()跳转到指定的url,但是history中不会添加记录,点击回退到上上个页面

4、this.$touter.go(n)向前或者后跳转n个页面,n可以是正数也可以是负数

5. vue 父子兄弟传参

父子 props/event $parent/$children ref provide/inject

兄弟 bus vuex

父传子:在父组件的子组件标签上绑定一个属性,挂载要传输的变量 ​ (2)在子组件中通过props来接受数据,props可以是数组也可以是对象,接受的数据可以直接使用 props: ["属性名"] props:{属性名:数据类型}

子传父:(1)在父组件的子组件标签上自定义一个事件,然后调用需要的方法 ​ (2)在子组件的方法中通过 this.$emit("事件")来触发在父组件中定义的事件,数据是以参数的形式进行传递的。

兄弟之间:(1)找到min.js文件,给他vue挂载一个 公共的 $bus Vue.prototype.$bus = new Vue() ​ (2)传送数据的一方 用this.$bus.$emit('事件名','传送的数据') ​ (3)在 接收数据的一方用通过 Bus.$on("事件名",(data)=>{data是接受的数据})
 

6. keep-alive的作用

keep-alive保存页面/组件的状态缓存组件,防止二次渲染,这样会大大的节省性能

7. v-for 与 v-if 的优先级

v-for 比 v-if 优先,源码中,会对v-for先进行判断,然后才是v-if,所以v-for优先级大于v-if优先级。另外,渲染中,判断是在内部的,列表渲染函数在外部,所以是先循环,然后再进行判断。

为了避免这种情况,在外层嵌套<template>,在这一层进行v-if判断,然后再在内部进行v-for循环。

8. v-show和v-if的区别

v-if 动态的创建或者销毁元素,为true的时候为显示,为false的时候不显示,要使用v-else必须和v-if紧挨着

v-show 是控制元素的显示或者隐藏,在我们的标签上会看到有display:block,none

v-if 有更高的切换消耗,而 v-show 有更高的初始化渲染消耗,一般推荐频繁切换的时候使用 v-show 更好,当我们的判断分支比较多的时候,和首次渲染的时候 使用v-if。

9. vue路由钩子函数

1:全局钩子: beforeEach、 afterEach、beforeResolve

2:单个路由里面的钩子:  beforeEnter

3:组件路由:beforeRouteEnter、 beforeRouteUpdate、 beforeRouteLeave

beforeEach:每次每一个路由改变的时候都得执行一遍;可进行一些页面跳转前处理,例如判断需要登录的页面进行拦截,做登录跳转!!

afterEach:router.beforeEach 是页面加载之前,相反router.afterEach是页面加载之后

  beforeRouteEnter (to, from, next) {// 在渲染该组件的对应路由被 confirm 前调用; 不!能!获取组件实例 `this`,因为当钩子执行前,组件实例还没被创建

  beforeRouteUpdate (to, from, next) { // 在当前路由改变,但是该组件被复用时调用可以访问组件实例 `this`

  beforeRouteLeave (to, from, next) // 导航离开该组件的对应路由时调用;可以访问组件实例 `this`

五、其他

1. ajax

步骤:1)  创建 ajax 对象:var xhr = new XMLHttpRequest()

2. 配置本次请求信息: xhr.open(请求方式,请求地址,是否异步)

        请求方式:按照接口文档进行书写
        请求地址:按照接口文档书写,基准地址+请求地址
        是否异步:默认是 true 表示异步请求,选填为false,表示同步请求

3. 注册请求完成事件: xhr.onload = function () {}

        请求完成:本次请求发送出去,服务器接收到了我们的请求,并且服务器返回的信息已经回到浏览器。

        如何拿到后端返回的数据? 语法:xhr.responseText

4. 把请求发送出去: xhr.send()
 

2. get 和 post 的区别

GETPOST
偏向获取的语义化偏向提交的语义化
参数是查询字符串参数格式多样,但是需要特殊说明
大小有限制 2KB 左右理论上没有限制
参数位置在地址后面

                                        参数位置在请求体内

3. 常见http状态码

    200响应成功
    301永久重定向
    302临时重定向
    304资源缓存
    403服务器禁止访问
    404服务器资源未找到
    500 502服务器内部错误
    504 服务器繁忙
    1xx Informational(信息状态码)      接受请求正在处理
    2xx Success(成功状态码)            请求正常处理完毕
    3xx Redirection(重定向状态码)      需要附加操作已完成请求
    4xx Client Error(客户端错误状态码)  服务器无法处理请求
    5xx Server Error(服务器错误状态码)  服务器处理请求出错

4. http与https的区别

1.HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
2.HTTP 是不安全的,而 HTTPS 是安全的
3.HTTP标准端口是80 ,而 HTTPS 的标准端口是443
4.在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
5.HTTP 无法加密,而HTTPS 对传输的数据进行加密,证的网络协议,安全性高于HTTP协议。
6.HTTP无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书,一般免费证书少,因而需要一定费用。


5. 三次握手和四次挥手

三次握手:

1:建立连接时,客户端发送syn包到服务器,等待服务端确认

2:服务器收到syn包,必须确认客户的syn,同时也发送一个syn包,即syn+ACK包

3:客户端收到服务器的syn和ack包,向服务器发送确认包ack,发送完毕,客户端和服务端连接成功,完成三次握手。

四次挥手:

1:浏览器发送完数据后,发送fin请求断开连接

2:服务器发送ack到客户端,确认客户端的断开请求

3:服务器请求断开fin的请求

4:客户端确认服务器的断开ack

参考:2022年最新前端面试题(大前端时代来临卷起来吧小伙子们..持续维护走到哪记到哪)_有两把刷子的博客-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值