当前位置:   article > 正文

2023前端超全面试题,全是金三银四面试真题整理!附答案。_前端面试题2023

前端面试题2023

目录

HTML

标签语意化

HTML5新特性

SEO

input元素的类型

iframe的特点

CSS

Flex

BFC

重排重绘

CSS优先级

CSS3新特性

清除浮动的方法

盒模型的理解

响应式布局

移动适配方案

三栏布局

圣杯布局和双飞翼布局

JS

JS为何是单线程

JS数据类型

js判断数据类型

js中的length属性

判断空对象

判断空数组

ES6新特性

ES6 Module 和 CommonJS 的区别

箭头函数和普通函数区别

new一个对象做了什么事情

构造函数与普通函数的区别

防抖和节流

深拷贝浅拷贝

数组去重

原型链

call、bind、apply的含义和区别

Class

Class和构造函数的区别

js继承的几种方式及其优缺点

闭包

浏览器的缓存机制

任务队列(宏/微任务)

事件委托

请求

请求的方式有哪些,应用场景是什么

什么是promise,解决了什么问题

谈谈对async/await的理解

跨越问题如何解决

输入网站url地址后发生了什么

ajax工作流程及原理

axios 是什么、怎么使用

Localstorage、sessionStorage、cookie 的区别

后端接口没写出来,前端如何进行开发

post请求和get请求的区别

Session,Token,Cookie在身份认证方面的区别

常见的状态码

Vue2

Vue是什么

MVVM

观察者模式和发布订阅者模式

SPA(单页应用)的理解

响应式原理

Vue2生命周期

data为什么是函数的存在

Vue组件通信的方式

keep-alive原理及缓存策略

computed原理

watch原理

computed和methods、watch的区别

vue-router原理

Vue3

Vue2和Vue3响应式原理的区别

Vue3生命周期

选项式API和组合式API

VueX和Pinia的区别、优劣

Vite好在哪为什么

TS

对ts的理解

ts的数据类型

never和void的区别

枚举的理解

泛型

项目

token超时处理

登录页面安全问题

发布通知功能怎么实现

项目刚上线出现bug

用什么进行版本管理

Echarts在Vue里怎么使用

Echarts里的配置项不够用怎么办

团队中有的人用vue2有的人用vue3怎么办

项目优化

PC端兼容问题

img下的留白

如果图片加a标签在IE9-中会有边框

移动端问题

移动端页面滚动滞涩感

修改移动端的点击高亮效果

滚动穿透问题

在ios和andriod中,audio元素和video元素在无法自动播放

iOS 系统中文输入法输入英文时,字母之间可能会出现一个六分之一空格

IOS移动端click事件300ms的延迟响应

阻止旋转屏幕时自动调整字体大小

图片模糊问题

移动端某些情况下input的placeholder会出现文本位置偏上的现象

h5底部输入框被键盘遮挡问题

移动端如何做真机测试

H5和app的区别


HTML

标签语意化

简单来说:就是用正确的标签做正确的事。比如:

  • 头部:header

  • 导航:nav

  • 主体内容:main

  • 标题:h1 ~ h6

  • 段落:p

  • 侧边栏:aside

  • 页脚:footer

这样,整篇HTML结构非常清晰,好看。

HTML语义化有什么好处呢?

  • 网页加载慢导致CSS文件还未加载时(没有CSS),页面仍然清晰、可读、好看。

  • 提升用户体验,例如title、alt可用于解释名词或解释图片信息。

  • 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息。

  • 方便其他设备(如屏幕阅读器、盲人阅读器、移动设备)更好的解析页面。

  • 使代码更具可读性,便于团队开发和维护。

HTML5新特性

  • 更加语义化的元素。 article、footer、header、nav、section

  • 本地化储存。 localStorage 和 sessionStorage

  • 拖曳以及释放的api。 Drag and drop(draggable="true";当拖拽一个项目到 HTML 元素中时,浏览器默认不会有任何响应。想要让一个元素变成可释放区域,该元素必须设置 ondragover和 ondrop 事件。)

  • 媒体播放。 video 和 audio

  • 增强表单控件类型。date、time、number、email、color、search

  • 全双工通信协议。 websocket

  • 跨域资源共享(CORS) Access-Control-Allow-Origin

补充:Web Storage 的概念和 cookie 相似,区别是它是为了更大容量存储设计的。Cookie 的大小是受限的,并且每次你请求一个新的页面的时候 Cookie 都会被发送过去,这样无形中浪费了带宽,另外 cookie 还需要指定作用域,不可以跨域调用。

1.localStorage: 用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。

2.sessionStorage: 用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此 sessionStorage 不是一种持久化的本地存储,仅仅是会话级别的存储。

Web Storage 拥有 setItem,getItem,removeItem,clear 等方法,不像 cookie 需要前端开发者自己封装 setCookie,getCookie(安装依赖js-cookie、Cookies.set()、Cookies.get()、Cookies.remove)

SEO

SEO(Search Engine Optimization),即搜索引擎优化。SEO的存在就是为了提升网站在搜索引擎中的权重,增加对搜索引擎的友好度,使得用户在访问网站时能排在前面。

  • 突出重要内容---合理的设计titledescriptionkeywords

  • 语义化书写HTML代码,符合W3C标准

  • 图片img标签添加alttitle属性

  • 链接<a>页内标签添加title属性

  • 使用h1标签自带权重

input元素的类型

① button ② checkbox ③ file ④ hidden ⑤ image ⑥ password ⑦ radio ⑧ reset ⑨ submit ⑩ Text ⑪ Date

iframe的特点

  • 优点:

  1. iframe能够原封不动的把嵌入的网页展现出来。

  2. 如果有多个网页引用iframe,那么你只需要修改iframe的内容,就可以实现调用的每一个页面内容的更改,方便快捷。

  3. 网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用iframe来嵌套,可以增加代码的可重用。

  4. 如果遇到加载缓慢的第三方内容如图标和广告,这些问题可以由iframe来解决。

  • 缺点:

  1. iframe会阻塞主页面的onload事件;

  2. iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。,会产生很多页面,不容易管理。

  3. iframe框架结构有时会让人感到迷惑,如果框架个数多的话,可能会出现上下、左右滚动条,会分散访问者的注意力,用户体验度差。

  4. 代码复杂,无法被一些搜索引擎索引到,这一点很关键,现在的搜索引擎爬虫还不能很好的处理iframe中的内容,所以使用iframe会不利于搜索引擎优化(SEO)。

  5. 很多的移动设备无法完全显示框架,设备兼容性差。

  6. iframe框架页面会增加服务器的http请求,对于大型网站是不可取的。

CSS

Flex

  • 哪些属性作用在父元素上?

justify-content:space-around space-between space-evently center flex-end

align-items:flex-star flex-end

flex-direction :row row-reverse column column-reverse

flex-wrap :nowrap(如果子孩子,的宽度超过父盒子,会进行总动的伸缩) wrap(不去管)

  • 哪些属性作用在子元素上?

order (项目排列的顺序 越小越靠前)

align-self(单个属性的操作 flex-end center flex-star)

flex-grow(如果剩余有宽度是否进行扩张方法,默认是0,)

flex-shrink (空间不足的时候进行缩小默认是1 进行缩小)

BFC

定义:

块级格式化上下文。BFC是一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局。用于对块级元素排版。默认情况下只有根元素(body)一个块级上下文。

布局规则:

  • 内部的盒子会在垂直方向,一个个地放置;

  • 盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的上下 margin 会发生重叠;

  • 每一个元素的左边,与包含块的左边相接触(对于从右往左的布局,则相反),即使存在浮动也是如此;

  • BFC 的区域不会与 float 重叠;(应用:三栏布局)

  • BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此;

  • 计算 BFC 的高度时,浮动元素也參与计算。(运用:清除浮动)

  • 当一个元素设置了新的 BFC 后,就和这个元素外部的 BFC 没有关系了,这个元素只会去约束自己内部的子元素。(应用:外边距塌陷)

怎么触发BFC:

  • overflow:不为 visible

  • float: 不为 none

  • display: 为 inline-blocktabletable-celltable-captionflexinline-flexgridinline-gridflow-root

  • position: 为 absolute 或者 fixed

重排重绘

页面生成的过程:

1.HTML 被 HTML 解析器解析成 DOM 树;

2.CSS 被 CSS 解析器解析成 CSSOM 树;

3.结合 DOM 树和 CSSOM 树,生成一棵渲染树(Render Tree),这一过程称为 Attachment;

4.生成布局(flow),浏览器在屏幕上“画”出渲染树中的所有节点;

5.将布局绘制(paint)在屏幕上,显示出整个页面。

第四步和第五步是最耗时的部分,这两步合起来,就是我们通常所说的渲染。

  • 重绘:某些元素的外观被改变,例如:元素的填充颜色

  • 重排:重新生成布局,重新排列元素。

单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分。比如改变元素高度,这个元素乃至周边dom都需要重新绘制。

也就是说:重绘不一定导致重排,但重排一定会导致重绘

CSS优先级

!important > style > id > class > 标签 > 通配符 > 默认 > 继承

CSS3新特性

  1. 新增的选择器(各种伪类选择器)

  2. 圆角(border-radius)

  3. 阴影(box-shadow)

  4. 动画(animation)

  5. 过渡(transition)

  6. 翻转(transform)

  7. 渐变

  8. 媒体查询 @media

  9. 弹性盒子(flex)

  10. rgba

清除浮动的方法

为什么要清除浮动?

如果子元素浮动,此时子元素不能撑开标准流的块级父元素。

方法:

1、直接给父元素设置高度

  • 优点:简单、方便

  • 缺点:有很多布局不能固定父元素高度:比如长列表、推荐模块,是无法确定子项内容有多少的

2、额外标签法

  • 实现方式:

    1. 给父元素内容的最后添加一个块级元素

    2. 给添加的块级元素设置clear: both;(可以认为,设置了clear:both的当前元素会把前边元素中设有浮动属性的元素,当做没设浮动一样来看待,以此来消除其对自己的影响)

  • 缺点:

    • 会添加进去额外的标签,让HTML结构变得复杂

3、单伪元素清除法

用伪元素替代额外标签

4、双伪元素清除法

除了可以清除浮动的影响,还可以解决外边距折叠的塌陷现象(原理:里面的"display:table;"触发BFC)

5、为父元素设置overflow: hidden

盒模型的理解

分标准盒模型和怪异盒模型。

标准盒模型采用的W3C标准,盒子的content内容部分由width宽度和height高度决定,添加padding内边距或border外边框后,宽高都会进行相应增长。

怪异盒模型也称为IE盒模型,是IE浏览器设计元素时遵循的规则。怪异盒模型的宽高在div盒子初次设置时就已经规定,添加padding或者border,会从中减少content内容的占据区域,来为padding和border制造空间,宽高不会相对应的进行增长。

盒模型转换用box-sizing:border-box,默认是标准盒模型。

响应式布局

  • bootstrop框架

  • 媒体查询

移动适配方案

  • rem(用flexible方案,flexible.js帮我们计算出1rem 等于多少px)

  • vw和vh

三栏布局

  • flex

  • 定位

  • 浮动

    • 两边浮动中间margin + overflow: hidden(触发BFC)

    • 两边浮动,中间calc()函数

    • 三个部分都浮动(圣杯和双飞翼布局),然后结合margin和定位调整

  • display:table;

  • grid布局

圣杯布局和双飞翼布局

最后我们来总结一下,双飞翼布局其实和圣杯布局的精髓是一样的,都是在三个部分都是浮动的情况下,左右的部分因为父盒子宽度不够被挤下来的问题,通过设置负margin来实现元素的排布。

  • 不同的就是html结构,双飞翼是在middle元素内部又设置了一个milddle-inner并设置它的左右margin,而非圣杯布局的padding,来排除两边元素的覆盖,最后把盒子定位到两侧。

  • 双飞翼布局可以多了一个html结构,但是可以不用设置left,right元素的定位。

JS

JS为何是单线程

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成这门语言的核心特征,将来也不会改变。

注:所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个。

JS数据类型

基本类型分为以下六种:

  • string(字符串)

  • boolean(布尔值)

  • number(数字)

  • symbol(符号)

  • null(空值)

  • undefined(未定义)

  • BigInt(是ES6中新引入的数据类型,它是一种内置对象,它提供了一种方法来表示表示任意大的整数。即使这个数已经超出了JavaScript构造函数 Number 能够表示的安全整数范围。)

引用数据类型:

  • 数组

  • 对象(函数也是对象)

区别:

值类型的变量会保存在 栈内存 中,如果在一个函数中声明一个值类型的变量,那么这个变量当函数执行结束之后会 自动销毁

引用类型的变量名会保存在 栈内存 中,但是变量值会存储在 堆内存 中,引用类型的变量不会自动销毁,当没有引用变量引用它时,系统的 垃圾回收机制 会回收它。

js判断数据类型

判断数据类型方法有很多,实际使用需要根据自己的需求使用最适合自己的方法

1、使用 typeof

测试简单数据类型。对于null及数组、对象,typeof均检测出为object,不能进一步判断它们的类型。

2、使用 obj instanceof Object

测试复杂数据类型,因为instanceof 是用来判断数据是否是某个对象的实例

所以对于 nullundefined 这两个家伙就检测不了

因为原型链继承的关系,instanceof 会把数组都识别为 Object 对象,所有引用类型的祖先都是 Object 对象

3、使用Object.prototype.toString.call

Object.prototype.toString.call() 区分的数据类型适用范围更大,但是无法区分自定义对象类型,区分自定义对象类型使用 instanceof 操作符。

Object.prototype.toString()本身是允许被修改的,而我们目前所讨论的关于Object.prototype.toString()这个方法的应用都是假设toString()方法未被修改为前提的。

因为实例对象有可能会自定义toString()方法,会覆盖Object.prototype.toString(), 所以在使用时,最好加上call()。

4、使用.constructor

constructor不能判断undefined和null,并且使用它是不安全的,因为contructor的指向是可以改变的

js中的length属性

1、length属性常见于字符串和数组,来判断长度。

2、length属性还可以用于函数,来判断函数的长度,即函数中形参的个数。

注意:

  • ...args不计入形参个数

  • 设置了默认值的参数及其之后的所有参数都不计入形参个数,之前的仍旧计入

判断空对象

所谓空对象,就是数组的长度等于0

  1. let obj = {name : '你好'}
  2. //是true为空对象,是false则不是空对象
  3. console.log(JSON.stringify(obj) === '{}');//false
  4. let obj = {}
  5. let fn = (obj) => {
  6.    for(let key in obj) {
  7.        return false
  8.   }
  9.    return true
  10. }
  11. //返回false代表不为空,返回true则为空对象
  12. console.log(fn(obj));//true
  13. let  obj = {name : '1'}
  14. //Object.getOwnPropertyNames()获取到对象中的全部属性名,存到一个数组中
  15. let s = Object.getOwnPropertyNames(obj)
  16. console.log(s); //['name']   //为[],代表空对象
  17. let  obj = {name : '1'}
  18. //Object.keys()获取给定对象的所有可枚举属性的字符串数组
  19. let s = Object.keys(obj)
  20. console.log(s);//[ 'name' ] //若为[],则为空对象
  21. let  obj = {name : '1'}
  22. // 注意for...in 会将对象原型链上的属性也枚举出来,所以要借hasOwnProperty()方法来判断是不是对象本身的属性
  23. // 如果存在返回true,不存在返回false
  24. let fn = (s) => {
  25.    for(let key in s) {
  26.        if(s.hasOwnProperty(key)) {
  27.            return false
  28.       }
  29.        return true
  30.   }
  31. }
  32. console.log(fn(obj));//false   //若是反回true则就是空对象

判断空数组

和判断空对象类似的,我们只要能验证这个对象的keys长度是0,那就是个空对象了。

Array.isArray(arr) & arr.length === 0

ES6新特性

  1. 新的定义变量的方式 let const var 的区别

  2. 模板字符串

  3. class

  4. Promise

  5. async/await

  6. 箭头函数

  7. 新的数组方法 filter some map every forEach reduce Array.from() find findIndex includes flat

  8. 拓展运算符

  9. 赋值解构运算符

  10. Proxy

  11. 对象新增方法 Object.assign() Object.keys()

  12. es6的模块化

  13. Set

  14. Map

ES6 Module 和 CommonJS 的区别

CommonJS 是对模块的浅拷贝;ES6 Module 是对模块的引用,即 ES6。

CommonJS是动态编译,可以放在代码里动态执行;ES6 Module 是静态编译,引用只能放在最前面。

箭头函数和普通函数区别

  1. this指向(普通函数指向调用者,this指向父级作用域的this)

  2. 不可以被当做构造函数

  3. 不可以使用arguments对象,该对象在函数体内不存在,如果要用就用剩余参数替代

  4. 没有prototype属性

new一个对象做了什么事情

  1. new构建函数可以在内存中创建一个空的对象

  2. this会指向刚才创建的空对象

  3. 执行构造函数的代码给这个空对象添加属性和方法

  4. 返回这个对象(所以构造函数不需要return)

构造函数与普通函数的区别

1.构造函数就是一个普通的函数,创建方法和普通函数没有区, 不同的是构造函数习惯上首字母大写。

2.构造函数与普通函数的区别就是调用方式不同,普通函数直接调用,而构造函数使用new关键字调用。

防抖和节流

  • 防抖debounce

    定义:触发高频事件后n秒内函数只会执行最后一次,如果n秒内高频事件再次被触发,则重新计算时间。

    原理:每次触发事件时都取消之前的延时调用方法

    1. function debounce(fn) {
    2.  let timer = null; // 创建一个标记用来存放定时器的返回值
    3.  return function () {
    4.    // 执行这个函数之前先清掉定时器
    5.    clearTimeout(timer);
    6.    timer = setTimeout(() => {
    7.      // 绑定this的原因是为了让this指向正确
    8.      // 绑定arguments的原因是为了正确使用函数参数位置的事件对象e
    9.      fn.apply(this, arguments);
    10.   }, 500);
    11. };
    12. }

    应用场景

    1. 搜索框输入查询,如果用户一直在输入中,没有必要不停地调用去请求服务端接口,等用户停止输入的时候,再调用,设置一个合适的时间间隔,有效减轻服务端压力。

    2. 表单验证

    3. 按钮提交事件。

    4. 浏览器窗口缩放,resize事件(如窗口停止改变大小之后重新计算布局)等

  • 节流throttle

    定义:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率

    原理:每次触发事件时都判断当前是否有等待执行的延时函数

    1. 方法一:
    2. function throttle(func, wait) {
    3.    var prev = 0;
    4.    return function() {
    5.        let now = Date.now();
    6.        if (now - prev > wait) {
    7.            func();
    8.            // 重置起始时间
    9.            prev = now;
    10.       }
    11.   }
    12. }
    13. 方法二:
    14. function throttle(fn) {
    15.  // 闭包保存是否可以开启定时器,默认是开启的
    16.  let canRun = true;
    17.  return function () {
    18.    // 如果没有开启就直接返回
    19.    if (!canRun) return;
    20.    // 开启了就立即关闭定时器入口,然后开启定时器
    21.    canRun = false;
    22.    setTimeout(() => {
    23.      fn.apply(this, arguments);
    24.      // 定时器运行后,下次定时器才可开启
    25.      canRun = true;
    26.   }, 500);
    27. };
    28. }

    应用场景

    1. 按钮点击事件

    2. 拖拽事件

    3. onScoll

    4. 计算鼠标移动的距离(mousemove)

深拷贝浅拷贝