前端面试题二(初中级)二线城市offer给他拿下

47 篇文章 1 订阅
本文介绍了前端面试中常见的问题,涵盖了JavaScript的let、const与var的区别,数组的多种遍历方法,Vue框架的优点与特点,虚拟DOM的概念及其作用,以及Vue组件间的通信方式。此外,还讲解了Vue的内置指令,如v-show与v-if的差异,以及CSS在组件中作用域的控制。文章最后讨论了SPA的优缺点,Vue的首屏渲染优化,以及Vue生命周期中的数据请求时机等知识点。
摘要由CSDN通过智能技术生成

1.let,const,var 有什么区别

(1)块级作用域: 块作用域由 { }包括,let 和 const 具有块级作用域,var 不存在块级作用域。块级作用域解决了 ES5 中的两个问题:
内层变量可能覆盖外层变量
用来计数的循环变量泄露为全局变量
(2)变量提升: var 存在变量提升,let 和 const 不存在变量提升,即在变量只能在声明之后使用,否在会报错。
(3)给全局添加属性: 浏览器的全局对象是 window,Node 的全局对象是 global。var 声明的变量为全局变量,并且会将该变量添加为全局对象的属性,但是 let 和 const 不会。
(4)重复声明: var 声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的遍历。const 和 let 不允许重复声明变量。
(5)暂时性死区: 在使用 let、const 命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区。使用 var 声明的变量不存在暂时性死区。
(6)初始值设置: 在变量声明时,var 和 let 可以不用设置初始值。而 const 声明变量必须设置初始值。
(7)指针指向: let 和 const 都是 ES6 新增的用于创建变量的语法。 let 创建的变量是可以更改指针指向(可以重新赋值)。但 const 声明的变量是不允许改变指针的指向。

区别

var

let

const

是否有块级作用域

×

是否存在变量提升

×

×

是否添加全局属性

×

×

能否重复声明变量

×

×

是否存在暂时性死区

×

是否必须设置初始值

×

×

能否改变指针指向

×

2.遍历数组你知道几种方法

1.map
map()返回一个新的数组,数组中的元素为原始数组调用函数处理后的值。
map()不会对空数组进行检测。
map()不会改变原始数组。
传递给 map() 方法的回调函数接受 3 个参数:currentValue,index 和 array。
currentValue:必须。当前元素的的值。
index:可选。当前元素的索引。
arr:可选。当前元素属于的数组对象。

2.filter
filter()方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
filter()不会对空数组进行检测。
filter()不会改变原始数组。
传递给 filter() 方法的回调函数接受 3 个参数:currentValue,index 和 array。
currentValue:必须。当前元素的的值。
index:可选。当前元素的索引。
arr:可选。当前元素属于的数组对象。

3.forEach
forEach()方法类似于 map(),传入的函数不需要返回值,并将元素传递给回调函数。
forEach() 对于空数组是不会执行回调函数的。
forEach()不会返回新的数组,总是返回undefined.
传递给 forEach() 方法的回调函数接受 3 个参数:currentValue,index 和 array。
currentValue:必须。当前元素的的值。
index:可选。当前元素的索引。
arr:可选。当前元素属于的数组对象。

4.sort
sort()方法用于对数组的元素进行排序。
sort()会修改原数组。
sort() 方法接受一个可选参数,用来规定排序顺序,必须是函数。
如果没有传递参数, sort() 方法默认把所有元素先转换为 String 再排序 ,根据 ASCII 码进行排序。
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
若 a 等于 b,则返回 0。
若 a 大于 b,则返回一个大于 0 的值。

5.some
some() 方法用于检测数组中的元素是否满足指定条件。
some() 方法会依次执行数组的每个元素。
如果有一个元素满足条件,则表达式返回 true, 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回 false 。
some()不会对空数组进行检测。
some()不会改变原始数组。
传递给 some() 方法的回调函数接受 3 个参数:currentValue,index 和 array。
currentValue:必须。当前元素的的值。
index:可选。当前元素的索引。
arr:可选。当前元素属于的数组对象。

6.every
every() 方法用于检测数组所有元素是否都符合指定条件。
every() 方法会依次执行数组的每个元素。
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true。
every()不会对空数组进行检测。
every()不会改变原始数组。
传递给 every() 方法的回调函数接受 3 个参数:currentValue,index 和 array。
currentValue:必须。当前元素的的值。
index:可选。当前元素的索引。
arr:可选。当前元素属于的数组对象。

7.reduce
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce()对于空数组是不会执行回调函数的。
reduce 方法接收两个参数
回调函数
一个可选的 initialValue (初始值)。如果不传第二个参数 initialValue,则函数的第一次执行会将数组中的第一个元素作为 prev 参数返回。
传递给 reduce() 方法的回调函数接受 4 个参数:prev, current, currentIndex, arr。
prev:必须。函数传进来的初始值或上一次回调的返回值。
current:必须。数组中当前处理的元素值。
currentIndex:可选。当前元素索引。
arr:可选。当前元素所属的数组本身。

8.reduceRight
reduceRight() 方法的功能和 reduce() 功能是一样的,不同的是 reduceRight() 从数组的末尾向前将数组中的数组项做累加。

9.find
find()方法用于查找符合条件的第一个元素,如果找到了,返回这个元素,否则,返回undefined。
find()不会对空数组进行检测。
find()不会改变原始数组。
传递给 find() 方法的回调函数接受 3 个参数:currentValue,index 和 array。
currentValue:必须。当前元素的的值。
index:可选。当前元素的索引。
arr:可选。当前元素属于的数组对象。

10.findIndex
findindex() 和 find() 类似,也是查找符合条件的第一个元素,不同之处在于 findindex() 会返回这个元素的索引,如果没有找到,返回 -1 。

3.说一下 vue 有哪些优点和特点

渐进式框架:可以在任何项目中轻易的引入;
轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十 kb ;
简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
双向数据绑定:在数据操作方面更为简单;
组件化:很大程度上实现了逻辑的封装和重用,在构建单页面应用方面有着独特的优势;
视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;

4.什么是虚拟 dom

Virtual DOM 是 DOM 节点在 JavaScript 中的一种抽象数据结构,之所以需要虚拟 DOM,是因为浏览器中操作 DOM 的代价比较昂贵,频繁操作 DOM 会产生性能问题。
虚拟 DOM 的作用是在每一次响应式数据发生变化引起页面重渲染时,Vue 对比更新前后的虚拟 DOM,匹配找出尽可能少的需要更新的真实 DOM,从而达到提升性能的目的。
虚拟 DOM 的实现原理主要包括以下 3 部分:
用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
diff 算法 — 比较两棵虚拟 DOM 树的差异;
pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树

5.vue 组件间传值的 n 种方式

(1)props / $emit适用 父子组件通信
(2)ref 适用 父子组件通信
ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
(3)$parent / $children / $root:访问父 / 子实例 / 根实例
(4)EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信
这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件。
(5)$attrs/$listeners适用于 隔代组件通信 $attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 ( class 和 style 除外 )。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外 ),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用。
$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件
(6)provide / inject 适用于 隔代组件通信
祖先组件中通过 provide 来提供变量,然后在子孙组件中通过 inject 来注入变量。provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
(7)Vuex 适用于 父子、隔代、兄弟组件通信
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。store 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。
(8)插槽
Vue3 可以通过 usesolt 获取插槽数据。
(9)mitt.js 适用于任意组件通信
Vue3 中移除了 $on,$off等方法,所以 EventBus 不再使用,相应的替换方案就是 mitt.js

6.vue 有哪些内置指令

在这里插入图片描述

7.v-show 和 v-if 有什么区别

手段:v-if 是动态的向 DOM 树内添加或者删除 DOM 元素;v-show 是通过设置 DOM 元素的 display 样式属性控制显隐;
编译过程:v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show 只是简单的基于 css 切换;
编译条件:v-if 是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译; v-show 是在任何条件下,无论首次条件是否为真,都被编译,然后被缓存,而且 DOM 元素保留;
性能消耗:v-if 有更高的切换消耗;v-show 有更高的初始渲染消耗;
使用场景:v-if 适合运营条件不大可能改变;v-show 适合频繁切换

8.如何让 CSS 只在当前组件中起作用

在组件中的 style 标签中加上 scoped

9.如何解决 vue 初始化页面闪动问题

在 css 里加上 [v-cloak] { display: none; } 。
如果没有彻底解决问题,则在根元素加上 style=“display: none;” :style="{display: block }"

10.什么是 SPA,有什么优点和缺点

SPA 仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。
优点:
用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
有利于前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;
缺点:
初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
不利于 SEO:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。

11.vue 首屏渲染优化有哪些

图片压缩/懒加载
禁止生成 .map 文件
路由懒加载
cdn 引入公共库
开启 GZIP 压缩

12.第一次页面加载会触发哪几个钩子

beforeCreate,created,beforeMount,mounted

13.在哪个生命周期中发起数据请求

可以在钩子函数 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。
推荐在 created 钩子函数中调用异步请求,有以下优点:
能更快获取到服务端数据,减少页面 loading 时间;
ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性

14.vue-router 有几种模式

vue-router 有 3 种路由模式:hash、history、abstract:
hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器;
history : 依赖 HTML5 History API 和服务器配置。
abstract : 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式

15.hash 和 history 有什么区别

(1)hash 模式的实现原理
早期的前端路由的实现就是基于 location.hash 来实现的。其实现原理很简单,location.hash 的值就是 URL 中 # 后面的内容。比如下面这个网站,它的 location.hash 的值为 #search
hash 路由模式的实现主要是基于下面几个特性:
URL 中 hash 值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash 部分不会被发送;
hash 值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制 hash 的切换;
可以通过 a 标签,并设置 href 属性,当用户点击这个标签后,URL 的 hash 值会发生改变;或者使用 JavaScript 来对 loaction.hash 进行赋值,改变 URL 的 hash 值;
我们可以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)。

(2)history 模式的实现原理
HTML5 提供了 History API 来实现 URL 的变化。其中做最主要的 API 有以下两个:history.pushState() 和 history.repalceState()。这两个 API 可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录
window.history.pushState(null, null, path);
window.history.replaceState(null, null, path);
history 路由模式的实现主要基于存在下面几个特性:
pushState 和 repalceState 两个 API 来操作实现 URL 的变化 ;
我们可以使用 popstate 事件来监听 url 的变化,从而对页面进行跳转(渲染);
history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面跳转(渲染)。

16.vuex 有哪些属性

State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。

17.git 常用命令了解哪些

初始化仓库

初始化仓库
git init
初始化裸仓库
git init --bare
克隆仓库
git clone <git-repo>

配置

编辑配置文件
git config [–global] -e
列出配置信息
git config -l
获取相应的配置
git config --get core.editor
配置用户邮箱
git config --global user.email
配置用户名
git config --global user.name
输出彩色信息
git config color.ui true
设置文件名大小写敏感
git config core.ignoreCase false
设置推送策略为 simple
git config push.default simple
设置 git 的编辑器是 vim
git config --global core.editor vim
设置命令别名
git config --global alias.co checkout

忽略文件

添加本项目的忽略文件
vim .gitignore
添加本项目的忽略文件并不把此文件纳入版本管理
vim .git/info/exclude
设置全局忽略文件
git config --global core.excludesfile ~/.gitignore
对已加入版本管理的文件不做更改检查
git update-index --assume-unchanged <file>
对已加入版本管理的文件做更改检查
git update-index --no-assume-unchanged <file>

添加删除移动文件

添加所有文件到暂存区,包括未追踪文件
git add -A
更新暂存区文件
git add -u
交互式添加文件到暂存区
git add -p
工作区与暂存区删除文件
git rm <file>
仅暂存区删除文件
git rm --cached <file>
重命名暂存区文件
git mv <file> <file1>

工作区状态

查看工作区的信息
git status
查看工作区信息并显示分支及追踪信息
git status -sb
并查看忽略文件的信息
git status --ignored
列出忽略文件
git check-ignore *

显示更改

显示工作区与暂存区的不同
git diff
显示暂存区与本地仓库的不同
git diff --cached
显示工作区,暂存区与本地仓库的不同
git diff HEAD
仅显示改变的文件
git diff --name-only
比较两次提交的差异
git diff <commit> <commit>
显示某次 commit 所做的更改
git show <commit>

列出文件信息

列出暂存区文件
git ls-files
列出忽略文件与未追踪文件
git ls-files -o
子目录中显示所在位置
git ls-files --full-name

储藏与恢复

储藏(stash)工作区相对暂存区更改的文件
git stash
储藏文件并添加描述信息
git stash save <message>
恢复最后一次储藏的文件
git stash apply
恢复最后一次储藏的文件并删除此次储存记录
git stash pop
查看储藏列表
git stash list

恢复工作区

重置工作区某文件
git checkout – <file>
重置工作区
git checkout .
列出将要清除的未追踪文件
git clean -n
清除未追踪文件
git clean -f
清除忽略文件
git clean -Xf
清除未追踪目录及文件
git clean -df

回退版本

重置暂存区
git reset
重置工作区和暂存区
git reset --hard
恢复本分支到某次提交,重置工作区与暂存区
git reset --hard <commit-ish>
恢复本分支到某次提交
git reset --soft <commit-ish>
恢复本分支到某次提交,重置暂存区
git reset --mixed <commit-ish>
反向恢复一个提交并生成新的提交
git revert <commit>

分支

列出本地分支
git branch
列出本地分支与追踪关系
git branch -vv
列出远程分支
git branch -r
列出所有分支
git branch -a
建立分支不切换工作区
git branch <branch>
删除已被合并的分支
git branch -d <branch>
强制删除未被合并的分支
git branch -D <branch>
更改分支名字
git branch -m <newbranch>
设置追踪分支
git branch -u <upstream>

切换分支

切换分支
git checkout <branch>
建立分支并切换工作区
git checkout -b <branch>
切换到最近一次分支
git checkout -
建立无任何提交历史的分支
git checkout --orphan <branch>

合并分支

合并 develop 分支到本分支
git merge develop
强制合并分支后生成 merge commit
git merge -no-ff develop
合并最近切换分支
git merge -
变基合并 develop 分支
git rebase develop
变基进入交互式界面
git rebase -i

远程仓库

添加远程仓库并命名为 origin
git remote add origin <git-repo>
修改远程仓库的地址
git remote set-url origin <git-repo>
列出所有的远程仓库
git remote -v
列出远程仓库 origin 的详细信息
git remote show origin

推送与拉取

git config push.default simple
设置默认推送策略为 simple
推送 master 到远程仓库
git push origin master
推送到远程仓库并建立追踪关系
git push -u origin master
推送时忽略 pre-push hook
git push -n
从远程仓库拉取文件
git pull origin master
设置 rebase 模式拉取代码
git pull --rebase origin master

提交

提交
git commit -m <message>
追加提交重置提交信息
git commit --amend -m <message>
重置作者
git commit --amend --author=<mail>
允许空提交
git commit --allow-empty
提交时跳过 pre-commit hook
git commit -n

日志

显示提交日志
git log
显示某文件的提交日志
git log -p <file>
以图表形式显示提交日志
git log --graph --all --oneline --decorate
显示每次提交的对象信息
git log --pretty=raw
显示某个时间段的提交信息
git log --since ‘2 days ago’
显示指定作者的提交信息
git log --author=<author>
根据提交信息中的关键字查找
git log --grep=<keyword>
根据提交源码中的关键字查找
git log -S
列出二者特有的提交
git log master…develop
列出 branch 有而 branch2 没有的提交
git log branch2…branch
仅显示 merge commit
git log --merges
统计每个作者的提交情况
git shortlog
统计每个作者的提交个数
git shortlog -sn

标签

列出所有标签并显示标签信息
git tag -ln
添加一个标签
git tag -a v1.0.0 -m <message>
在某个 commit 上添加一个标签
git tag v0.9.0 <commit>
删除一个标签
git tag -d v1.0.0
查看某个标签信息
git show v1.0.0
推送所有标签到远程仓库
git push --tags
使用最近的标签描述本次提交
git describe

追责(甩锅)

找到最后一次提交的作者
git blame <file>
找到具体某一段的最后一次提交
git blame -L 10,18 <file>
查找文件的修改历史及明细
git log -p <file>

确认坏的提交

二分查找坏的提交
git bisect start <br> git checkout HEAD~20 <br> git bisect good <br> git bisect bad <br> git bisect reset

git 对象

获取改摘要信息的类型
git cat-file -t <hash>
获取改摘要信息的内容
git cat-file -p <hash>

查找

在已追踪文件中查找关键字并指明行号
git grep -n hello

打包

打包
git archive -o arch.zip HEAD

18.如何做权限认证

token 做权限认证

19.如何做 mock 数据

使用 mock.js

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值