最全面、最详细web前端面试题及答案总结

2022-08-01 10:38:51 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

最全面、最详细web前端面试题及答案总结

总结不易,希望可以帮助到即将面试或还在学习中的web前端小伙伴,祝面试顺利,拿高薪!

本章是HTML考点的⾮重难点,因此我们采⽤简略回答的⽅式进⾏撰写,所以不会有太多详细的解释。我们约定,每个问题后我们标记『✨ 』的为⾼频⾯试题 doctype的作⽤是什么?✨ DOCTYPE是html5标准⽹⻚声明,且必须声明在HTML⽂档的第⼀⾏。来告知浏览器的解析器⽤什么⽂档标准解析这个 ⽂档,不同的渲染模式会影响到浏览器对于 CSS 代码甚⾄ JavaScript 脚本的解析 ⽂档解析类型有: BackCompat:怪异模式,浏览器使⽤⾃⼰的怪异模式解析渲染⻚⾯。(如果没有声明DOCTYPE,默认就是这个模式) CSS1Compat:标准模式,浏览器使⽤W3C的标准解析渲染⻚⾯。 IE8还有⼀种介乎于上述两者之间的近乎标准的模式,但是基本淘汰了。

这三种模式的区别是什么?

标准模式(standards mode):⻚⾯按照 HTML 与 CSS 的定义渲染怪异模式(quirks mode)模式: 会模拟更旧的浏览器的⾏为 近乎标准(almost standards)模式: 会实施了⼀种表单元格尺⼨的怪异⾏为(与IE7之前的单元格布局⽅式⼀致), 除此之外符合标准定义 HTML、XHTML、XML有什么区别? HTML(超⽂本标记语⾔): 在html4.0之前HTML先有实现再有标准,导致HTML⾮常混乱和松散 XML(可扩展标记语⾔): 主要⽤于存储数据和结构,可扩展,⼤家熟悉的JSON也是相似的作⽤,但是更加轻量⾼效,所以XML现在市场越来越⼩了 XHTML(可扩展超⽂本标记语⾔): 基于上⾯两者⽽来,W3C为了解决HTML混乱问题⽽⽣,并基于此诞⽣了 HTML5,开头加⼊ 的做法因此⽽来,如果不加就是兼容混乱的HTML,加了就是标准模式。 什么是data-属性? HTML的数据属性,⽤于将数据储存于标准的HTML元素中作为额外信息,我们可以通过js访问并操作它,来达到操作数据的⽬的。 前端框架出现之后,这种⽅法已经不流⾏了 你对HTML语义化的理解?✨ 语义化是指使⽤恰当语义的html标签,让⻚⾯具有良好的结构与含义,⽐如

标签就代表段落,

代表正⽂内容等等。 语义化的好处主要有两点: 开发者友好:使⽤语义类标签增强了可读性,开发者也能够清晰地看出⽹⻚的结构,也更为便于团队的开发和维护机器友好:带有语义的⽂字表现⼒丰富,更适合搜索引擎的爬⾍爬取有效信息,语义类还可以⽀持读屏软件,根据 ⽂章可以⾃动⽣成⽬录 这对于简书、知乎这种富⽂本类的应⽤很重要,语义化对于其⽹站的内容传播有很⼤的帮助,但是对于功能性的web软件重要性⼤打折扣,⽐如⼀个按钮、Skeleton这种组件根本没有对应的语义,也不需要什么SEO。

HTML5与HTML4的不同之处

⽂件类型声明(<!DOCTYPE>)仅有⼀型:。新的解析顺序:不再基于SGML。 新的元素:section, video, progress, nav, meter, time, aside, canvas, command, datalist, details, embed, figcaption, figure, footer, header, hgroup, keygen, mark, output, rp, rt, ruby, source, summary, wbr 。 input元素的新类型:date, email, url等等。 新的属性:ping(⽤于a与area), charset(⽤于meta), async(⽤于script)。全域属性:id, tabindex, repeat。 新的全域属性:contenteditable, contextmenu, draggable, dropzone, hidden, spellcheck。 移除元素:acronym, applet, basefont, big, center, dir, font, frame, frameset, isindex, noframes, strike, tt

有哪些常⽤的meta标签? meta标签由name和content两个属性来定义,来描述⼀个HTML⽹⻚⽂档的属性,例如作者、⽇期和时间、⽹⻚描述、关键词、⻚⾯刷新等,除了⼀些http标准规定了⼀些name作为⼤家使⽤的共识,开发者也可以⾃定义name。 charset,⽤于描述HTML⽂档的编码形式

http-equiv,顾名思义,相当于http的⽂件头作⽤,⽐如下⾯的代码就可以设置http的缓存过期⽇期 viewport,移动前端最熟悉不过,Web开发⼈员可以控制视⼝的⼤⼩和⽐例 apple-mobile-web-app-status-bar-style,开发过PWA应⽤的开发者应该很熟悉,为了⾃定义评估⼯具栏的颜⾊。 src和href的区别? src是指向外部资源的位置,指向的内容会嵌⼊到⽂档中当前标签所在的位置,在请求src资源时会将其指向的资源 下载并应⽤到⽂档内,如js脚本,img图⽚和frame等元素。当浏览器解析到该元素时,会暂停其他资源的下载和处理,知道将该资源加载、编译、执⾏完毕,所以⼀般js脚本会放在底部⽽不是头部。 href是指向⽹络资源所在位置(的超链接),⽤来建⽴和当前元素或⽂档之间的连接,当浏览器识别到它他指向的 ⽂件时,就会并⾏下载资源,不会停⽌对当前⽂档的处理。

知道img的srcset的作⽤是什么?(追问) 可以设计响应式图⽚,我们可以使⽤两个新的属性srcset 和 sizes来提供更多额外的资源图像和提示,帮助浏览器选择正确的⼀个资源。 srcset 定义了我们允许浏览器选择的图像集,以及每个图像的⼤⼩。 sizes 定义了⼀组媒体条件(例如屏幕宽度)并且指明当某些媒体条件为真时,什么样的图⽚尺⼨是最佳选择。所以,有了这些属性,浏览器会: 查看设备宽度 检查 sizes 列表中哪个媒体条件是第⼀个为真查看给予该媒体查询的槽⼤⼩ 加载 srcset 列表中引⽤的最接近所选的槽⼤⼩的图像 srcset提供了根据屏幕条件选取图⽚的能⼒ 还有哪⼀个标签能起到跟srcset相似作⽤?(追问) 元素通过包含零或多个 元素和⼀个 元素来为不同的显示/设备场景提供图像版本。浏览器会选择最匹配的⼦ 元素,如果没有匹配的,就选择 元素的 src 属性中的URL。然后,所选图像呈现在 元素占据的空间中 picture同样可以通过不同设备来匹配不同的图像资源 script标签中defer和async的区别?✨ defer:浏览器指示脚本在⽂档被解析后执⾏,script被异步加载后并不会⽴刻执⾏,⽽是等待⽂档被解析完毕后执 ⾏。 async:同样是异步加载脚本,区别是脚本加载完毕后⽴即执⾏,这导致async属性下的脚本是乱序的,对于script 有先后依赖关系的情况,并不适⽤。

蓝⾊线代表⽹络读取,红⾊线代表执⾏时间,这俩都是针对脚本的;绿⾊线代表 HTML 解析

有⼏种前端储存的⽅式?✨ cookies、localstorage、sessionstorage、Web SQL、IndexedDB

这些⽅式的区别是什么?(追问)✨

cookies: 在HTML5标准前本地储存的主要⽅式,优点是兼容性好,请求头⾃带cookie⽅便,缺点是⼤⼩只有4k, ⾃动请求头加⼊cookie浪费流量,每个domain限制20个cookie,使⽤起来麻烦需要⾃⾏封装 localStorage:HTML5加⼊的以键值对(Key-Value)为标准的⽅式,优点是操作⽅便,永久性储存(除⾮⼿动删除),⼤⼩为5M,兼容IE8 sessionStorage:与localStorage基本类似,区别是sessionStorage当⻚⾯关闭后会被清理,⽽且与cookie、localStorage不同,他不能在所有同源窗⼝中共享,是会话级别的储存⽅式 Web SQL:2010年被W3C废弃的本地数据库数据存储⽅案,但是主流浏览器(⽕狐除外)都已经有了相关的实现,web sql类似于SQLite,是真正意义上的关系型数据库,⽤sql进⾏操作,当我们⽤JavaScript时要进⾏转换, 较为繁琐。 IndexedDB: 是被正式纳⼊HTML5标准的数据库储存⽅案,它是NoSQL数据库,⽤键值对进⾏储存,可以进⾏快速读取操作,⾮常适合web场景,同时⽤JavaScript进⾏操作会⾮常⽅便。

CSS基础

CSS选择器的优先级是怎样的?✨ link和@import的区别? 有哪些⽅式(CSS)可以隐藏⻚⾯元素? empxrem区别? 块级元素⽔平居中的⽅法? CSS有⼏种定位⽅式? 如何理解z-index?✨ 如何理解层叠上下⽂?✨ 清除浮动有哪些⽅法? 你对css-sprites的理解 你对媒体查询的理解? 你对盒模型的理解?✨ 标准盒模型和怪异盒模型有什么区别?✨ 谈谈对BFC(Block Formatting Context)的理解? ✨ 为什么有时候⼈们⽤translate来改变位置⽽不是定位? 伪类和伪元素的区别是什么? 你对flex的理解?✨ 关于CSS的动画与过渡问题 本章是CSS考点的⾮重难点,因此我们采⽤简略回答的⽅式进⾏撰写,所以不会有太多详细的解释。我们约定,每个问题后我们标记『✨ 』的为⾼频⾯试题 CSS选择器的优先级是怎样的?✨ CSS选择器的优先级是:内联 > ID选择器 > 类选择器 > 标签选择器 到具体的计算层⾯,优先级是由 A 、B、C、D 的值来决定的,其中它们的值计算规则如下: A 的值等于 1 的前提是存在内联样式, 否则 A = 0; B 的值等于 ID选择器 出现的次数; C 的值等于 类选择器 和 属性选择器 和 伪类 出现的总次数; D 的值等于 标签选择器 和 伪元素 出现的总次数 。 就⽐如下⾯的选择器,它不存在内联样式,所以A=0,不存在id选择器B=0,存在⼀个类选择器C=1,存在三个标签选择器 D=3,那么最终计算结果为: {0, 0, 1 ,3}

按照这个结算⽅式,下⾯的计算结果为: {0, 1, 0, 0}

我们的⽐较优先级的⽅式是从A到D去⽐较值的⼤⼩,A、B、C、D权重从左到右,依次减⼩。判断优先级时,从左到右,⼀⼀⽐较,直到⽐较出最⼤值,即可停⽌。 ⽐如第⼆个例⼦的B与第⼀个例⼦的B相⽐,1>0,接下来就不需要⽐较了,第⼆个选择器的优先级更⾼。

link和@import的区别?

link属于XHTML标签,⽽@import是CSS提供的。 ⻚⾯被加载时,link会同时被加载,⽽@import引⽤的CSS会等到⻚⾯被加载完再加载。 import只在IE 5以上才能识别,⽽link是XHTML标签,⽆兼容问题。link⽅式的样式权重⾼于@import的权重。 使⽤dom控制样式时的差别。当使⽤javascript控制dom去改变样式的时候,只能使⽤link标签,因为@import不是 dom可以控制的。

有哪些⽅式(CSS)可以隐藏⻚⾯元素?

opacity:0 :本质上是将元素的透明度将为0,就看起来隐藏了,但是依然占据空间且可以交互 visibility:hidden : 与上⼀个⽅法类似的效果,占据空间,但是不可以交互了 overflow:hidden : 这个只隐藏元素溢出的部分,但是占据空间且不可交互 display:none : 这个是彻底隐藏了元素,元素从⽂档流中消失,既不占据空间也不交互,也不影响布局 z-index:-9999 : 原理是将层级放到底部,这样就被覆盖了,看起来隐藏了 transform: scale(0,0) : 平⾯变换,将元素缩放为0,但是依然占据空间,但不可交互 还有⼀些靠绝对定位把元素移到可视区域外,或者⽤clip-path进⾏裁剪的操作过于Hack,就不提了。

empxrem区别? px:绝对单位,⻚⾯按精确像素展示。 em:相对单位,基准点为⽗节点字体的⼤⼩,如果⾃身定义了font-size按⾃身来计算(浏览器默认字体是16px),整个⻚⾯内1em不是⼀个固定的值。 rem:相对单位,可理解为”root em”, 相对根节点html的字体⼤⼩来计算,CSS3新加属性,chrome/firefox/IE9 ⽀持

块级元素⽔平居中的⽅法? 如果使⽤Hack的话,⽔平居中的⽅法⾮常多,我们只介绍主流的,奇葩的⻅拓展阅读 margin:0 auto ⽅法 flex布局,⽬前主流⽅法 table⽅法

还有⼀些通过position (margin|transform)等⽅法的不⼀样列举了,⾮重点没必要。拓展阅读: 16种⽅法实现⽔平居中垂直居中 CSS有⼏种定位⽅式?

static: 正常⽂档流定位,此时 top, right, bottom, left 和 z-index 属性⽆效,块级元素从上往下纵向排布,⾏级元素从左向右排列。 relative:相对定位,此时的『相对』是相对于正常⽂档流的位置。 absolute:相对于最近的⾮ static 定位祖先元素的偏移,来确定元素位置,⽐如⼀个绝对定位元素它的⽗级、和祖 ⽗级元素都为relative,它会相对他的⽗级⽽产⽣偏移。 fixed:指定元素相对于屏幕视⼝(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变,⽐如那种回到顶部的按钮⼀般都是⽤此定位⽅式。 sticky:粘性定位,特性近似于relative和fixed的合体,其在实际应⽤中的近似效果就是IOS通讯录滚动的时候的 『顶屁股』。 ⽂字描述很难理解,可以直接看代码

如何理解z-index?✨

CSS 中的z-index属性控制重叠元素的垂直叠加顺序,默认元素的z-index为0,我们可以修改z-index来控制元素的图层位置,⽽且z-index只能影响设置了position值的元素。 我们可以把视图上的元素认为是⼀摞书的层叠,⽽⼈眼是俯视的视⻆,设置z-index的位置,就如同设置某⼀本书在这摞书中的位置。 顶部: 最接近观察者 … 3 层 2 层 1 层 0 层 默认层 -1 层 -2 层 -3 层 … 底层: 距离观察者最远

可以结合这个例⼦理解z-index 如何理解层叠上下⽂?✨ 是什么? 层叠上下⽂是HTML元素的三维概念,这些HTML元素在⼀条假想的相对于⾯向(电脑屏幕的)视窗或者⽹⻚的⽤户的z 轴上延伸,HTML元素依据其⾃身属性按照优先级顺序占⽤层叠上下⽂的空间。

如何产⽣? 触发⼀下条件则会产⽣层叠上下⽂: 根元素 (HTML), z-index 值不为 “auto”的 绝对/相对定位, ⼀个 z-index 值不为 “auto”的 flex 项⽬ (flex item),即:⽗元素 display: flex|inline-flex, opacity 属性值⼩于 1 的元素(参考 the specification for opacity), transform 属性值不为 “none”的元素, mix-blend-mode 属性值不为 “normal”的元素, filter值不为“none”的元素, perspective 值 不 为 “none” 的 元 素 , isolation 属性被设置为 “isolate”的元素, position: fixed 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值(参考 这篇⽂章) -webkit-overflow-scrolling 属性被设置 “touch”的元素 拓展阅读:层叠上下⽂-张鑫旭

清除浮动有哪些⽅法?

空 div ⽅ 法 :

Clearfix ⽅法:上⽂使⽤.clearfix类已经提到overflow: auto或overflow: hidden⽅法,使⽤BFC 在flex已经成为布局主流之后,浮动这种东⻄越来越少⻅了,毕竟它的副作⽤太⼤

你对css sprites的理解,好处是什么? 是什么 ?

雪碧图也叫CSS精灵, 是⼀CSS图像合成技术,开发⼈员往往将⼩图标合并在⼀起之后的图⽚称作雪碧图。

如何操作? 使⽤⼯具(PS之类的)将多张图⽚打包成⼀张雪碧图,并为其⽣成合适的 CSS。 每张图⽚都有相应的 CSS 类,该类定义了background-image、background-position和background-size属性。 使⽤图⽚时,将相应的类添加到你的元素中。

好处: 减少加载多张图⽚的 HTTP 请求数(⼀张雪碧图只需要⼀个请求) 提前加载资源

不⾜: CSS Sprite维护成本较⾼,如果⻚⾯背景有少许改动,⼀般就要改这张合并的图⽚ 加载速度优势在http2开启后荡然⽆存,HTTP2多路复⽤,多张图⽚也可以重复利⽤⼀个连接通道搞定

你对媒体查询的理解? 是什么 媒体查询由⼀个可选的媒体类型和零个或多个使⽤媒体功能的限制了样式表范围的表达式组成,例如宽度、⾼度和颜 ⾊。媒体查询,添加⾃CSS3,允许内容的呈现针对⼀个特定范围的输出设备⽽进⾏裁剪,⽽不必改变内容本身,⾮常适合web⽹⻚应对不同型号的设备⽽做出对应的响应适配。

如何使⽤? 媒体查询包含⼀个可选的媒体类型和,满⾜CSS3规范的条件下,包含零个或多个表达式,这些表达式描述了媒体特 征,最终会被解析为true或false。如果媒体查询中指定的媒体类型匹配展示⽂档所使⽤的设备类型,并且所有的表达式的值都是true,那么该媒体查询的结果为true.那么媒体查询内的样式将会⽣效。

拓展阅读:深⼊理解CSS Media媒体查询

你对盒模型的理解✨ 是什么? 当对⼀个⽂档进⾏布局(lay out)的时候,浏览器的渲染引擎会根据标准之⼀的 CSS 基础框盒模型(CSS basic box model),将所有元素表示为⼀个个矩形的盒⼦(box)。CSS 决定这些盒⼦的⼤⼩、位置以及属性(例如颜⾊、背景、边框尺⼨…)。

盒模型由content(内容)、padding(内边距)、border(边框)、margin(外边距)组成。

标准盒模型和怪异盒模型有什么区别?✨ 在W3C标准下,我们定义元素的width值即为盒模型中的content的宽度值,height值即为盒模型中的content的⾼度值。因此,标准盒模型下: 元素的宽度 = margin-left border-left padding-left width padding-right border-right margin-right

⽽IE怪异盒模型(IE8以下)width的宽度并不是content的宽度,⽽是border-left padding-left content的宽度值 padding-right border-right之和,height同理。 在怪异盒模型下: 元素占据的宽度 = margin-left width margin-right

虽然现代浏览器默认使⽤W3C的标准盒模型,但是在不少情况下怪异盒模型更好⽤,于是W3C在css3中加⼊ box- sizing 。

此演示来源于拓展阅读⽂章

拓展阅读:深⼊理解盒模型

谈谈对BFC的理解✨ 是什么? 书⾯解释:BFC(Block Formatting Context)这⼏个英⽂拆解 Box: CSS布局的基本单位,Box 是 CSS 布局的对象和基本单位, 直观点来说,就是⼀个⻚⾯是由很多个 Box 组成的,实际就是上个问题说的盒模型 Formatting context:块级上下⽂格式化,它是⻚⾯中的⼀块渲染区域,并且有⼀套渲染规则,它决定了其⼦元素将如何定位,以及和其他元素的关系和相互作⽤ 简⽽⾔之,它是⼀块独⽴的区域,让处于BFC内部的元素与外部的元素互相隔离

如何形成? BFC触发条件: 根元素,即HTML元素position: fixed/absolute float 不 为 none overflow不为visible display的值为inline-block、table-cell、table-caption

作⽤是什么? 防⽌margin发⽣重叠

两栏布局,防⽌⽂字环绕等

防⽌元素塌陷

拓展阅读:深⼊理解BFC

为什么有时候⼈们⽤translate来改变位置⽽不是定位? translate()是transform的⼀个值。改变transform或opacity不会触发浏览器重新布局(reflow)或重绘(repaint),只会 触发复合(compositions)。⽽改变绝对定位会触发重新布局,进⽽触发重绘和复合。transform使浏览器为元素创建⼀个 GPU 图层,但改变绝对定位会使⽤到 CPU。 因此translate()更⾼效,可以缩短平滑动画的绘制时间。 ⽽translate改变位置时,元素依然会占据其原始空间,绝对定位就不会发⽣这种情况。拓展阅读:CSS3 3D transform变换-张鑫旭 伪类和伪元素的区别是什么? 是什么? 伪类(pseudo-class) 是⼀个以冒号(:)作为前缀,被添加到⼀个选择器末尾的关键字,当你希望样式在特定状态下才被呈现到指定的元素时,你可以往元素的选择器后⾯加上对应的伪类。 伪元素⽤于创建⼀些不在⽂档树中的元素,并为其添加样式。⽐如说,我们可以通过::before来在⼀个元素前增加⼀些 ⽂本,并为这些⽂本添加样式。虽然⽤户可以看到这些⽂本,但是这些⽂本实际上不在⽂档树中。

区别 其实上⽂已经表达清楚两者区别了,伪类是通过在元素选择器上加⼊伪类改变元素状态,⽽伪元素通过对元素的操作进 ⾏对元素的改变。 我们通过 p::before 对这段⽂本添加了额外的元素,通过 p:first-child 改变了⽂本的样式。

拓展阅读:伪类与伪元素

你对flex的理解?✨ web应⽤有不同设备尺⼨和分辨率,这时需要响应式界⾯设计来满⾜复杂的布局需求,Flex弹性盒模型的优势在于开发 ⼈员只是声明布局应该具有的⾏为,⽽不需要给出具体的实现⽅式,浏览器负责完成实际布局,当布局涉及到不定宽度,分布对⻬的场景时,就要优先考虑弹性盒布局

具体⽤法移步阮⼀峰的flex语法、flex实战,讲得⾮常通俗易懂,⽽且我们⼀两句话说不清楚。

关于CSS的动画与过渡问题 深⼊理解CSS动画animation https://www.cnblogs.com/xiaohuochai/p/5391663.html 深⼊理解CSS过渡transition https://www.cnblogs.com/xiaohuochai/p/5347930.html

参考资料:

  1. 盒模型

JavaScript基础

终于到了⼤家最擅⻓的JavaScript部分,相⽐于HTML和CSS笔者写起JavaScript要顺⼿很多,虽然前端有三剑客的说法,但是实际应⽤中基本就是JavaScript为绝对主导,尤其是在⼯程化的今天。 所以JavaScript才是前端基础⾯试中的重中之重,在这部分我们会加⼊⼀个新的部分就是原理性的解释。 ⽐如,我们会有⼀个⾯试问题『解释下变量提升?』,在本章下我们会有⼀个简短的解释,但是不会解释原理性的东 ⻄,因为『简短的解释』是给⾯试官听的,『原理性的』是给⾃⼰解释的,原理性的解释会在相关问题下连接到其他各个原理性详解的章节。 再说⼀下为什么会有『原理详解』这⼀part,本项⽬并不仅想作为⾯试季帮助⼤家突击的⼀个清单,更想做的是帮助⼤家梳理前端的各个知识点,并把知识点讲透彻,这才是真正对每个开发者有成⻓的事情。 此外,如果不懂原理,很容易被较真的⾯试官追问,⼀下就原形毕露了,所以如果你不懂原理,建议阅读原理部分,如果你已经懂了,可以看简答部分作为梳理即可。 我们约定,每个问题后我们标记『✨ 』的为⾼频⾯试题

本章索引

  1. js基础 谈谈你对原型链的理解? ✨ 如何判断是否是数组? ES6模块与CommonJS模块有什么区别? 聊⼀聊如何在JavaScript中实现不可变对象? JavaScript的参数是按照什么⽅式传递的? js有哪些类型? 为什么会有BigInt的提案? null与undefined的区别是什么? 0.1 0.2为什么不等于0.3? 类型转换的规则有哪些? 类型转换的原理是什么?
  2. js机制 解释下变量提升?✨ ⼀段JavaScript代码是如何执⾏的?✨ JavaScript的作⽤域链理解吗?✨ 谈⼀谈你对this的了解?✨ 箭头函数的this指向哪⾥?✨ 理解闭包吗?✨
  3. js内存 讲讲JavaScript垃圾回收是怎么做的? JavaScript的基本类型和复杂类型是储存在哪⾥的?
  4. 异 步 async/await 是什么?

async/await 相⽐于Promise的优势?

解释下变量提升?✨ JavaScript引擎的⼯作⽅式是,先解析代码,获取所有被声明的变量,然后再⼀⾏⼀⾏地运⾏。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。

上⾯的代码实际执⾏顺序是这样的: 第⼀步: 引擎将 var a = 1 拆解为 var a = undefined 和 a = 1 ,并将 var a = undefined 放到最顶端, a = 1 还在原来的位置 这样⼀来代码就是这样:

第⼆步就是执⾏,因此js引擎⼀⾏⼀⾏从上往下执⾏就造成了当前的结果,这就叫变量提升。原理详解请移步,预解释与变量提升

⼀段JavaScript代码是如何执⾏的?✨ 此部分涉及概念较多,请移步JavaScript执⾏机制

理解闭包吗?✨ 这个问题其实在问:

  1. 闭包是什么?
  2. 闭包有什么作⽤?

闭包是什么 MDN的解释:闭包是函数和声明该函数的词法环境的组合。 按照我的理解就是:闭包 =『函数』和『函数体内可访问的变量总和』举个简单的例⼦:

add 函数本身,以及其内部可访问的变量,即 a = 1 ,这两个组合在⼀起就被称为闭包,仅此⽽已。

闭包的作⽤ 闭包最⼤的作⽤就是隐藏变量,闭包的⼀⼤特性就是内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后 基于此特性,JavaScript可以实现私有变量、特权变量、储存变量等 我们就以私有变量举例,私有变量的实现⽅法很多,有靠约定的(变量名前加_),有靠Proxy代理的,也有靠Symbol这种新数据类型的。 但是真正⼴泛流⾏的其实是使⽤闭包。

函数体内的 var name = ‘cxk’ 只有 getName 和 setName 两个函数可以访问,外部⽆法访问,相对于将变量私有化。

JavaScript的作⽤域链理解吗?✨ JavaScript属于静态作⽤域,即声明的作⽤域是根据程序正⽂在编译时就确定的,有时也称为词法作⽤域。 其本质是JavaScript在执⾏过程中会创造可执⾏上下⽂,可执⾏上下⽂中的词法环境中含有外部词法环境的引⽤,我们 可以通过这个引⽤获取外部词法环境的变量、声明等,这些引⽤串联起来⼀直指向全局的词法环境,因此形成了作⽤域链。

原理详解请移步JavaScript执⾏机制

ES6模块与CommonJS模块有什么区别? ES6 Module和CommonJS模块的区别: CommonJS是对模块的浅拷⻉,ES6 Module是对模块的引⽤,即ES6 Module只存只读,不能改变其值,具体点就是指针指向不能变,类似const import的接⼝是read-only(只读状态),不能修改其变量值。 即不能修改其变量的指针指向,但可以改变变量内部指针指向,可以对commonJS对重新赋值(改变指针指向),但是对ES6 Module赋值会编译报错。 ES6 Module和CommonJS模块的共同点: CommonJS和ES6 Module都可以对引⼊的对象进⾏赋值,即对对象内部属性的值进⾏改变。详解请移步ES6模块与CommonJS模块的差异 js有哪些类型? JavaScript的类型分为两⼤类,⼀类是原始类型,⼀类是复杂(引⽤)类型。原始类型:

boolean null undefined number string symbol 复杂类型: Object

还有⼀个没有正式发布但即将被加⼊标准的原始类型BigInt。

为什么会有BigInt的提案? JavaScript中Number.MAX_SAFE_INTEGER表示最⼤安全数字,计算结果是9007199254740991,即在这个数范围内不 会出现精度丢失(⼩数除外)。 但是⼀旦超过这个范围,js就会出现计算不准确的情况,这在⼤数计算的时候不得不依靠⼀些第三⽅库进⾏解决,因此官⽅提出了BigInt来解决此问题。

null与undefined的区别是什么? null表示为空,代表此处不应该有值的存在,⼀个对象可以是null,代表是个空对象,⽽null本身也是对象。 undefined表示『不存在』,JavaScript是⼀⻔动态类型语⾔,成员除了表示存在的空值外,还有可能根本就不存在(因为存不存在只在运⾏期才知道),这就是undefined的意义所在。

0.1 0.2为什么不等于0.3?

JS 的 Number 类型遵循的是 IEEE 754 标准,使⽤的是 64 位固定⻓度来表示。 IEEE 754 浮点数由三个域组成,分别为 sign bit (符号位)、exponent bias (指数偏移值) 和 fraction (分数值)。64 位中, sign bit 占 1 位,exponent bias 占 11 位,fraction 占 52 位。 通过公式表示浮点数的值 value = sign x exponent x fraction ** 当⼀个数为正数,sign bit 为 0,当为负数时,sign bit 为 1. 以 0.1 转换为 IEEE 754 标准表示为例解释⼀下如何求 exponent bias 和 fraction。转换过程主要经历 3 个过程:

  1. 将 0.1 转换为⼆进制表示
  2. 将转换后的⼆进制通过科学计数法表示
  3. 将通过科学计数法表示的⼆进制转换为 IEEE 754 标准表示

将 0.1 转换为⼆进制表示 回顾⼀下⼀个数的⼩数部分如何转换为⼆进制。⼀个数的⼩数部分,乘以 2,然后取整数部分的结果,再⽤计算后的⼩数部分重复计算,直到⼩数部分为 0 。

因此 0.1 转换为⼆进制表示的过程如下:

⼩数 x2 的结果 整数部分 0.1 0.2 0 0.2 0.4 0 0.4 0.8 0 0.8 1.6 1 0.6 1.2 1 0.2 0.4 0 0.4 0.8 0 0.8 1.6 1 0.6 1.2 1 … … … 得到 0.1 的⼆进制表示为 0.00011…(⽆限重复 0011)

通过科学计数法表示 0.00011…(⽆限重复 0011) 通过科学计数法表示则是 1.10011001…(⽆线重复 1001)*2

转换为 IEEE 754 标准表示 当经过科学计数法表示之后,就可以求得 exponent bias 和 fraction 了。 exponent bias (指数偏移值) 等于 双精度浮点数固定偏移值 (2-1) 加上指数实际值(即 2 中的 -4) 的 11 位⼆进制表示。为什么是 11 位?因为 exponent bias 在 64 位中占 11 位。 因此 0.1 的 exponent bias 等于 1023 (-4) = 1019 的11 位⼆进制表示,即 011 1111 1011。 再来获取 0.1 的 fraction,fraction 就是 1.10011001…(⽆线重复 1001) 中的⼩数位,由于 fraction 占 52位所以抽取 52 位⼩数,1001…(中间有 11 个 1001)…1010 (请注意最后四位,是 1010 ⽽不是 1001,因为四舍五⼊有进位,这个进位 就是造成 0.1 0.2 不等于 0.3 的原因)

此时如果将这个数转换为⼗进制,可以发现值已经变为 0.100000000000000005551115123126 ⽽不是 0.1 了,因此这个计算精度就出现了问题。

类型转换的规则有哪些? 在if语句、逻辑语句、数学运算逻辑、==等情况下都可能出现隐⼠类型转换。

类型转换的原理是什么? 类型转换指的是将⼀种类型转换为另⼀种类型,例如:

当然,类型转换分为显式和隐式,但是不管是隐式转换还是显式转换,都会遵循⼀定的原理,由于JavaScript是⼀⻔动态类型的语⾔,可以随时赋予任意值,但是各种运算符或条件判断中是需要特定类型的,因此JavaScript引擎会在运算时为变量设 定类型. 这看起来很美好,JavaScript引擎帮我们搞定了 类型 的问题,但是引擎毕竟不是ASI(超级⼈⼯智能),它的很多动作会跟我们预期相去甚远,我们可以从⼀到⾯试题开始.

答案是0 是什么原因造成了上述结果呢?那么我们得从ECMA-262中提到的转换规则和抽象操作说起,有兴趣的童鞋可以仔细阅读下这浩如烟海的语⾔规范,如果没这个耐⼼还是往下看.

这是JavaScript种类型转换可以从原始类型转为引⽤类型,同样可以将引⽤类型转为原始类型,转为原始类型的抽象操作为 ToPrimitive ,⽽后续更加细分的操作为: ToNumber ToString ToBoolean 。 为了更深⼊的探究JavaScript引擎是如何处理代码中类型转换问题的,就需要看 ECMA-262详细的规范,从⽽探究其内部原理,我们从这段内部原理示意代码开始.

上⾯代码的逻辑是这样的:

  1. 如果变量为字符串,直接返回.
  2. 如果 !IS_SPEC_OBJECT(x) ,直接返回.
  3. 如果 IS_SYMBOL_WRAPPER(x) ,则抛出异常.
  4. 否则会根据传⼊的 hint 来调⽤ DefaultNumber 和 DefaultString ,⽐如如果为 Date 对象,会调⽤ DefaultString .
  5. DefaultNumber :⾸ 先x.valueOf ,如果为 primitive ,则返回 valueOf 后的值,否则继续调⽤ x.toString ,如果为 primitive ,则返回 toString 后的值,否则抛出异常
  6. DefaultString :和 DefaultNumber 正好相反,先调⽤ toString ,如果不是 primitive 再调⽤ valueOf .

那讲了实现原理,这个 ToPrimitive 有什么⽤呢?实际很多操作会调⽤ ToPrimitive ,⽐如加、相等或⽐较操。在进⾏加操作时会将左右操作数转换为 primitive ,然后进⾏相加。 下⾯来个实例,({}) 1(将{}放在括号中是为了内核将其认为⼀个代码块)会输出啥?可能⽇常写代码并不会这样写, 不过⽹上出过类似的⾯试题。 加操作只有左右运算符同时为 String或Number 时会执⾏对应的 %_StringAdd或%NumberAdd ,下⾯看下 ({}) 1 内部会经过哪些步骤: {} 和 1 ⾸先会调⽤ToPrimitive {} 会⾛到 DefaultNumber ,⾸先会调⽤ valueOf ,返回的是 ,不是 primitive类型,从⽽继续⾛到 toString ,返回 [object Object] ,是 String 类型 最后加操作,结果为 [object Object]1 再⽐如有⼈问你 [] 1 输出啥时,你可能知道应该怎么去计算了,先对 [] 调⽤ ToPrimitive ,返回空字符串,最后结果为”1″。

谈谈你对原型链的理解?✨ 这个问题关键在于两个点,⼀个是原型对象是什么,另⼀个是原型链是如何形成的

原型对象 绝⼤部分的函数(少数内建函数除外)都有⼀个 prototype 属性,这个属性是原型对象⽤来创建新对象实例,⽽所有被创建的对象都会共享原型对象,因此这些对象便可以访问原型对象的属性。 例如 hasOwnProperty() ⽅法存在于Obejct原型对象中,它便可以被任何对象当做⾃⼰的⽅法使⽤. ⽤法: object.hasOwnProperty( propertyName ) hasOwnProperty() 函数的返回值为 Boolean 类型。如果对象 object 具有名称为 propertyName 的属性,则返回 true ,否则返回 false 。

由以上代码可知, hasOwnProperty() 并不存在于 person 对象中,但是 person 依然可以拥有此⽅法. 所以 person 对象是如何找到 Object 对象中的⽅法的呢?靠的是原型链。 原型链 原因是每个对象都有 proto 属性,此属性指向该对象的构造函数的原型。 对象可以通过 proto 与上游的构造函数的原型对象连接起来,⽽上游的原型对象也有⼀个 proto ,这样就形成了原型链。 经典原型链图

如何判断是否是数组? es6中加⼊了新的判断⽅法

在考虑兼容性的情况下可以⽤toString的⽅法

谈⼀谈你对this的了解?✨ this的指向不是在编写时确定的,⽽是在执⾏时确定的,同时,this不同的指向在于遵循了⼀定的规则。 ⾸先,在默认情况下,this是指向全局对象的,⽐如在浏览器就是指向window。

其次,如果函数被调⽤的位置存在上下⽂对象时,那么函数是被隐式绑定的。

再次,显示改变this指向,常⻅的⽅法就是call、apply、bind 以bind为例:

最后,也是优先级最⾼的绑定 new 绑定。 ⽤ new 调⽤⼀个构造函数,会创建⼀个新对象, 在创造这个新对象的过程中,新对象会⾃动绑定到Person对象的this上, 那么 this ⾃然就指向这个新对象。

绑定优先级: new绑定 > 显式绑定 >隐式绑定 >默认绑定

那么箭头函数的this指向哪⾥?✨ 箭头函数不同于传统JavaScript中的函数,箭头函数并没有属于⾃⼰的this,它的所谓的this是捕获其所在上下⽂的 this 值,作为⾃⼰的 this 值,并且由于没有属于⾃⼰的this,⽽箭头函数是不会被new调⽤的,这个所谓的this也不会被改变. 我们可以⽤Babel理解⼀下箭头函数:

转化后

async/await是什么? async 函数,就是 Generator 函数的语法糖,它建⽴在Promises上,并且与所有现有的基于Promise的API兼容。

  1. Async—声明⼀个异步函数(async function someName(){…})
  2. ⾃动将常规函数转换成Promise,返回值也是⼀个Promise对象
  3. 只有async函数内部的异步操作执⾏完,才会执⾏then⽅法指定的回调函数
  4. 异步函数内部可以使⽤await
  5. Await—暂停异步的功能执⾏(var result = await someAsyncCall()

    0 人点赞