2023前端面试题集锦(js+vue) 前端2020最新面试题


JS篇

1.es6新特性

1.let、const变量声明

2.模板字符串

3.箭头函数

4.spread/rest操作符,就是...

5.使用新的super和extends关键字扩展类:

6.async/await,比promise更好的解决了回调地狱

7.symbol基本数据类型

2.谈谈对promise的理解

promise是es6中新增的一个构造函数,是为了解决异步操作中数据调用嵌套(回调地狱)的问题。

promise对象提供两个方法 resolve 和 reject 那么需要拿到他们的结果 就需要用到promis对象下的then和carch


promise是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息,从字面意思上讲,它是一种承诺,承诺过一段时间会返回一个结果。


什么是回调地狱:函数做为参数传入方法中,一般方法的回调嵌套不会很多层,一般就一到两层,但是某些情况下,回调嵌套层数很多的时候,代码就会很繁琐,给编程带来麻烦,这就是回调地狱,promise就是解决这个问题的

Promise解决的问题

1. 解决回调地狱的问题,代码难以维护,第一个函数的输出是第二个函数的输入这种情况

2. Promise可以支持多个并发的请求,获取并发请求中的数据

3. Promise可以解决异步的问题,但它并不是异步的


3.Null和undefined区别

Null:表示定义了一个对象,值为空值,转换为数值类型为0

Undefined:一般用于表示无效数据,未定义,转换为数值类型为NAN


4.什么是闭包

闭包是指可以访问另一个函数作用域中的变量的函数,也可以说是在函数内部声明函数的语法

特点:函数嵌套函数,内层函数可以访问外层函数的变量或参数,变量或参数不会被垃圾回收机制回收

优点:可以重复使用变量,不会污染全局的一种机制,可以一直保存在内存中,不会被垃圾回收机制回收

缺点:闭包较多时,会消耗内存,影响性能,容易造成内存泄漏,在退出函数时删除不使用的变量


5.原型链和作用域链的区别


原型链

当访问一个对象的属性时, 会在这个对象的属性上去找,如果没有找到就会去这个对象的--proto-- 上去找,即构造函数prototype 上找,如果没有会一直在--proto-- 上找,直到最顶层,找不到即为undefined 。这样一层一层地向上,就彷佛一条链子串起来,所以就叫原型链。

一个实例对象在调用属性或方法时,会依次从实例本身、构造函数原型、对象原型的原型上一层层查找的过程好像一个链条,就是原型链

先在对象本身找 è 构造函数中找 è 对象原型中找 è 构造函数原型中找 è Object原型中找

例:

Function Fun(){

This.a = ‘Fun函数中添加的’;

}

Fun.prototype.a = ‘Fun函数原型中添加的’

Let obj = new Fun();

Obj.a = ‘对象本身的’

Obj.__proto__.a= ‘对象原型中添加的’

Object.prototype.a = ‘Object添加的’

作用域链

作用域链本质上是一个指向变量对象的指针列表

变量取值会到创建这个变量的函数的作用域中取值,如果找不到,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链

区别就是

作用域链是相对于变量而言, 原型是相对于属性而言

作用域最顶层是window ,原型链最顶层是Object。


1.构造函数是使用了new关键字的函数,用来创建对象,所有函数都是Function()的实例

2.原型对象是用来存放实例对象的公有属性和公有方法的一个公共对象,所有原型对象都是Object()的实例

3.原型链又叫隐式原型链,是由__proto__属性串联起来,原型链的尽头是Object.prototype

作用域优先级:

声明变量 > 声明普通函数 > 参数 > 变量提升


6.说一说对前端内存泄漏的理解

Js已经分配了内存地址的对象,但是由于长时间没有释放或者没办法清楚,造成长期占用内存的现象,会让内存资源大幅浪费,最终导致运行速度慢,甚至崩溃的情况


7.JS基本数据类型和引用数据类型的区别

基本数据类型:string,number,boolean,null,undefined,保存在栈内存,保存的是一个值

引用数据类型:object,function,array,保存在堆内存中,声明一个引用类型的变量,他保存的引用类型数据的地址;假如声明两个引用数据类型同时指向一个地址时,改变其中一个那么另一个也会改变

8.this指向问题

箭头函数没有this,要看外层有没有函数,有的话指向外层,没有就是指向window

匿名函数的this永远指向window,匿名函数的执行环境具有全局性,所以他指向window

New 关键字改变this的指向

Apply,call,bind可以改变this的指向

全局对象中的this/全局作用域或普通函数的this指向的是window

This永远指向最后调用他的那个对象


9.async和defer的区别

共同点:都是延迟加载

不同点:

Defer: 等html全部解析完成,才会执行js代码,而且是顺次执行js脚本

Async: async是和html解析同步的,不是顺次执行js脚本(谁先加载完谁先执行)

10. == 和 === 的区别

==:比较值

用的valueOf做的隐式转换,如果重写了valueOf方法,就不会生效了( object.prototype.valueOf = function(){ xxxx} )

===:比较值,还回比较数据类型


11. new操作符具体做了什么

1. 创建了一个空对象

2. 将空对象的原型指向了构造函数的原型

3. 将空对象作为构造函数的上下文(改变this的指向)

4. 对构造函数有返回值的处理判断


12. Js微任务和宏任务

1. Js语言的最大特点是单线程;

2. Js代码执行流程:先执行同步任务,è进入事件循环

同步任务都执行完了,才会执行事件循环的内容

进入事件循环的有:请求、定时器、事件

3.事件循环中包含【微任务和宏任务】

微任务:promise.then

宏任务:settimeouT

要执行红任务的前提是清空了所有的微任务

同步任务,è事件循环è微任务è宏任务è微任务…

13. 怎么实现深浅拷贝

深拷贝:

1. Json.parse(Json.stringfy()): 此方法不能拷贝内部函数

2. 递归函数实现


浅拷贝:

1.扩展运算符(...):只能对对象或数组的第一层做深拷贝,如果是多维数组或者多层对象就不行

2.Object.assgin

14. 什么是同源策略

同源策略:协议、域名、端口号3者相同时就是同源,其中一个不同就不是同源,就会产生跨域

跨域时可以发送请求,后端也会返回内容,只不过结果会被浏览器拦截

15. http协议规定的请求头和响应头有什么

请求头信息:(reuqest-headers)

Accept:浏览器告诉服务器所支持的数据类型

Host:浏览器告诉服务器我想访问服务器哪台主机

Referer:浏览器告诉服务器我是从哪里来的(做防盗链的)

User-Agent:浏览器类型和版本信息

Date:浏览器告诉服务器我是什么时候访问的

Connection:连接方式

Cookie

X-Request-With:请求方式

响应头信息:(response-headers)

Location:告诉浏览器你要找谁

Server:告诉浏览器服务器的类型

Content-Type:告诉浏览器返回的数据类型

Refresh: 控制浏览器的定时刷新

16.浏览器的缓存策略

强缓存(本地缓存):不发请求,直接使用缓存里的内容,浏览器把Js、Css、Image等存到内存中,下次用户访问直接从内存取,提高性能

弱缓存(协商缓存):需要向后台发起求,通过判断来决定是否使用协商缓存,如果请求内容没有变化,则返回304,浏览器就用缓存里的内容

17.页面渲染过程(输入url后做了什么操作)

DNS解析(域名解析)

建立TCP连接

发送HTTP请求

服务器处理请求

渲染页面:

浏览器会获取html和css资源,然后把html解析成DOM树

再把css解析成CSSOM

把DOM和CSSOM合并成渲染树

然后进行布局

把渲染树的每个节点渲染到屏幕上(绘制)

断开TCP连接

18.重排和重绘的区别

重排(回流):布局引擎会根据所有的样式计算出盒模型在页面上的位置大小

重绘: 计算好盒模型的位置、大小和其他一些属性后,浏览器会根据每个盒模型的特性进行绘制。

浏览器的渲染机制

对DOM的大小、位置进行修改后,浏览器需要重新计算元素的这些几何属性,就叫做重排

对DOM的样式进行修改,比如color、背景色,浏览器不需要重新计算几何属性的时候,直接绘制了该元素的新样式,那么这就触发了重绘

19.js检测数据类型的方法有哪些,他们有什么区别

1. typeof: 对于基本数据类型没问题,遇到引用数据类型就不管用

console.log(typeof 666) // number

console.log(typeof [1,2,3]) // object

console.log(typeof null) // object

console.log(typeof undefined) // undefined


2. instanceof:只能判断引用数据类型,不能判断基本数据类型

console.log([] instanceof Array) // true

console.log(‘123456’ instanceof String) // false

3. constructor: 几乎可以判断基本数据类型和引用数据类型。但是如果声明了一个构造函数,并把它指向了Array,就不管用了

console.log((‘abc’). Constructor=== String) // true

4. Object.protottype.toString.call()

Var obj = Object.prototype.toString

Console.log(obj.call(2)) //number

Console.log(obj.call(true)) //Boolean

Console.log(obj.call(‘aaa’)) //string

Console.log(obj.call([])) //arrary

Console.log(obj.call({})) //object


20.cavas和svg的区别

Canvas描述:

通过Javascript来绘制2D图形。

是逐像素进行渲染的。

其位置发生改变,会重新进行绘制。


SVG描述:

一种使用XML描述的2D图形的语言

SVG基于XML意味着,SVG DOM中的每个元素都是可用的,可以为某个元素附加Javascript事件处理器。

在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。

SVG与canvas的区别

(1)SVG是用来描述XML中2D图形的语言,canvas借助JavaScript动态描绘2D图形

(2)SVG可支持事件处理程序而canvas不支持

(3)SVG中属性改变时,浏览器可以重新呈现它,适用于矢量图,而canvas不可以,更适合视频游戏等。

(4)canvas可以很好的绘制像素,用于保存结果为png或者gif,可做为API容器。

(5)canvas取决于分辨率。SVG与分辨率无关。

(6)SVG具有更好的文本渲染,而Canvas不能很好的渲染,渲染中的SVG可能比Canvas慢,特别是应用了大量的DOM。

(7)画布更适合渲染较小的区域。SVG渲染更好的更大区域。

21.map和set的区别

Map 和 Set 数据结构是ES6语法,最大优点就是运行时间少大大提高了性能。

(1) 这两种方法具有极快的查找速度

(2) 初始化需要的值不一样,Map需要的是一个二维数组,而Set 需要的是一维 Array 数组

(3) Map 和 Set 都不允许键重复

(4) Map的键是不能修改,但是键对应的值是可以修改的;Set不能通过迭代器来改变Set的值,因为Set的值就是键。

(5) Map 是键值对的存在,值也不作为健;而 Set 没有 value 只有 key,value 就是 key;


VUE篇

1. 路由模式和实现原理

Hash模式:

实际就是在url地址栏上有#,hash值就是#后面的东西,特点是不会被包含在http请求中,对后端没有影响,因此,改变hash不会重新加载页面。

可以为hash的改变添加监听

History模式:

利用h5新增的pushState()和replaceState(),在当前已有的back、forword、go的基础上,提供了对历史记录进行修改的功能

2. 什么是双向绑定?原理是什么?怎么实现

1. 把数据层(model)的数据绑定到视图层(view),是单向绑定,如果改变视图层的数据时数据层也自动被更新了,就是双向绑定了

2. 业务逻辑层(viewModel):

主要职责是:数据变化更新视图,视图变化更新数据

还有两个主要组成部分:监听器(Observer)--对所有数据的属性进行监听,解析器(Compiler)--对每个元素节点的指令进行扫描跟解析,根据指令模板替换数据,以及绑定相应的更新函数

3.最后通过wathcer把Observer和Compiler联系起来,最终达到数据变化更新视图,视图变化更新数据的操作

3.做过那些vue的性能优化

1.编码优化:

不要把所有数据都放在data里,对象层级不要太深,区分v-if和v-show的使用场景,v-for要加key,避免同时使用v-if,适当使用keepalive缓存组件,合理使用路由懒加载,异步路由

2.加载优化:

按需加载,内容懒加载,图片懒加载

3.用户体验:骨架屏

4.Seo优化:预渲染,服务端渲染(SSR)

5.打包优化:CDN形式加载第三方模块,多线程打包,抽离公共文件

6.缓存和压缩:客户端缓存,服务端缓存,服务端Gzip压缩

4.vue中使用了那些设计模式

1、工厂模式 - 传入参数即可创建实例

虚拟 DOM 根据参数的不同返回基础标签的 Vnode 和组件 Vnode。

2、单例模式 - 整个程序有且仅有一个实例

vuex 和 vue-router 的插件注册方法 install 判断如果系统存在实例就直接返回掉。

3、发布-订阅模式。(vue 事件机制)

4、观察者模式。(响应式数据原理)

5、装饰器模式(@装饰器的用法)

6、策略模式,策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现方案 - 比如选项的合并策略。

5.多环境打包

1.添加配置文件。在config文件夹中添加开发环境,测试环境,生产环境的配置文件,格式为。.env.js

2.在package.json配置需要的环境运行命令

3.更改webpack配置文件,build文件夹下的webpack,主要是判断打什么环境的包

6.vuex是什么

State:定义数据结构

Getter:可以对State进行计算操作,在多个组件间复用,相当于计算属性

Mutation:同步提交操作

Action:异步操作,提交mutation

Module:拆分多个模块,每个模块里拥有自己的state,mutation,action,getter

7. 路由钩子函数

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

全局的路由钩子函数:beforeEach、beforeResolveafterEach

单个的路由钩子函数:beforeEnter

组件内的路由钩子函数:beforeRouteEnter、beforeRouteLeave、beforeRouteUpdate

执行顺序:A路由跳转B路由的执行顺序

A的beforeRouteLeave > 全局的beforeEach > B路由的beforeEnter > B组件的beforeRouteEnter > 全局 的beforeResolve > 导航被确认 > 全局的afterEach


8. v-for为什么要加key

key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点,提升性能

key是每一个节点的唯一标识

9. vue3和vue2的区别,有什么优缺点

响应式原理的改变: Proxy 替代 Object.defineProperty。因为 Proxy 可以直接监听对象和数组的变化,并且有多达13种拦截方法。

组件选项声明方式:使用组合式API,添加了setup属性,setup是组合式api的入口

模板语法的改变:slot具名插槽语法,自定义指令升级

10. Vue 2.0 响应式数据的原理

1. 用object.defineproperty将数据进行劫持,

2. 使用getter收集依赖,setter通知watcher派发更新

3. Watcher发布订阅模式

采用数据劫持结合发布订阅者模式实现的,就是通过object.defineproperty来劫持各个属性的getter和setter,在数据变动时发布消息给订阅者,触发相应的监听回调

11.watch和computed的区别

Watch:是一个数据影响多个数据

Computed:是多个数据影响一个数据,只有存在依赖数据,并且数据发生改变才会触发计算操作,并且他有缓存

Methods:是定义函数的,需要手动调用,而不像Watch和Computed,当依赖数据变化时,所有依赖这个数据的其他相关数据自动发现改变,也就是自动调用项目函数去实现数据变动

12.data为什么是函数

数据已函数的形式返回,每次复用一次组件,都会返回一个新的data,相当于有一个私有空间,不会造成这个组件里data发生改变影响另一个组件

13.组件通讯方式有哪些

1、props 和 $emit。父组件向子组件传递数据是通过props传递的,子组件传递给父组件是通过$emit触发事件来做到的。

2、$parent 和 $children 获取单签组件的父组件和当前组件的子组件。

3、$refs 获取组件实例。

4、envetBus 兄弟组件数据传递,这种情况下可以使用事件总线的方式。

5、vuex 状态管理。

14.单页应用首屏加载慢怎么解决

1.路由懒加载:以函数的形式加载路由,这样就可以把路由文件分别打包,只有解析指定路由时才加载对应的路由组件

2.静态资源本地缓存:localStorage,seesionStorage等缓存方式

3.图片压缩,图片懒加载

4.组件按需加载

5.减少重复请求

6.做一些loading动画

15.require和import的区别

require和import分别使用在:

· require 是赋值过程并且是运行时才执行,也就是异步加载。

· require可以理解为一个全局方法,因为它是一个方法所以意味着可以在任何地方执行。

· import 是解构过程并且是编译时执行。

· import必须写在文件的顶部。

  require和import的优缺点比较:

require的性能相对于import稍低,因为require是在运行时才引入模块并且还赋值给某个变量,而import只需要依据import中的接口在编译时引入指定模块所以性能稍高。

准确来说是require配置是为了懒加载:
import:当项目打包时路由里的所有component(组件)都会打包在一个js中,造成进入首页时,需要加载的内容过多,时间相对比较长。
require:这种方式引入的时候,会将你的component(组件)分别打包成不同的js,加载的时候也是按需加载,只用访问这个路由网址时才会加载这个js。

16.vue项目目录介绍

build:存放webpack编译配置和打包的脚本文件

config:存放编译参数配置文件

dist:发布后的目录

node_modules:第三方包模块的安装目录

src:源码目录(开发人员主要在这个目录下进行开发工作)

src/components:公共组件目录

src/config:存放编译发布配置文件(按需编译和发布)

src/pages:所有页面的目录

src/pages/system:子系统(业务模块)目录

src/pages/system/group:页面目录(一个页面需要一个目录)src/pages/system/static:业务模块静态资源(含公共js)

src/static:项目静态资源目录(css、image、font、公共js等)

src/templates:存放项目共同的母版页文件


Css篇

1. css的盒模型

标准盒模型:box-sizing:content-box; margin、border、padding、content

IE盒模型 :box-sizing:border-box; margin、content(border + padding + content)


2. 什么是BFC

Block Formatting content就是页面上一个隔离的独立容器,容器里的子元素不会影响外面的元素

触发条件:

根元素

float的值不为none

overflow的值不为visible

display的值为inline-block、table-cell、table-caption

position的值为absolute或fixed

原文链接:,转发请注明来源!