【H2O2|全栈】阶段常见面试题(二)【万字大长篇】
目录
前言
开篇语
准备工作
JS相关
规范
数据类型
大类
字符串
数组
变量和作用域
DOM
DOM元素
DOM事件
AJAX
存储方式
BOM
BOM元素
JQuery
HTTP
ES6
CSS相关
基础样式
布局
CSS3
HTML相关
HTML5
Echarts
性能优化
结束语
前言
开篇语
目前,JS的基础部分内容已经全部学完,进阶部分的jQuery和Ajax也已经学完,这里总结了一些阶段的重点面试题,供诸位参考。
注意,本次汇总的内容更加广泛,且按照新的标题进行分类,部分内容可能与上一期重复,就当复习哈。
本文中的Q和A分别对应问题和答案,Tips是对于答案的部分释义。
准备工作
软件:【参考版本】Visual Studio Code
插件(扩展包):Open in browser, Live Preview, Live Server, Tencent Cloud AI Code Assistant, htmltagwrap
提示:在不熟练的阶段建议关闭AI助手
第三方JS库:jquery.min.js
提示:请站内搜索下载、引入方式
浏览器版本:Chrome
系统版本: Win10/11/其他非Windows版本
JS相关
规范
Q:JavaScript的基本规范有哪些?
A:常见规范如下——
- 同一行不要声明多个变量;
- 使用 === 和 !== 来比较true和false的值;
- 使用字面量代替构造函数创建变量;
- 不要使用全局函数;
- switch语句最后应当有default语句;
- 函数不应该有时有返回值,有时没有返回值;
- for循环和if语句必须使用大括号;
-
for-in循环中的变量,应该使用var关键字明确限定作用域,从而避免作用域污染。
数据类型
大类
Q:JS的基础数据类型有哪些?引用数据类型有哪些?
Tips:注意,引用数据类型我们在之前也叫做“复杂数据类型”,这里说的更准确一点。
A:基础数据类型:Number、String、Boolean、Null、undefined。
引用数据类型:Object、function、Array、Date、RegExp。
Q:NaN、null 与 undefined的区别是什么?
A:NaN为非数字类型,是一种特殊的number类型,null是一种特殊的空对象Object,undefined是未定义的值和定义未赋值。
Q:JS如何判断数据类型?
A:typeof运算符可以用于判断数据类型。
此外,instanceof运算符可以判断引用数据类型是否为某一特定类型,比如——
arr instanceof Array
还可以用is加类型的方法判断是否为某一数据类型,比如——
arr.isArray()
Tips:is加类型的方法常用的也就是isArray()。
Q:=,==,===的区别是什么?
A:= 表示赋值,==和===均用于判断。
不同的是,==只需值相同即可判断相等,类型不同也可;
===表示值和类型都得严格相同才可以判断相等。
Q:请例举3种强制类型转换和2种隐式类型转换?
A:例举三种强制类型转换—— parseInt(),parseFloat(),Number()
例举两种隐式转换—— == ,===
字符串
Q:JS如何让数据转为字符串类型?
A:常规的方法有下面三种(以变量a为例)——
- a.toString() (方法转换)
- String(a) (构造函数转换)
- a + "" (拼接空字符串)
Q:如何去除字符串中的空格?
A:对于一个字符串str,有两种方式去除其中的空格——replace正则匹配和trim()方法。
Tips:使用replace正则匹配,可以这么做——
str.replace(/\s+/gi, "")
其中\s代表空白字符,+表示匹配一个或多个,gi表示全局匹配,"" 表示正则匹配到的字段替换为空字符串。
原生JS使用trim()方法可以去除首尾空格——
str.trim()
该方法返回一个新字符串,不能移除字符串中间部分的空格。
$ 也提供了封装的trim()去除首尾空格——
$.trim(str)
注意:$.trim()会移除字符串开始和末尾处的所有换行符,空格(包括连续的空格)和制表符,最后也返回一个新字符串。
$.trim()依然不能移除字符串中间部分的空格。
Q:请用js去除字符串空格?
A:str.trim() ,$.trim(str),replace使用正则匹配空格
数组
Q:如何将两个数组拼接起来?
A:使用数组的concat()方法。
Tips:比如,拼接arr1和arr2,可以这么做——
arr1.concat(arr2)
Q:数组增删元素的方法有哪些?
A:相关的方法有下面四种——
-
pop() 删除并返回数组的最后一个元素
-
shift() 删除并返回数组的第一个元素
-
push() 向数组的末尾添加一个或更多元素,并返回新的长度
-
unshift() 向数组的开头添加一个或更多元素,并返回新的长度
Q:数组的splice()方法有哪些参数?
A:splice()方法的形参列表如下——
splice(index, howmany, item1, ....., itemX)
index为必需参数,且为整数,用于规定添加/删除项目的起始位置,使用负数可从数组结尾处规定位置;
howmany为必需参数,且为整数,用于指定要删除的项目数量,如果设置为 0,则不会删除项目;
item1, ..., itemX为非必需参数。可以设置向数组删除位置添加的新项目。
Tips:注意,splice()可以直接修改原数组。
Q:数组转化字符串join(),toString(),toLocaleString()有什么区别?
A:join() 可以传递一个参数作为分隔符来连接每个元素输出显示;
toString()用于将数组每个元素转换为字符串,然后以逗号为分隔符连接输出显示;
toLocaleString()可以把用户所在地区特定的分隔符把生成的字符串连接起来,形成一个字符串。
Tips:toLocaleString()是一个比较少见的方法,可以指定地区(语言选项)以及附加选项。
它的参数列表如下——
toLocaleString(locale, options)
一般来说,这个方法是针对数组中的元素使用的。如果数组调用该方法,则需要为数组中的所有数据类型都指定附加选项中的属性。
无参数时,数字自动转千分位形式显示。
locale可以指定语言的类型,比如'zh'(中文),'en'(英语)等。
options为附加选项,需要传入一个对象,该对象有下面这些常见属性(此处主要列举对number类型的数据处理)——
属性 | 作用 | 值示例 |
---|---|---|
style | 指定格式化时使用的样式 | percent 转为百分数 currency 货币数字 unit 带度量单位数字 |
currency | 指定输出货币单位 | cny 人民币 |
currencyDisplay | 货币格式展示形式(设置currency之后使用) | code 输出示例:CNY 1,000 name 输出示例:1,000 人民币 |
numberingSystem | 指定数字编号系统 | hanidec 转为汉字输出(千分位显示) |
unit | 指定度量单位 | acre 亩 minute 分钟 |
minimumIntegerDigits | 保留整数位数(开头补0) | 6 整数部分补全为6位 |
minimumFractionDigits | 保留小数位数(末尾补0) | 6 保留6位小数 |
minimumSignificantDigits | 保留总位数(末尾补0) | 10 多的位数在小数后面补 |
maximumFractionDigits | 截去超出位数小数(四舍五入) | \ |
maximumSignificantDigits | 截去超出位数数字(整数+小数,截去小数,四舍五入) | \ |
更加详细的toLocaleString()的使用方法可以自行站内搜索,这里不扩展了。
Q:数组去重有哪些方法?
A:方法一(新数组利用indexOf拿取值)——
function unique(array) {var res = [];for (var i = 0, len = array.length; i < len; i++) {var current = array[i];if (res.indexOf(current) === -1) {res.push(current)}}
return res;}
方法二(数组filter方法)——
function unique(array) {var res = array.filter(function(item, index, array){return array.indexOf(item) === index;})return res;
}
方法三(ES6 利用Set集合去重)——
var unique = (a) => [...new Set(a)]
Tips:Set集合的构造函数会自动把数组中的重复值去掉(值不重复),...为扩展运算符,用于把集合中的数据从语法层面展开,在数组中则按照数组元素形式展开。
Q:JS常见的数组排序方式有哪些?
A:冒泡排序、插入排序、快速排序等。
Q:请实现对数组ary的冒泡排序,封装成函数形式。
A:示例代码如下——
function sortBubble(ary) {let temp = nullfor (let i = 0; i < ary.length; i++) {for (let j = 0; j < ary.length - 1 - i; j++) {if (ary[j] > ary[j + 1]) {temp = ary[j]ary[j] = ary[j + 1]ary[j + 1] = temp}}}return ary
}
Q:如何实现多维数组扁平化,请给出代码。
A:示例代码如下——
let arry2 = ary2.toString().split(',').map(item => parseFloat(item))
变量和作用域
Q:变量的作用域有哪些?
A: es6之前,有全局作用域和局部(函数)作用域。
es6之后添加块级作用域。
Tips:全局作用域是声明在函数外的,局部作用域是声明在函数内的,es6之后,const和let可以将变量的作用域限制在代码块 {} 中。
Q:请讲述a++和++a的区别。
A:主要有三方面的区别——(1)计算结果不同;(2)计算过程不同;(3)内存运行不同。
Tips:a++是先参与计算,然后自身值+1,而++a是先自身值+1,然后参与计算。
Q:如何判断一个数是否为整数?
A:使用对1求余,根据结果是否为0来判定是否为整数。
DOM
DOM元素
Q:如何查找DOM节点?
A: 查找DOM节点有五种原生的方式——
document.getElementById()
document.getElementsByTagName()
document.getElementsByClassName()
document.querySelector()
document.querySelectorAll()
Q:如何添加、移除、替换、插入DOM元素?
A:这里涉及到四种DOM元素的修改方法,由父元素调用——
方法 | 作用 |
---|---|
appendChild() | 子元素列表末尾添加 |
removeChild() | 子元素列表中移除 |
replaceChild() | 子元素列表中替换指定元素为另一元素 |
insertBefore() | 指定子元素之前添加 |
Q:浏览器弹出窗口有哪三种?
A:有下面这三种——
弹窗名 | 类型 | 框内按钮 |
---|---|---|
alert | 警告框 | 确定(返回true) |
prompt | 提问框 | 输入框(返回输入值) |
confirm | 确认框 | 确定(返回true)取消(返回false) |
Q:请讲述offsetWidth、offsetHeight与clientWidth、clientHeight的区别。
A:offsetWidth和offsetHeight包含元素的边框,即content(内容)+padding+border;
clientWidth和clientHeight不包含元素的边框,即content+padding。
Q:src和href的区别是什么?
A:src用于获取外部资源嵌入替换当前元素;href用于在当前文档和引用资源之间确立联系。
Tips:src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在的位置;href是Hypertext Reference 的缩写,指向网络资源所在的位置,建立和当前元素(锚点)或当前文档之间的链接。
Q:如何获取浏览器地址中的hash值?
A:示例代码如下——
var hash = window.location.hash.substr(1)
Tips:hash属性通常用于获取url中#以及后面的值,substr(1)的作用就是截取#之后的值。
DOM事件
Q:事件绑定和普通事件有什么区别?
A:事件绑定中的addEventListener是DOM 2级事件,可以添加多个事件侦听器而不用担心覆盖;
而普通事件(如onclick)的级别为DOM 0级,仅支持添加单个事件,会被其他DOM0级事件覆盖。
Q:如何阻止事件冒泡?
A:阻止事件冒泡的方式因浏览器的不同而有所区别。
对于IE浏览器,阻止方式为:
e.cancelBubble = true
对于非IE浏览器,阻止方式为:
e.stopPropagation()
其中e代表事件对象,下同。
Q:什么是事件委托?
A:利用事件冒泡的原理,将事件绑定在父容器,让父容器代为触发子元素的事件。
Tips:addEventListener中可以添加事件委托,on-事件绑定中则不可以。
Q:如何阻止默认事件?
A:有两种方式,一种是在事件处理函数中直接return false(传统方式),一种是调用事件对象的方法——
e.preventDefault()
Q:如何改变this指针的指向?
A:call()和apply()改变this的指向并且执行调用函数,bind()改变this的指向并返回函数。
AJAX
Q:请概括地解释AJAX的工作原理。
A:一般来说,AJAX主要有下面的几个步骤——
-
创建ajax对象(XMLHttpRequest/ActiveXObject(Microsoft.XMLHttp))
-
判断数据传输方式(GET/POST)
-
打开链接 open()
-
发送 send()
-
当ajax对象完成第四步(onreadystatechange检测readyState的值为4)时数据接收完成,判断http响应状态(status)在200-300之间或者304(缓存)时执行回调函数
Q:AJAX请求时,GET和POST方式有什么区别?
A:一般来说,有下面几个区别——
- get的数据在url后面,post的数据在虚拟载体中
- get只能提交少量参数,容量较小
- post的安全性更高
- get常常用于请求数据,post常常用于提交数据
Q:说出AJAX的缺点?
A:主要有五方面的缺点——
- 不支持浏览器back按钮
- AJAX暴露了与浏览器交互的细节,带来安全问题
- 对搜索引擎的支持较弱
- 破坏了程序的异常机制
- 不容易调试
存储方式
Q:sessionStorage、localStorage和Cookie有什么区别?
A:三种存储方式的特点和区别为——
-
localStorage: 用于长期、持久的客户端数据存储,适合需要跨页面访问并长期保存的数据。
-
sessionStorage: 用于单次会话的数据存储,数据只在会话期间有效。
-
Cookie: 用于服务器和客户端之间的数据交换,通常用于会话管理、身份验证等场景,具有小容量和广泛的作用范围。
BOM
BOM元素
Q:BOM对象有哪些,试例举window的对象。
A:例举:
- window对象,是JS的顶级对象,其他BOM对象都是window对象的属性;
- document对象,文档对象;
- location对象,浏览器当前的URL信息;
- navigator对象,浏览器本身信息;
- screen对象,客户端的屏幕信息;
- history对象,浏览器访问历史信息。
JQuery
Q:jQuery 中$(this) 和 this 关键词有何不同?
A:$(this) 返回一个 jQuery 对象,你可以对它调用多个 jQuery 方法,比如用 text() 获取文本,用val() 获取值等等。
this 代表当前元素,它是 JavaScript 关键词中的一个,表示上下文中的当前 DOM 元素。你不能对它调用 jQuery 方法,直到它被 $() 函数包裹,例如 $(this)。
Q:jQuery获取节点的常见方法有哪些?
A:常用方法和它们的作用如下——
方法 | 作用 |
---|---|
children() | 获取直接子代元素 |
next() | 获取下一个相邻的兄弟元素 |
prev() | 获取上一个相邻的兄弟元素 |
nextAll() | 获取自身之前的所有兄弟元素 |
prevAll() | 获取自身之后的所有兄弟元素 |
siblings() | 获取其他的兄弟元素 |
parent() | 获取直接父代元素 |
parents() | 获取所有的祖先元素 |
find() | 获取子代和后代中的指定元素 |
Q:如何设置和获取HTML、文本和值?
A:html(), text(), val()。
Tips:分别对应innerHtml、innerText和value属性。
Q:为什么我们使用jQuery?
A:主要有以下理由——
- 易于使用和学习
- 易于扩展
- 跨浏览器支持
- 易于DOM操作
- 大量内置方法
- AJAX功能
- 更改或应用CSS,提供创建动画的方法
- 事件的检测和处理
- 满足各类需求的大量插件
Q:jQuery如何插入节点?
A:append(), appendTo(), prepend(), prependTo(), after(), before()。
Q:如何利用jQuery来向一个元素中添加和移除CSS类?
A:添加——.addClass()
移除——.removeClass()
Q:jQuery中animate()方法有哪些参数?
A:执行样式,执行时间,回调函数。
Tips:animate()方法通常在使用了js的第三方动画库(如move.js)时使用,执行样式通常为动画的名称。
HTTP
Q:HTTP状态消息200、302、304、403、404、500分别表示什么?
A:状态消息与对应的状态如下表——
状态消息(code) | 状态 |
---|---|
200 | 请求成功,响应头或数据体随此响应返回 |
302 | 请求资源临时从不同URL响应请求,客户端应当继续向原地址发送后续请求 |
304 | GET请求已被允许,但文档内容(与上次访问时比较)未被改变 |
403 | 服务器理解请求,但是拒绝执行 |
404 | 请求失败,在服务器上未发现请求的资源 |
500 | 服务器遇到未预料的情况,无法完成对请求的处理,通常是服务器端源代码错误 |
ES6
【本阶段暂时不要求】
CSS相关
基础样式
Q:px、%、vh、vw、rem、em有什么区别?
A:区别如下——
- px是像素值,属于绝对单位,是一种基本单位;
- %是相对父元素尺寸的百分比,对于设置了绝对定位的元素,则是相对于设置了最近的设置了定位属性的祖先元素,对于设置了固定定位的元素,则是相对于可视窗口;
- vh是相对于可视窗口的高度,100vh对应可视窗口高度的100%;
- vw是相对于可视窗口的宽度,100vw对应可视窗口宽度的100%;
- rem是相对于根元素font-size属性数值的倍数,比如如果根元素html默认字体大小为16px,那么1rem就是16px;
- em是相对于父元素font-size属性数值的倍数。
Q:flex布局中flex属性的值有哪些?
A:flex属性是flex-grow,flex-shrink和flex-basis的简写,默认值为0 1 auto。
Tips:这三个属性的作用如下表——
属性 | 作用 |
---|---|
flex-grow | 定义项目(元素)的扩大比例,默认值为0 |
flex-shrink | 定义项目(元素)的缩小比例,默认值为1(不可为负值) |
flex-basis | 定义了在分配多余空间之前,成员占据的主轴空间,默认值为auto,即成员本身占据的大小 |
Q:CSS中的calc的作用是什么?请举例。
A:作用是实时计算属性值。比如——
width: calc(100% - 100px);
Q:如何隐藏元素?
A:在CSS中,有下面的三种方式——
- visibility: hidden;
- opacity: 0;
- display: none;
HTML5提供了一个新的属性——hidden,也可以用来隐藏元素。
Q:CSS优先级算法如何计算?
A:主要有三种标准——
- 同权重下,就近原则
- 载入样式,以最后载入的样式为准
- 优先级 !important > 内联 > id > class > 标签 > *
Q:为什么要初始化CSS样式?
A:因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。
Q:描述一下box-sizing属性。
A:有两种属性——context-box和border-box。
-
context-box:W3C的标准盒子模型,设置元素的 height/width 属性指的是content部分的高/宽
-
border-box:IE传统盒子模型。设置元素的height/width属性指的是border + padding + content部分的高/宽
Q:a标签样式如何初始化?
A:示例代码如下——
a{
text-decoration: none;
}
Q:::before 和 ::after 之前的双冒号和单冒号的区别?这2个伪元素的作用?
A:在 CSS3 中 : 表示伪类, :: 表示伪元素;
想让插入的内容出现在其他内容前,使用::before,否则,使用::after。
布局
Q:移动端下内部元素可以左右滑动,不显示滚动条。
A:分析题目——
设置左右滑动,需要让元素在水平方向超出,并出现水平向滚动条。
对应属性——
div {
overflow-x: scoll;
}
下面,让滚动条隐藏,由于为水平向滚动条,所以直接将高度设置为0即可——
div::-webkit-scollbar {
height: 0;
}
Q:@media媒体类型有哪些?
A:All(全部类型),print(打印设备)、screen(屏幕设备)、speech(演讲设备)。
Q:响应式布局的优点和缺点是什么?
A:优点是:
- 可以灵活地适应不同分辨率的设备
- 可以快捷解决多设备显示适应问题
缺点是:
- 兼容多设备时,工作量大,效率低下
- 代码冗余,出现隐藏无用的元素,加载时间长
- 一定程度上改变了网站原有的布局结构,会出现用户混淆的情况
Q:网页布局有哪几种,有什么区别?
A:主要有静态布局、自适应布局、流式布局和响应式布局。
- 静态布局:不考虑浏览器尺寸,按照代码设置的尺寸来布局;
- 自适应布局:页面中的元素位置会发生变化,但是大小不会发生变化;
- 流式布局:页面中的元素大小会发生变化,但是位置不会发生变化;
- 响应式布局:由媒体查询获取页面大小,使用对应尺寸下的CSS样式。
CSS3
Q:CSS3有哪些新特性?
A:下面例举一些常见的新特性——
- 圆角 border-radius
- 盒子阴影 box-shadow
- 文字阴影 text-shadow
- 渐变 radial-gradient(径向渐变)和linear-gradient(线性渐变)
- 变形操作 transform: rotate(旋转),skew(斜切),translate(平移),scale(缩放)
- 颜色 rgba
- 新的伪元素 ::selection
- 媒体查询 @media
- 弹性布局 flex
- 边框图片 border-image
HTML相关
HTML5
Q:什么是HTML语义化?
A:简单来说,就是正确的标签做正确的事。
-
语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;
-
搜索引擎的爬虫也依赖于 HTML 标记来确定上下文和各个关键字的权重,利于SEO。
Q:HTML5的优势有哪些?
A:有下面五大优势——
- 相关性
- 标记、代码简洁
- 语义清晰
- 简明的表单和网页应用程序
- 缓存式离线应用程序
Echarts
Q:Echarts支持哪些图表?
A:主要支持12种类型的图表——
折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)、雷达图(填充雷达图)、和弦图、力导向布局图、地图、仪表盘、漏斗图、事件河流图
性能优化
Q:前端有哪些性能优化的方式?
A:常见的优化方式有下面七种——
- 减少DOM操作
- 部署前,将图片和代码压缩
- 优化JS代码结构,减少冗余代码
- 减少Http请求,合理设置Http缓存
- 使用内容分发cdn加速
- 静态资源缓存
- 图片延迟加载
Q:CSS优化、提高性能的方式有哪些?
A:常见的优化方式如下——
- 避免过度约束
- 避免后代选择符
- 避免链式选择符
- 使用紧凑的语法
- 避免不必要的命名空间
- 避免不必要的重复样式
- 语义化选择器名称,一个好的类名应当是描述它是什么而不是像什么
- 避免使用 !important
- 尽可能精简规则,最好合并类之间的重复规则
Q:什么是优雅降级?什么是渐进增强?
A:
优雅降级:
在新式浏览器中可以正常工作的Web站点,对于老式浏览器,代码会检查确认它们是否能正常工作,并为无法支持新功能的浏览器增加候选方案,使之在老式浏览器上以某种形式降级体验而不至于完全失效。
渐进增强:
从被所有浏览器支持的基本功能开始,逐步向页面增加无害于基础浏览器的只有新式浏览器才支持的样式和功能。当浏览器支持时,它们会自动地呈现出来并发挥作用。
Q:如何减少页面加载时间?
A:主要有下面这些方式——
1.优化图片
2.图片格式的选择
3.优化CSS
4.网址url后加 /
5.为图片注明尺寸(否则浏览器需要不断计算图片大小并做出调整)
6.减少Http请求(合并文件和图片)
结束语
本期内容到此结束,需要了解更多的全栈面试相关内容,可以点击我的主页或订阅我的全栈面试题汇总系列。
在全栈领域,博主也只不过是一个普通的萌新而已。本系列的博客主要是记录一下自己学习的一些经历,然后把自己领悟到的一些东西总结一下,分享给大家。
文章全篇的操作过程都是笔者亲自操作完成的,一些定义性的文字加入了笔者自己的很多理解在里面,所以仅供参考。如果有说的不对的地方,还请谅解。
==期待与你在下一期博客中再次相遇==
——过期比较久的【H2O2】