前端面试题小记

260 阅读6分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」。

什么是html语言化?

1、易于用户阅读,样式丢失的时候能让页面呈现清晰的结构。
2、有利于SEO,搜索引擎根据标签来确定上下文和各个关键字的权重。
3、方便其他设备解析,如盲人阅读器根据语义渲染网页
4、有利于开发和维护,语义化更具可读性,代码更好维护,与CSS3关系更和谐

html5提供了哪些api?

  • Media API
  • Text Track API
  • Application Cache API
  • User Interaction
  • Data Transfer API
  • Command API
  • Constraint Validation API
  • History API

html5的的存储有哪些?有什么区别

早些时候我们使用cookie:可设置失效时间,没有设置的话,默认是关闭浏览器后失效
h5:
localStorage:除非被手动清除,否则将会永久保存。
sessionStorage: 仅在当前网页会话下有效,关闭页面或浏览器后就会被清除。
note:localstorage有addeventlistener方法

typeof会返回哪些数据类型?与 instanceof什么区别。

值:1. number 2. string 3. boolean 4. symbol 5. undefined 6. bigint
引用:1. object 2. function
image.png typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

什么是宏任务、微任务?

一般大家会问谁先执行,我这边的理解是从<Script>算起,‘宏’任务先执行然后是派发微任务->然后‘宏’任务->微任务...
至于什么是事件循环机制: 上面这一执行过程就是Event Loop。
我们可以大概看看浏览器是怎么处理的:
浏览器的主线程是事件循环。它是一个无线循环,永远处于接受处理的状态,并等待事件(如布局和绘制事件)发生,并进行处理。下面是firefox中关于主事件循环的代码: `

while (!mExiting)
    NS_ProcessNextEvent(thread);

参考:developer.mozilla.org/zh-CN/docs/…

js异步加载方案有哪些?

1、<script async = "async" src = "./index.js"></script>

2、通过document.createElement('script');手动加载

3、动态 import
import('/modules/my-module.js')
  .then((module) => {
    // Do something with the module.
  });
或者
let module = await import('/modules/my-module.js');

link和@import的区别。

(1)所属范围:link是html标签,@import是css语法
(2)加载顺序:页面加载时,link标签引入的css样式同时被加载,@import引入的css样式等页面加载完毕之后再加载 (3)兼容性:link不存在兼容性问题,@import只支持IE5以上的版本

常见兼容性问题有哪些?

css的默认初始化,别写奇怪代码,移动端尽量使用flex布局,老浏览器就算了吧。
html5新标签的兼容性问题:使用静态资源的html5shiv包。
getAttribute的兼容问题,嗯~用jq
什么属性啊多看看api的浏览器支持情况

说说常见的http状态码。

大区间:
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误
常见:
101 服务器应客户端升级协议的请求(Upgrade (en-US)请求头)正在切换协议。(在使用 WebSockets 时会用到协议切换。)
301 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。 401 当前请求需要用户验证
403 服务器已经理解请求,但是拒绝执行它。如:请求接口路由不存在、跨域等可能会出现此code
404 请求失败,请求所希望得到的资源未被在服务器上发现。
500 内部服务器错误
详细

用js实现数组去重

const a=[1,2,3] 
const b=[4,5,6]
const c=[...new Set([...a,...b])];
note:Set成员值唯一特性。(另:map、key值去重、过滤器等)

怎么理解Promise对象?

首先可以了解下:Promise a+规范翻译版
Promise对象用于表示一个异步操作的最终完成 (或失败)及其结果值。
主要是三重状态:pending、fulfilled、rejected。另外还有settled( settled 状态的定义是非 pending,即 fulfilled 或者 rejected 中的任一状态。)

image.png

使用:new Promise((resolve, reject)

列举js中的强制类型转换和隐式类型转换。

强制转换:通过String(),Number(),Boolean()函数
隐式: 转为布尔!! --- if ([]) ----><===
数字*1 ---- +[]

js实现一个深拷贝。

1let obj2=JSON.parse(JSON.stringify(obj));
//有局限性
2var obj2 = Object.assgin({ }, obj)
//assgin拷贝的是属性值
3、递归(一直认为这种玩意就该用框架)
说说简单思路:声明一个变量,判断obj是否是基本类型,是就直接赋值。不是就判断不同的类型,如果是obj然后循环赋值。多层的情况下就递归,别忘了return

JSON字符串转换。

JSON.parse()、JSON.stringify

内存泄漏的情况

垃圾回收机制无法回收就是内存泄漏 主要有:全局变量、闭包变量、console等不会被垃圾回收

什么是闭包?

概练:闭包让开发者可以从内部函数访问外部函数的作用域
表现形式:函数里面套函数

什么是作用域和作用域链

Scope(作用域):作用域是当前的执行上下文,和表达式在其中“可见”或可被访问。 JavaScript的作用域分为下面几种:

  • 全局作用域:脚本模式运行所有代码的默认作用域
  • 模块作用域:模块模式中运行代码的作用域
  • 函数作用域:由函数创建的作用域

此外,用 let 或 const 声明的变量属于额外的作用域:

  • 块级作用域:用一对花括号(一个代码块)创建出来的作用域。
let x = 1;
{
  let x = 2;
}
console.log(x); // 输出 1

作用域链:因为作用域内会由内而外查找变量(就近原则),这一过程称为作用域链。

原型链与继承

prototype-原型 (函数特有)
[[Prototype]]/__proto__的查找关系叫 - 原型链
相关链接:

说一说事件冒泡和事件捕获。

事件流的模型是自上而下捕获,到达目标,然后再自下而上冒泡。 dom0-2默认是事件冒泡,dom2级使用btn.addEventListener(click,fn,false) false->true为事件捕获。

get和post的区别

默认情况下get请求参数放在query,post请求参数放在body,http协议本身没有要求。
接口使用规范我们可以参考restful接口规范。
因为get请求一般是放在url的query中,而url的长度有上线(避免url过长导致服务器爆内存),因此一般说get参数长度有上线。
安全方面本质没有区别,只是get/query是在地址栏可见所以会有相关安全问题。

防抖与节流

防抖:在用户事件在触发n秒后再执行回调逻辑,如果在这n秒内事件又被触发,则重新计时 节流:当遇到连续用户事件时,以n秒为间隔进行阻断

如何一次性渲染10w条数据

1、通过分页加上定时器实现。
2、window.requestAnimationFrame()替代settimeout减少重排。
3、使用document.createDocumentFragment()/英 /ˈfræɡmənt/ /文档碎片,最后一次性插入数据。

vue中虚拟dom是什么?用来做什么?

虚拟DOM的本质:就是使用JS对象来模拟DOM树,将直接操作dom变为js对象的比较提高效率。 虚拟DOM大致结构如下,简称 vnode。

例: let obj={
         target:'ul', //目标
         attrs:{"id":"app"},  //属性
         children:[] //子集
         }

Vue2 data()为什么是一个函数?

使用了闭包的特性保护数据的私密性、延长变量的生命周期。

Vue2父子组件生命周期加载时的执行顺序

父beforeCreate -----> 父created -----> 父beforeMount ----> 子beforeC...子beforeMount ----> 子mounted ----> 父mounted 规律就是:父组件肯定要等子组件加载完它才能完,所以开始阶段肯定是父组件先加载先开始执行,然后等到子组件执行完,父组件收尾。

this.$nextTick()的原理?作用是什么?

原理:本质是对 JavaScript 执行原理EventLoop的一种应用,来实现 Vue 框架中自己的异步回调队列。
监听nextTick作用就是用来等下次DOM渲染完才去调用nextTick内的DOM操作代码。

vue和react的区别。

首先官方回答链接
React:
1.单向数据流
2.手动setState Vue:
1.v-model 可以实现双向数据流,但只是v-bind:value 和 v-on:input的语法糖;
2.通过 this 改变值,会触发 Object.defineProperty的 set(vue3 proxy),然后更新DOM;

vue中对象更改检测的注意事项。

Vue已经创建的实例后添加的数据是不可响应式的。但是,可以使用 Vue.set(object, key, value)方法向嵌套对象添加响应式属性

vue优化加载速度。

1、路由懒加载(路由通过require加载)
2、vue key的合理定义
3、合理局部组件和全局组件
4、ssr
5、按需引入组件
6、computed 和 watch 不同场景的合理使用

讲讲mixin

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

// 定义一个混入对象  
var myMixin = {  
created: function () {  
this.hello()  
},  
methods: {  
hello: function () {  
console.log('hello from mixin!')  
}  
}  
}  
  
// 定义一个使用混入对象的组件  
var Component = Vue.extend({  
mixins: [myMixin]  
})  
  
var component = new Component() // => "hello from mixin!"

缺点:可能有data和命名方法的冲突问题,导致项目难以维护。

Vue2/vue3生命周期。

image.png

未标题-3.jpg

讲一下你对vue2和vue3的了解。

  1. 首先vue和vue3脚手架方面区别,vue2我们使用较多的是vuecli+webpack+vuex目前vue3我们是使用的vite+pinia+ts。
  2. vue2.0中是直接创建了一个vue实例,vue3.0中按需导出了一个createApp。
  3. vue3中剔除了过滤器filter功能。
  4. vue3使用Proxy代替defineProperty重写虚拟DOM实现和Tree-shaking。(Vue2使⽤的是Object.defineProperty()进⾏数据劫持,结合发布订阅的⽅式实现。Vue3使⽤的是Proxy代理,使⽤ref或者reactive将数据转化为响应式数据。 )
  5. Vue3新特性,引入了Composition API。
  6. 获取props区别:vue2:console.log(‘props’,this.xxx)。vue3:setup(props,context){ console.log(‘props’,props) }或者setup语法糖。
  7. 父组件传值emit:vue2:this.$emit(),vue3:setup(props,context){context.emit()}或者setup语法糖。
  8. vue3提供了组合式API-Provide / Inject用于多级组件的通信。
  9. 更好的支持typescript。

讲讲pinia和vuex的区别

  1. pinia持久化存储更方便。
  2. 提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。
  3. pinia没有Mutation、Module。

pinia官方介绍 image.png vuex官方介绍

结尾

整理的一些面试问题,不断更新。