前端面试题二

在CSDN整理的前端面试题,忘记都是哪些大神总结的了,所以没法贴出来都是谁的,有冒犯到的烦请见谅哈!
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、HTML/CSS

1、HTML语义化

语义化就是内容的结构化,让标签有自己的含义,让正确的标签做正确的事。
主要围绕标题h、列表l、强调em/strong等标签而言的。
作用是:(1)使得代码结构清晰,使页面在没有CSS的情况在也能够呈现很好的页面效果。(2)语义化可以和搜索引擎建立良好的沟通,有利于SEO(3)语义化使得代码更具有可读性,便于团队开发和维护。

2、CSS选择器

CSS选择器用于指定 CSS 样式的 HTML 标签,它包括了标签选择器、类选择器、id 选择器和通配符选择器,他们的优先级是根据选择器的权重计算的。
判断优先级时,首先我们会判断一条属性声明是否有权重,也就是是否在声明后面加上了!important。一条声明如果加上了权重,
那么它的优先级就是最高的,前提是它之后不再出现相同权重的声明。如果权重相同,我们则需要去比较匹配规则的特殊性。
继承或通配符 0000
元素选择器 0001
类/伪类选择器 0010
ID选择器 0100
行内样式表style 1000
!Important 无穷大
规则中每出现一个选择器,就将它的特殊性进行叠加,这个叠加只限于对应的等级的叠加,不会产生进位。选择器特殊性值的比较是从左向右排序的,也就是说以1开头的特殊性值比所有以0开头的特殊性值要大。比如说特殊性值为1000的的规则优先级就要比特殊性值为0999的规则高。如果两个规则的特殊性值相等的时候,那么就会根据它们引入的顺序,后出现的规则的优先级最高。

3、@import与link

两者都是外部引用CSS的方式。
(1)link是XHTML方式,无兼容问题,除了加载CSS外还可以定义RSS事务等,而@import是CSS方式,低版本浏览器不支持,只能加载CSS。
(2)Link在页面加载时同时执行,而@import是页面加载完之后加载。
(3)Link支持JS控制DOM去改变样式,而@import不支持。总之,link要优于@import

4 盒模型

当对一个文档进行布局(layout)的时候,浏览器的渲染引擎会根据标准将所有元素表示为一个个矩形的盒子。一个盒子由四个部分组成:content、padding、border、margin。盒模型分为标准盒子模型和IE盒子模型。
(1)标准:(content)+padding+border+margin
(2)IE:(content+padding+border)+margin
标准盒模型和IE盒模型的区别在于设置width和height时,所对应的范围不同。标准盒模型的width和height属性的范围只包含了content,而IE盒模型的width和height属性的范围包含了border、padding和content。
一般来说,我们可以通过修改元素的box-sizing属性来改变元素的盒模型。

5、清除浮动

浮动元素可以左右移动,直到遇到另一个浮动元素或者遇到它外边缘的包含框。浮动框不属于文档流中的普通流,当元素浮动之后,不会影响块级元素的布局,只会影响内联元素布局。此时文档流中的普通流就会表现得该浮动框不存在一样的布局模式。当包含框的高度小于浮动框的时候,此时就会出现“高度塌陷”。 清除浮动是为了清除使用浮动元素产生的影响。浮动的元素,高度会塌陷,而高度的塌陷使我们页面后面的布局不能正常显示。

清除浮动的方式

(1)使用clear属性清除浮动。
(2)使用BFC块级格式化上下文来清除浮动。
因为BFC元素不会影响外部元素的特点,所以BFC元素也可以用来清除浮动的影响,因为如果不清除,子元素浮动则父元素高度塌陷,必然会影响后面元素布局和定位,这显然有违BFC元素的子元素不会影响外部元素的设定。

使用 clear 属性清除浮动的原理?

使用clear属性清除浮动,其语法如下:
clear:none|left|right|both
如果单看字面意思,clear:left应该是“清除左浮动”,clear:right应该是“清除右浮动”的意思,实际上,这种解释是有问题的,因为浮动一直还在,并没有清除。
官方对clear属性的解释是:“元素盒子的边不能和前面的浮动元素相邻。”,我们对元素设置clear属性是为了避免浮动元素对该元素的影响,而不是清除掉浮动。
还需要注意的一点是clear属性指的是元素盒子的边不能和前面的浮动元素相邻,注意这里“前面的”3个字,也就是clear属性对“后面的”浮动元素是不闻不问的。考虑到float属性要么是left,要么是right,不可能同时存在,同时由于clear属性对“后面的”浮动元素不闻不问,因此,当clear:left有效的时候,clear:right必定无效,也就是此时clear:left等同于设置clear:both;同样地,clear:right如果有效也是等同于设置clear:both。由此可见,clear:left和clear:right这两个声明就没有任何使用的价值,至少在CSS世界中是如此,直接使用clear:both吧。
一般使用伪元素的方式清除浮动
.clear::after{
content:’’;
display:table;//也可以是’block’,或者是’list-item’
clear:both;
}
clear属性只有块级元素才有效的,而::after等伪元素默认都是内联水平,这就是借助伪元素清除浮动影响时需要设置display属性值的原因。

zoom:1 的清除浮动原理?

清除浮动,触发hasLayout;
zoom属性是IE浏览器的专有属性,它可以设置或检索对象的缩放比例。解决ie下比较奇葩的bug。譬如外边距(margin)的重叠,浮动清除,触发ie的haslayout属性等。
来龙去脉大概如下:
当设置了zoom的值之后,所设置的元素就会就会扩大或者缩小,高度宽度就会重新计算了,这里一旦改变zoom值时其实也会发生重新渲染,运用这个原理,也就解决了ie下子元素浮动时候父元素不随着自动扩大的问题。
zoom属性是IE浏览器的专有属性,火狐和老版本的webkit核心的浏览器都不支持这个属性。然而,zoom现在已经被逐步标准化,出现在CSS3.0规范草案中。

目前非ie由于不支持这个属性,它们又是通过什么属性来实现元素的缩放呢?可以通过css3里面的动画属性scale进行缩放。

6、水平居中/垂直居中

如何居中div
一般常见的几种居中的方法有:
对于宽高固定的元素
(1)我们可以利用margin:0 auto来实现元素的水平居中。
(2)利用绝对定位,设置四个方向的值都为0,并将margin设置为auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中。
(3)利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过margin负值来调整元素的中心点到页面的中心。
(4)利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过translate来调整元素的中心点到页面的中心。
(5)使用flex布局,通过align-items:center和justify-content:center设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中。
对于宽高不定的元素,上面的后面两种方法,可以实现元素的垂直和水平的居中。

7、相对/绝对定位

1、功能理解
相对定位:相对于自己(一开始的位置)进行定位的,但无论怎么移动,这个元素会依然占据原来的位置,它是不占用偏移后的位置的,也就是说偏移后的元素相当于一个投影/虚像。
绝对定位:相对于离自己最近的开启了定位的祖先元素进行定位的,脱离文档流,因此可以盖住页面上的其他元素,可以用z-index来控制开启了绝对定位的元素与其他元素的层叠关系。
浮动:向左或向右浮动,直到遇到其他元素。
2、使用目的
  浮动:让元素排成一行;
  定位:能随意摆放元素;
3、共同点:
  浮动和定位的元素都会转换为行内块元素。
绝对定位元素与非绝对定位元素的百分比计算的区别
绝对定位元素的宽高百分比是相对于临近的position不为static的祖先元素的padding box来计算的。非绝对定位元素的宽高百分比则是相对于父元素的content box来计算的。

8、Flex布局

意为”弹性布局”,可以简便、完整、响应式地实现各种页面布局.
flex布局是CSS3新增的一种布局方式,我们可以通过将一个元素的display属性值设置为flex从而使它成为一个flex容器,它的所有子元素都会成为它的项目。
一个容器默认有两条轴,一个是水平的主轴,一个是与主轴垂直的交叉轴。我们可以使用flex-direction来指定主轴的方向。
我们可以使用justify-content来指定元素在主轴上的排列方式,使用align-items来指定元素在交叉轴上的排列方式。还可以使用flex-wrap来规定当一行排列不下时的换行方式。
对于容器中的项目,我们可以使用order属性来指定项目的排列顺序,还可以使用flex-grow来指定当排列空间有剩余的时候,项目的放大比例。还可以使用flex-shrink来指定当排列空间不足时,项目的缩小比例。

水平居中:只需把要处理的块元素的父级设置display:flex,justify-content:center;
块级元素垂直居中:在需要垂直居中的父元素上,设置display:flex和align-items:center
注意:父元素必须要设置height值
水平垂直居中:display: flex;
justify-content: center;
align-items: center;

9、伪类、伪元素

css引入伪类和伪元素概念是为了格式化文档树以外的信息。也就是说,伪类和伪元素是用来修饰不在文档树中的部分,比如,一句话中的第一个字母,或者是列表中的第一个元素。伪类用于当已有的元素处于某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。比如说,当用户悬停在指定的元素时,我们可以通过:hover来描述这个元素的状态。
伪元素用于创建一些不在文档树中的元素,并为其添加样式。它们允许我们为元素的某些部分设置样式。比如说,我们可以通过::before来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。
有时你会发现伪元素使用了两个冒号(::)而不是一个冒号(:)。这是CSS3的一部分,并尝试区分伪类和伪元素。大多数浏览器都支持这两个值。按照规则应该使用(::)而不是(:),从而区分伪类和伪元素。但是,由于在旧版本的W3C规范并未对此进行
特别区分,因此目前绝大多数的浏览器都支持使用这两种方式表示伪元素。
::before 和:after 中双冒号和单冒号有什么区别
在css3中使用单冒号来表示伪类,用双冒号来表示伪元素。但是为了兼容已有的伪元素的写法,在一些浏览器中也可以使用单冒号来表示伪元素。
伪类一般匹配的是元素的一些特殊状态,如hover、link等,而伪元素一般匹配的特殊的位置,比如after、before等。

10、行内/块级

行内:a、b、span、img、input等 块级:div、ul、ol、li、h等
区别:1.经典:块级元素独占一行,行内元素与其他元素共享一行2.宽高:块级可以直接设置宽高,行内不可以直接设置宽高,需要通过display改变元素属性来设置。( img、input 特殊的行内,置换元素)3.块级可以包含块级和行内、行内只能包含行内。
相互转换:
Display:inline 块级——>行内 display:block 行内——>块级
inline-block布局:**也可以达到横向排列的效果,但需要消除间隙
间隙产生的原因:HTML 中的换行符、空格符、制表符等合并为空白符,字体大小不为 0 的情况下,空白符自然占据一定的宽度,使用inline-block 会产生元素间的空隙。
清除间隙方法:inline-block消除间隙
• inline-block布局:主要用于横向排列
• 浮动布局:主要用于需要文字环绕的时候

11、隐藏元素方式

① visibility: hidden; 这个属性只是简单的隐藏某个元素,但是元素占用的空间任然存在
② opacity: 0; CSS3属性,设置0可以使一个元素完全透明
③ position: absolute; 设置一个很大的 left 负值定位,使元素定位在可见区域之外
④ display: none; 元素会变得不可见,并且不会再占用文档的空间。
⑤ transform: scale(0); 将一个元素设置为缩放无限小,元素将不可见,元素原来所在的位置将被保留
⑥ 

HTML5属性,效果和display:none;相同,但这个属性用于记录一个元素的状态
⑦ height: 0; 将元素高度设为 0 ,并消除边框
⑧ filter: blur(0); CSS3属性,将一个元素的模糊度设置为0,从而使这个元素“消失”在页面中

12、CSS3新增

新增各种CSS选择器 (:not(.input):所有class不是“input”的节点)
圆角 (border-radius:8px)
多列布局 (multi-column layout)
阴影和反射 (Shadow\Reflect)
文字特效 (text-shadow)
文字渲染 (Text-decoration)
线性渐变 (gradient)
旋转 (transform)
缩放,定位,倾斜,动画,多背景
例如:transform:\scale(0.85,0.90)\translate(0px,-30px)\skew(-9deg,0deg)\Animation:

纯 CSS 创建一个三角形的原理

采用的是相邻边框连接处的均分原理。
将元素的宽高设为0,只设置
border
,把任意三条边隐藏掉(颜色设为
transparent),剩下的就是一个三角形。
#demo {
width: 0;
height: 0;
border-width: 20px;
border-style: solid;
border-color: transparent transparent red transparent;
}

13、CSS动画

css3动画通过animation来实现,css3动画不需要事件的触发,只需要调用关键帧即可。因此,制定好关键帧是实现动画的关键步骤。
制定关键帧
方法一:from内一般写入动画的初始状态,to写入动画的结束状态。
@keyframes 关键帧名字{
from{
}
to{
}
}
方法二:百分比形式表示动画的状态,0%表示动画初始状态,100%表示动画结束状态。
@keyframes 关键帧名字{
0%{
}
25%{
}
75%{
}
100%{
}
}
animation动画属性
1.animation-name 关键帧的名字
2.animation-duration 动画的持续时间
3.animation-timing-function 动画的类型(匀速运动 加速运动 贝塞尔曲线等等)
4.animation-delay 动画延迟
5.animation-iteration-count 动画运动次数(默认为一次,属性值infinite为无限循环)
6.animation-direction 动画运动方向(默认正向运动)
属性值:
(1)reverse 反向运动
(2)alternate 先正向后反向再正向后反向……(一直循环)
(3)alternate-reverse 先反向后正向
7.animation-play-state 动画正在运行还是暂停
属性值:
(1)pause 动画停止
(2)running 运动运动(默认值)
拓展:逐帧动画
animation-timing-function:step-start;
逐帧动画指的是帧与帧之间没有动画中间的过渡效果,每次都直接跳到下一帧开始的地方。
animation常用写法
一般动画都不用将每个属性单独写出来,可以用简写的方式,需要什么属性效果就写什么即可。例如,想要一个立方体在10秒内无限匀速循环,可以写成:
animation:关键帧名字 10s linear infinite;

14、.CSS 中哪些属性可以继承?

每一个属性在定义中都给出了这个属性是否具有继承性,一个具有继承性的属性会在没有指定值的时候,会使用父元素的同属性的值来作为自己的值。
一般具有继承性的属性有,字体相关的属性,font-size和font-weight等。文本相关的属性,color和text-align等。表格的一些布局属性、列表属性如list-style等。还有光标属性cursor、元素可见性visibility。
当一个属性不是继承属性的时候,我们也可以通过将它的值设置为inherit来使它从父元素那获取同名的属性值来继承。

15、Display

block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。
none 元素不显示,并从文档流中移除。
inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。
inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。
list-item 像块类型元素一样显示,并添加样式列表标记。
table 此元素会作为块级表格来显示。
inherit 规定应该从父元素继承display属性的值。

16、Position

relative定位的元素,是相对于元素本身的正常位置来进行定位的。
absolute定位的元素,是相对于它的第一个position值不为static的祖先元素的padding box来进行定位的。这句话我们可以这样来理解,我们首先需要找到绝对定位元素的一个position的值不为static的祖先元素,然后相对于这个祖先元素的padding box来定位,也就是说在计算定位距离的时候,padding的值也要算进去。

17、Px/em/rem

px和em都是长度单位,区别是,px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。
三.rem
1.相对长度单位。相对于根节点html字体大小来计算。任意浏览器默认字体高都是16px.
2.如果html根节点设置字体font-size为100px. 则1em=100px. 2em=200px. 跟父级字体无关。
3.浏览器兼容性比较好。

18、Css中less和sess

Sass 和 LESS 都是是 CSS 预处理器,是 CSS 上的一种抽象层,是一种特殊的 语法/语言 最终会编译成 CSS
less和sass都是一种动态样式语言,将 CSS 赋予了动态语言的特性,如变量,继承,运算, 函数.。less 既可以在客户端上运行 (支持 IE 6+, Webkit, Firefox),也可一在服务端运行(需要借助 Node.js)。
less和sass的区别Less和Sass的主要不同就是他们的实现方式。
Less是基于JavaScript,是在客户端处理的。
Sass是基于Ruby的,是在服务器端处理的

为什么要使用less和sass?

结构清晰,便于扩展。
可以方便地屏蔽浏览器私有语法差异。这个不用多说,封装对浏览器语法差异的重复处理,减少无意义的机械劳动。
可以轻松实现多重继承。
完全兼容 CSS 代码,可以方便地应用到老项目中。LESS 只是在 CSS 语法上做了扩展,所以老的 CSS 代码也可以与 LESS 代码一同编译。

19、回流和重绘

一个页面从加载到完成,首先是构建DOM树,然后根据DOM节点的几何属性形成渲染树,当渲染树构建完成,页面根据dom树开始布局,这时候,当我们增删DOM节点,修改元素的宽高,页面布局发生变化,DOM树结构发生变化,那么肯定要重新构建DOM,当DOM树重新构建完,那么页面也就渲染一次,这个过程就叫做回流。而当给一个元素修改颜色,这样的行为是不会影响页面布局的,DOM树不会变化,但页面要重新渲染,这个过程就是重绘。
总结:引起DOM树结构变化,页面布局变化的行为叫回流,且回流一定伴随重绘。
只是样式的变化,不会引起DOM树变化,页面布局变化的行为叫重绘,且重绘不一定会便随回流。

减少重绘和回流方法:

1)不使用能够触发回流的属性。
(2)建立一个图层,让回流在图层里面进行,限制回流和重绘的范围,减少浏览器的运算工作量
(3)尽量不要使用table布局,因为一个小小的改动可能会使整个table进行重新布局。
(4)不要频繁操作元素的样式,对于静态页面,可以修改类名,而不是样式。
(5)使用transform代替top,left,margin-left等属性
(6)将DOM的多个读写操作放在一起,而不是读写操作穿插着写。
如何优化动画?
对于如何优化动画,我们知道,一般情况下。动画需要频繁的操作DOM,就会导致页面的性能问题,我们可以将动画的position属性设置为absolute或fixed,将动画脱离文档流,这样它的回流就不会影响页面了。

20、margin 重叠问题的理解

margin重叠指的是在垂直方向上,两个相邻元素的margin发生重叠的情况。
一般来说可以分为四种情形:
第一种是相邻兄弟元素的marin-bottom和margin-top的值发生重叠。这种情况下我们可以通过设置其中一个元素为BFC来解决。
第二种是父元素的margin-top和子元素的margin-top发生重叠。它们发生重叠是因为它们是相邻的,所以我们可以通过这一点来解决这个问题。我们可以为父元素设置border-top、padding-top值来分隔它们,当然我们也可以将父元素设置为BFC来解决。
第三种是高度为auto的父元素的margin-bottom和子元素的margin-bottom发生重叠。它们发生重叠一个是因为它们相邻,一个是因为父元素的高度不固定。因此我们可以为父元素设置border-bottom、padding-bottom来分隔它们,也可以为父元素设置一个高度,max-height和min-height也能解决这个问题。当然将父元素设置为BFC是最简单的方法。
第四种情况,是没有内容的元素,自身的margin-top和margin-bottom发生的重叠。我们可以通过为其设置border、padding或者高度来解决这个问题。

21、对 BFC 规范(块级格式化上下文:block formatting context)的理解?

BFC指的是块级格式化上下文,一个元素形成了BFC之后,那么它内部元素产生的布局不会影响到外部元素,外部元素的布局也不会影响到BFC中的内部元素。一个BFC就像是一个隔离区域,和其他区域互不影响。一般来说根元素是一个BFC区域,浮动和绝对定位的元素也会形成BFC,display属性的值为inline-block、flex这些属性时也会创建BFC。还有就是元素的overflow的值不为visible时都会创建BFC。

22、移动端的布局用过媒体查询吗?

假设你现在正用一台显示设备来阅读这篇文章,同时你也想把它投影到屏幕上,或者打印出来,而显示设备、屏幕投影和打印等这些媒介都有自己的特点,CSS就是为文档提供在不同媒介上展示的适配方法。当媒体查询为真时,相关的样式表或样式规则会按照正常的级联规被应用。当媒体查询返回假,标签上带有媒体查询的样式表仍将被下载(只不过不会被应用)。 包含了一个媒体类型和至少一个使用宽度、高度和颜色等媒体属性来限制样式表范围的表达式。CSS3加入的媒体查询使得无需修改内容便可以使样式应用于某些特定的设备范围。

23、浏览器是怎样解析 CSS 选择器的?

样式系统从关键选择器开始匹配,然后左移查找规则选择器的祖先元素。只要选择器的子树一直在工作,样式系统就会持续左移,直到和规则匹配,或者是因为不匹配而放弃该规则。试想一下,如果采用从左至右的方式读取CSS规则,那么大多数规则读到最后(最右)才会发现是不匹配的,这样做会费时耗能,最后有很多都是无用的;而如果采取从右向左的方式,那么只要发现最右边选择器不匹配,就可以直接舍弃了,避免了许多无效匹配。

24、margin 和 padding 分别适合什么场景使用?

margin是用来隔开元素与元素的间距;padding是用来隔开元素与内容的间隔。
margin用于布局分开元素使元素与元素互不相干。
padding用于元素与内容之间的间隔,让内容(文字)与(包裹)元素之间有一段距离。
何时应当使用margin:
•需要在border外侧添加空白时。
•空白处不需要背景(色)时。
•上下相连的两个盒子之间的空白,需要相互抵消时。如15px+20px的margin,将得到20px的空白。
何时应当时用padding:
•需要在border内测添加空白时。
•空白处需要背景(色)时。
•上下相连的两个盒子之间的空白,希望等于两者之和时。如15px+20px的padding,将得到35px的空白。

25、为什么不建议使用统配符初始化 css 样式。

采用*{padding:0;margin:0;}这样的写法好处是写起来很简单,但是是通配符,需要把所有的标签都遍历一遍,当网站较大时,
样式比较多,这样写就大大的加强了网站运行的负载,会使网站加载的时候需要很长一段时间,因此一般大型的网站都有分层次的一套初始化样式。
出于性能的考虑,并不是所有标签都会有padding和margin,因此对常见的具有默认padding和margin的元素初始化即可,并不需使用通配符*来初始化。

26、.一个满屏品字布局如何设计?

简单的方式:
上面的div宽100%,
下面的两个div分别宽50%,
然后用float或者inline使其不换行即可

27、.li 与 li 之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

浏览器会把inline元素间的空白字符(空格、换行、Tab等)渲染成一个空格。而为了美观。我们通常是一个

  • 放在一行,这导致
  • 换行后产生换行字符,它变成一个空格,占用了一个字符的宽度。
    解决办法:
    (1)为
  • 设置float:left。不足:有些容器是不能设置浮动,如左右切换的焦点图等。
    (2)将所有
  • 写在同一行。不足:代码不美观。
    (3)将
    • 内的字符尺寸直接设为0,即font-size:0。不足:
      • 中的其他字符尺寸也被设为0,需要额外重新设定其他字符尺寸,且在Safari浏览器依然会出现空白间隔。
        (4)消除
        • 的字符间隔letter-spacing:-8px,不足:这也设置了
        • 内的字符间隔,因此需要将
        • 内的字符间隔设为默认letter-spacing:normal。
  • 28、CSS 里的 visibility 属性有个 collapse 属性值是干嘛用的?在不同浏览器下以后什么区别?

    (1)对于一般的元素,它的表现跟visibility:hidden;是一样的。元素是不可见的,但此时仍占用页面空间。
    (2)但例外的是,如果这个元素是table相关的元素,例如table行,table group,table列,table column group,它的表现却跟display:none一样,也就是说,它们占用的空间也会释放。
    在不同浏览器下的区别:
    在谷歌浏览器里,使用collapse值和使用hidden值没有什么区别。
    在火狐浏览器、Opera和IE11里,使用collapse值的效果就如它的字面意思:table的行会消失,它的下面一行会补充它的位置。

    29、width:auto 和 width:100%的区别

    一般而言
    width:100%会使元素box的宽度等于父元素的content box的宽度。
    width:auto会使元素撑满整个父元素,margin、border、padding、content区域会自动分配水平空间。
    30、简单介绍使用图片 base64 编码的优点和缺点。
    base64编码是一种图片处理格式,通过特定的算法将图片编码成一长串字符串,在页面上显示的时候,可以用该字符串来代替图片的url属性。

    使用base64的优点是:

    (1)减少一个图片的HTTP请求
    使用base64的缺点是:
    (1)根据base64的编码原理,编码后的大小会比原文件大小大1/3,如果把大图片编码到html/css中,不仅会造成文件体积的增加,影响文件的加载速度,还会增加浏览器对html或css文件解析渲染的时间。
    (2)使用base64无法直接缓存,要缓存只能缓存包含base64的文件,比如HTML或者CSS,这相比域直接缓存图片的效果要差很多。
    (3)兼容性的问题,ie8以前的浏览器不支持。一般一些网站的小图标可以使用base64图片来引入

    二、JS面试题

    1.原型对象和原型链

    原型是属性,原型是对象,原型是在一定时期比如执行函数定义的时候当前 prototype 显示原型创建出来,实例化对象的时候下划线原型_proto_产生出来。原型的作用是实现数 据共享、节省空间,通过改变原型实现数据共享。 原型链是一种关系,从对象的_proto_开始,连接的所有对象就是我们所说的原型链, 也可以称为隐式原型链,在查找对象属性时,我们先从自身查找,找不到就会通过__proto__ 属性在父级的原型中找,一级一级往上,如果还找不到返回 Undefined。
    1 每个函数都有 prototype,该属性指向原型对象(显式原型对象)
    2 每个实例都有_proto_属性,该属性指向原型对象(隐式原型对象)
    3 构造函数的显示原型对象===当前构造函数实例对象的隐式原型对象
    4 原型对象的本质:普通的 Object 对象,非函数对象
    5 所有函数都是 new Function 产生的,包括 Function 自己 构造函数。

    构造函数

    构造函数的本质是一个普通函数,他的特点是需要通过 new 关键字来调用, 用来创建对象的实例。所有的引用类型,如[],{},function 等都是由构造函数实例化而来。 一般首字母大写。

    JS 究竟是先有 Object 还是先有 Function 呢?

    两者没有先后关系,两者关系是function属于Object类型,即函数属于对象。现有Object.prototype—>Function.Prototype------>object和Fonction

    如何理解 constructor 属性

    所有函数的原型对象都有一个 constructor 属性指向函数本身。 解析:实例化的对象可以通过[].__proto__.constructor 获取到其构造函数 如何判断一个变量是数组类型 使用 instanceof 关键字 或者 constructor 属性。 解析:instanceof 的原理是判断操作符左边对象的原型链上是否有右边构造函数的 prototype 属性。
    

    作用域 作用域链

    作用域:本身是一个抽象的概念,在定义时就已经创建好了,它是变量的使用范围。全局作用域和局部作用域。ES6 因为 let,const 的引入而有了块作用域。 js 在浏览器中的顶级作用域是 window。
    作用:隔离变量,不同作用域下同名的变量不冲突
    作用域链:简单的理解就是多个嵌套的作用域形成由内向外的结构,用于查找变量。
    作用域链产生:(1)函数定义的时候自动添加一个属性[scopes],该属性保存的是其上下文作用域链(2)函数执行的时候,进入执行上下文环境,将创建的变量添加到[scopes]数组的第一个位置,形成新的数组
    原型链和作用域链的区别 A.b 找 b(对象属性)的过程就是原型链 找 A(变量)的过程就是作用域链 变量提升 在 js 中,所有变量和函数的声明都会被提升到所在作用域的最顶部,所以变量先使用, 后声明是不会报错的。 解析:注意是所在作用域而不是最外层。

    执行上下文

    执行上下文代表了代码执行的环境,包括:执行环境,变量对象,this, 作用域链。执行上下文是动态创建的,函数每调用一次就会创建一个执行上下文。
    执行上下文的流程:
    1 JS 引擎在 JS 代码正式执行之前会创建一个执行环境
    2 进入该环境以后创建一个变量对象,该对象用于收集:变量、函数、函数的参数、 this 前两步又被称为变量提升
    3 确认 this 的指向
    4 创建作用域链

    变量提升机制

    JS存在预解析(现有作用域再有预解析然后执行上下文)分为全局预解析和局部预解析,它做了两件事,把变量提升,把函数提升,赋值和函数表达式不会提升,然后开始往下执行。

    变量提升注意点:
    2. 无论条件成不成立都会先进行预解析
    3. 匿名函数不会预解析
    4. es6 不存在变量提升
    5. 预解析的函数只解析一次(再遇到就会跳过)

    变量提升机制:
    一、变量提升 1)先找 var 进行提升,赋值 undefined,变量名一样,后者覆盖前者 2)遇见函数,把函数名提升,赋值整个代码块 函数名同名,后者覆盖前面,只看最后一个函数即可 3)变量名与函数名同名情况下,最终留下代码块 如果是函数声明,就只解读一次,遇到别的直接跳过 函数表达式是带等号的所以会解读
    二、逐行解读代码 只看带有等号的,如果有赋值,这个变量就是被赋值的值 就算下面有函数声明也不会继续看了

    ✅JS 继承.

    (一)原型链继承:将父类的实例作为子类的原型。

    特点: 1 非常纯粹的继承关系,实例是子类的实例,也是父类的实例 2 父类新增原型方法/原型属性,子类都能访问到 3 简单,易于实现

    缺点: 1 要想为子类新增属性和方法,必须要在 new Animal()这样的语句之后执行,不能放 到构造器中 2 无法实现多继承3 来自原型对象的所有属性被所有实例共享 4 创建子类实例时,无法向父类构造函数传参
    (二)构造函数继承:使用父类的构造函数来增强子类实例,等于是复制父类的实例 属性给子类(没用到原型)
    特点: 1 解决了子类实例共享父类引用属性的问题 2 创建子类实例时,可以向父类传递参数 3 可以实现多继承(call 多个父类对象)
    缺点: 1 实例并不是父类的实例,只是子类的实例 2 只能继承父类的实例属性和方法,不能继承原型属性/方法 3 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
    (三)实例继承:为父类实例添加新特性,作为子类实例返回
    特点: 1 解决了 1 中,子类实例共享父类引用属性的问题 2 创建子类实例时,可以向父类传递参数 3 可以实现多继承(call 多个父类对象)
    缺点: 1 实例并不是父类的实例,只是子类的实例 2 只能继承父类的实例属性和方法,不能继承原型属性/方法 3 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
    (4) 拷贝继承:在子类构造函数中拷贝父类实例的所有方法
    特点: 支持多继承
    缺点: 1 不是是父类的实例,是子类的实例(和父类无关)
    2 效率较低,内存占用高(因为要拷贝父类的属性) 3 无法获取父类不可枚举的方法(不可枚举方法,不能使用 for in 访问到)
    (五)组合继承(1+2 推荐):结合了原型链和构造函数继承,通过调用父类构造, 继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
    特点: 1 弥补了方式 2 的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法 2 既是子类的实例,也是父类的实例 3 不存在引用属性共享问题 4 可传参 5 函数可复用
    缺点: 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了

    ✅数据类型 JS 有七种数据类

    JS 有七种数据类型,分别是 Number、String、Boolean、Null、Undefined、Symbol、Object。 其中 Object 是引用数据类型,其他都是值类型(基本数据类型)。引用数据类型又细分为 Function, Array 和 Object 类型。 值类型占用空间固定,保存在栈里面,操作的是值本身;引用类型占用空间不固定,保 存在堆中,操作的是指向对象的一个指针。

    如何理解堆(heap)栈(stack)

    栈一般存放变量的值,内存空间由系统自动分配和释放;堆一般存放复杂对象,内存空 间为动态分配,不主动释放的话,可能会由垃圾回收机制自动回收。

    Null 和 Undefined 有什么区别

    null 是一个对象指针,但没有指向任何对象,通过 typeof(null)得到的是 Object 类型; undefined 则是一个空值,通过typeof(undefined)得到的是 Undefined。

    什么是浅拷贝和深拷贝

    浅拷贝是只复制指向对象的指针,对新旧对象进行操作都会互相影响;而深拷贝则是创 建一个新的对象,将原来的值一个个复制过来,与原对象不在同一内存地址。

    如何理解 Symbol 类型,使用场景是什么

    Symbol 的特点就是 Symbol 类型只能通过 Symbol()这个方法返回得到,且 Symbol 类型的 值是绝对唯一的。使用场景是作为对象属性的 key 值

    ✅类型判断 (Object.prototype.toString.call)

    1、typeof()函数 JS 基础数据类型做出准确的判断,返回一个表示数据类型的字符串,返回结果包括: number、boolean、string、object、undefined、function 等 6 种数据类型。但 typeof 无 法判断引用数据类型,用此方法判断的所有引用数据类型,都会返回一个 Object。
    2、Instanceof 判断一个变量是否是某个对象的实例。表达式为:A instanceof B,如果 A 是 B 的实例,
    则返回 true,否则返回 false。(instanceof 检测的是原型)。但是无法判断原始类型。
    3、Object.prototype.toString 可以通用的来判断原始数据类型和引用数据类型。toString 是 Object 原型对象上的一个 方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString 运行时 this 指向 的对象类型, 返回的类型格式为[object,xxx],xxx 是具体的数据类型,其中包括: String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,… 基本上所有对象的类型都可以通过这个方法获取到。

    JS 数据类型转换

    强制类型转换

    Number(参数)把任何类型转换成数值类型;parseInt(参数 1,参数 2)将字符串转换成整数;

    parseFloat()将字符串转换成浮点数字;string(参数):可以将任何类型转换成字符串

    ;Boolean()可以将任何类型的值转换成布尔值

    隐式类型转换

    (1).四则运算
    加法运算符+是双目运算符,只要其中一个是 string 类型,表达式的值便是一个 String。 对于其他的四则运算,只要其中一个是 Number 类型,表达式的便是一个 Number。 对于非法字符的情况通常会返回 NaN:‘1’‘a’ // => NaN,这是因为 parseInt(a)值为 NaN, 1NaN 还是 NaN
    (2).判断语句
    判断语句中的判断条件需要是 Boolean 类型,所以条件表达式会被隐式转换为 Boolean。 其转换规则则同 Boolean 的构造函数。比如:var obj = {};if(obj){while(obj);}
    (3).Native 代码调用
    JavaScript 宿主环境都会提供大量的对象,它们往往不少通过 JavaScript 来实现的。JavaScript 给这些函数传入的参数也会进行隐式转换。例如 BOM 提供的 alert 方法接受 String 类型的参 数:alert({a:1}); //=>[object Object]

    relpace 说一下用法

    replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配 的子串。
    replace 方法的语法是:stringObj.replace(rgExp, replaceText) 其中 stringObj 是字符串(string), reExp 可以是正则表达式对象(RegExp)也可以是字符串(string),replaceText 是替代查找到的字 符串

    为什么 0.1+0.2!=0.3

    精度缺失造成的 在 0.1 + 0.2 这个式子中,0.1 和 0.2 都是近似表示的,在他们相加的时候,两个近似值进行 了计算,导致最后得到的值是 0.30000000000000004,此时对于 JS 来说,其不够近似于 0.3, 于是就出现了 0.1 + 0.2 != 0.3 这个现象。 当然,也并非所有的近似值相加都得不到正确的 结果。
    解决办法: 将浮点数转化成整数计算。因为整数都是可以精确表示的。

    on 绑定和 addEventLisener 的区别

    on 绑定是传统的,唯一性 后面注册的会覆盖前面的事件 addEventLister:w3c 标准的事件监听,多次复用同一个事件,函数添加多个事件 ie9 之前使用 attachEvent 代替

    ✅var、const、let 对比

    var 和 let, const 有什么区别 答:var 声明的变量没有块作用域,在最外层声明的话会挂在到 window 上,并且存在变量 提升;let 和 const 声明的是块级变量,不会挂载到 window 上,也不存在变量提升,而且不 能重复声明同一个变量;const 声明的变量不能被重新赋值,一般用来声明常量。
    解析:const 声明的变量虽然不能被重新赋值,但并不意味着他的值不能被改变。例如当 const 声明的变量是引用类型的时候。

    ✅new 的过程.

    描述 new 操作符的执行过程
    ① 创建一个空对象。
    ② 将这个空对象的__proto__指向构造函数的 prototype。
    ③ 将构造函数的 this 指向这个对象。
    ④ 执行构造函数中的代码。
    new 之后发生了什么
    1 使用 new 之后不用加括号一样会执行函数
    2 new 之后 this 变为实例化对象
    3 默认返回值就不是 undefined 而是实例化对象
    4 写了 return,如果 return 后面是简单类型,返回结果依然是实例化对象,如果是复 合类型,返回结果则是这个复合类型

    this 指向问题

    this只有当函数执行的时候才知道它到底指向谁,与编写时的绑定无关,实际上this最终的指向时是那个调用它的对象。
    (1)this 是每次调用函数的时候都会向函数内部传递进一个隐含的参数。
    (2)this 指向的是一个对象,函数执行的上下文对象。
    (3)根据函数的调用方式,this 的指向也不同。
    (4)我们可以把 this 理解为这个函数执行者。
    this 的指向
    (1)普通函数调用,this 指向全局对象 window
    \(2)构造函数调用,this 始终指向新对象
    (3)对象函数调用,谁调用 this 就指向谁,就是那个实例对象 (4)箭头函数调用,箭头函数的 this 指向的是定义时的this,而不是执行时的this,this指向取决于箭头函数所处的环境,它指向外部环境中的this指向。
    怎么改变 this 指向
    js 提供了三种方法 call() , apply() , bind() 三个方法的主要作用都是改变 this 指向。
    call 和 apply 都是改变指向之后,立即执行。 但是 bind 仅仅改变 this 指向,不调用函数。call 和 bind 直接将第二个参数及其以后的 参数作为参数传入函数体内。但是 apply 需要将所有参数放入一个数组内。
    1 call: 通过 call 方法调用函数,第一个参数为 this 指向的对象,第二个参数开始为函 数真正的需要传入的参数。
    2 apply: 通过 apply 方法调用和 call 类似,第一个参数也是 this 指向的对象,区别在 于第二个参数是数组,数据的值为函数所需要传入的参数
    3 bind: 与 apply 和 bind 不同的是,bind 方法传入 this 所指向的对象,返回一个新的 函数。新的函数调用方式和原函数一致。
    call 和 bind 的区别: 它和 call 很相似,接受的参数有两部分,第一个参数是是作为函数上下文的对象,第 二部分参数是个列表,可以接受多个参数。 它们之间的区别有以下两点。 (1)bind 的返回值是一个函数,这个方法不会立即执行,而是返回一个改变 this 之后 的函数,原函数的 this 没有改变。如果想保存改变 this 的方法,需要一个表达式接收该 方法。
    (2)参数的使用也并不相同:call 是把第二个及以后的参数作为 func 方法的实参传 进去,而 func1 方法的实参实则是在 bind 中参数的基础上再往后排。

    ✅闭包

    闭包是一个可以访问到其他函数内部变量的函数,它是在执行内部函数定义之后产生,说白了,闭包其实就是一种引用关系,引用关系存在于内部函数中,引用的是外部函数的变量的对象

    作用:延长了外部函数的变量对象的生命周期,让函数外部可以读取函数内部的数据但如果不及时释放的话会造成内存泄露(闭包是在嵌套的内部函数成为垃圾对象的时候挂的)
    (1)读取函数内部变量(2)让变量的值始终保持在内存中
    解析:闭包的第一个作用可以理解为,java 中的 getter 方法,外部只能通过 getter(闭包) 来访问对象(函数)中的私有变量(变量)。
    缺点:(1)内存消耗(2)性能问题 会涉及到跨作用域的访问,每次访问都会导致性能损失。
    释放闭包:让闭包函数成为垃圾对象,断开指向它的所有引用

    ✅事件循环 【超高频】和 node 中的区别

    JavaScript 为什么是单线程的?

    如果 js 不是单线程的,同时有两个方法操作一个 DOM 节点,一个做删除任务,一个做 修改任务,那么此时浏览器该听谁的?所以,为了避免复杂性,从一诞生,JavaScript 就是 单线程。但是单线程就导致有很多任务需要排队,只有一个任务执行完才能执行后一个任务。如 果某个执行时间太长,就容易造成阻塞;为了解决这一问题,JavaScript 引入了事件循环机 制

    事件循环是什么

    Javascript 单线程任务被分为同步任务和异步任务。
    1 同步任务:立即执行的任务,在主线程上排队执行,前一个任务执行完毕,才能执 行后一个任务;
    2 异步任务:异步执行的任务,不进入主线程, 而是在异步任务有了结果后,将注 册的回调函数放入任务队列中等待主线程空闲的时候读取执行。
    主线程不断从任务队列中读取事件,这个过程是循环不断的, 这种运行机制就叫做 Event Loop(事件循环)!

    宏任务和微任务

    在 JavaScript 中,除了广义的同步任务和异步任务,还可以细分,一种是宏任务 (MacroTask)也叫 Task,一种叫微任务(MicroTask)每次单个宏任务执行完毕后, 检查微任务队列是否为空, 如果不为空,会按照先入先 出的规则全部执行完微任务后, 清空微任务队列, 然后再执行下一个宏任务,如此循环。

    如何区分宏任务与微任务呢?

    宏任务:macrotask,又称为 task, 可以理解为每次执行栈执行的代码就是一个宏任务 (包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。
    一般包括:script(可以理解为外层同步代码)、setTimeout、setInterval 、setImmediate、 I/O 操作
    微任务:microtask, 又称为 job, 可以理解是在当前 task 执行结束后立即执行的任务。
    包括:Promise.then/cath /finally 回调(平时常见的)、 MutationObserver 回调(html5 新特 性)

    为什么要有微任务

    因为事件队列其实是一个“先进先出”的数据结构,排在前面的事件会优先被主线程读 取, 那如果突然来了一个优先级更高的任务,还让去人家排队,就很不理性化, 所以需要 引入微任务。

    JavaScript 为什么是异步的?

    如果 JavaScript 不是异步的,由于代码的执行是自上而下的,那么如果一行代码需要执 行很久,下一行的代码就会被阻塞。对用户来说,就是页面“卡死”,这样的话,用户体验 很差。

    JavaScript 是如何实现异步的?

    JavaScript 是通过事件循环(Event Loop)实现异步的。JavaScript 的核心就是事件循环机制, 理解了事件循环机制,就理解了 JS 的执行机制。

    浏览器是多线程的

    JavaScript 是单线程的,但浏览器是多线程的,多个线程相互配合以保持同步。

    浏览器 里的常驻线程有:

    (1)JS 线程 (2)GUI 渲染线程 (3)基本 UI 事件线程 (4)定时器线程 (5)异步 Ajax 线程

    Node 和浏览器的事件循环的区别?

    浏览器环境下,microtask 的任务队列是每个 macrotask 执行完之后执行。而在 Node.js 中,microtask 会在事件循环的各个阶段之间执行,也就是一个阶段执行完毕,就会去执行 microtask 队列的任务。
    同步就会按顺序来修改。但是,同步需要等待资源访问结束,浪费时间,效率低。 异步则可以提高效率,现在 cpu 都是双核,四核,异步处理的话可以同时做多项工作,
    当然必须保证是可以并发处理的。但是安全性较低。 异步和多线程 两者并不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段。 异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事 情。实现异步可以采用多线程技术或则交给另外的进程来处理。

    总结
    提示:这里对文章进行总结:
    例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

    帮助文档
    快捷键目录标题文本样式列表链接代码片表格注脚注释自定义列表LaTeX 数学公式插入甘特图插入UML图插入Mermaid流程图插入Flowchart流程图插入类图
    标题复制

    异步&同步

    同步:是按顺序执行,执行完一个再执行下一个,需要等待、协调运行。
    异步:就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完 成后再工作。

    同步和异步区别

    同步可以避免出现死锁,读脏数据的发生。一般共享某一资源的时候用,如果每个人都 有修改权限,同时修改一个文件,有可能使一个人读取另一个人已经删除的内容,就会出错, 同步就会按顺序来修改。但是,同步需要等待资源访问结束,浪费时间,效率低。
    异步则可以提高效率,现在 cpu 都是双核,四核,异步处理的话可以同时做多项工作,当然必须保证是可以并发处理的。但是安全性较低。

    异步和多线程

    两者并不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段。 异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事 情。实现异步可以采用多线程技术或则交给另外的进程来处理。

    ✅深拷贝&浅拷贝

    深拷贝:复制了引用地址和值,相当于复制了一份副本,值相同,地址不同,互不影响。
    浅拷贝:仅仅是复制了引用地址,也就是说新变量和旧变量共用内存,彼此的修改会互相影 响。

    如何实现深拷贝?

    (1)使用浅拷贝加递归方法 缺点是只考虑了object和array两种数据结构 嵌套过多容易导致栈溢出。
    (2)json
    用 JSON.stringify 将对象转为字符串,再用 JSON.parse 将字符串转为对象。注意:只有 能被转为 json 格式的对象才能这样用。
    缺点:无法拷贝不能串化的目标。比如:函数
    优点:代码简单
    (3)JQuery中的extend方法
    $extend([deep],target,object[,objectN])
    deep表示是否深拷贝,深为true,浅为false

    浅拷贝方法

    (1)直接赋值(for in循环赋值)
    对于(Boolean、String、Number、Undefined、Null)这五种基本数据类型,它们的复赋 值是值传递,而对于对象的赋值是对引用赋值,所以使用“=”赋值对象就是对对象的浅拷贝。
    (2)Object.assign()
    此方法是 ES6 中定义的方法,用于将源对象的所有可枚举属性复制到目标对象中,返回值是 目标对象。用法如下: Object.assign(targetObj, sourceObj1, …sourceObjn);
    单层的深拷贝,但不是意义上的深拷贝
    (3)ES6中展开运算符
    (4)ES6中Array.from()复制数组,此方法复制为浅拷贝

    事件流(冒泡 捕获) 事件委托

    DOM 事件流
    事件流描述的是从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传 播,这个传播过程即 DOM 事件流。包括三个阶段:事件捕获阶段、处于目标阶段、事件冒 泡阶段。
    。在 dom 模型中,html 是多层次的,当一个 html 元素上产生事件时,该事件会在 dom 树元素节点之间按照特定的顺序去传播。传播路径的每一个节点,都会收到这个事件,这就 是 dom 事件流。当事件发生后,就会从内向外逐级传播,因为事件流本身没有处理事件的 能力,所以,处理事件的函数并不会绑定在该事件源上。例如我们点击了一个按钮,产生了 一个 click 事件,click 事件就会开始向上传播,一直到到处理这个事件的代码中。

    事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听 函数,那就不执行。
    事件冒泡标签之间有嵌套关系,两个标签有相同或者类似的事件,内部事件触发了而外部事件会自动触发,这时候就是事件冒泡。程序中,当一个元素接收到事件的时候会把他接收到的事件传给自己的父级,一直到 window 。
    事件捕获:与冒泡正好相反,从window开始,一层层往内走,直到到达当前的target。从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口 级别捕获事件,不过必须由开发人员特别指定)。

    addEventListener (type, listener[, useCapture])

    第三个参数如果是 true,表示在事件捕获阶段 调用事件处理程序;如果是 false(不写默认就是 false),表示在事件冒泡阶段电泳事件处 理程序。
    在实际开发中,我们很少使用事件捕获(低版本 ie 不兼容),我们更关注事件冒泡 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseover、onmouseleave

    阻止冒泡(重)

    1 event.stopPropagation(); // 一般浏览器停止冒泡 2 event.cancelBubble; // IE 6 7 8 的停止冒泡

    事件对象

    1 event 就是一个事件对象,写道我们的侦听函数的小括号里面,当形参来看
    2 事件对象只有有了事件才会存在,他是系统给我们自动创建的,不需要我们传递参 数
    3 事件对象是我们的事件的一系列相关数据的集合,比如鼠标点击里面就包含了鼠标 的相关信息
    4 这个事件对象我们可以自己命名,比如 event、evt 、e 等 5 事件对象也有兼容性问题。 IE 6、7、8 通过 window.event 实现

    e.target 和 this 的区别

    this 返回的是绑定事件的对象(元素) e.target 返回的是点击的那个对象,就是谁触发了这个事件,如点击事件->谁被点了

    阻止对象默认行为

    1 e.preventDefaule();是一个方法,适合普通浏览器
    2 e.returnValue; 是一个属性,适用于 IE 6 7 8 3 return false;没有兼容性问题,但是需要注意后面的语句就不执行了,直接跳出

    事件委托

    为什么要事件委托

    如果有一个ul,里面有俩个li标签,我们想要设置li标签一个绑定事件,我们直接在ul上遍历方式设置就行,这时候我们加入一个按钮,按钮的作用是点击一次向ul中加入一个li标签,但是新加入的li 标签没有绑定事件,所以我们仅仅用遍历方式绑定事件监听是不合适的,那么就可以采用事件委托

    事件委托原理

    不给每个子节点单独设置事件监听器,而是设置在其父节点上,然后利用冒泡原理设置每个子节点。例如: 给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li ,然后事件冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。
    事件委托的作用:只操作了一次 DOM ,提高了程序的性能。

    Dom和Bom

    区别:
    BOM是浏览器对象模型,DOM是文档对象模型,前者是对浏览器本身进行操作,而后者是对浏览器(可看成容器)内的内容进行操作。bom没有相关标准。dom是w3c的标准、bom的最根本对象是window。dom最根本对象是document(实际上是window.document)。

    题目 1:DOM 是哪种基本的数据结构

    答案:DOM 是一种树形结构的数据结构

    题目 2:DOM 操作的常用 API 有哪些

    答案:获取 DOM 节点,以及节点的 property 和 Attribute。获取父节点,获取子节点。新增 节点,删除节点

    题目 3:DOM 节点的 Attribute 和 property 有何区别

    答案:property 只是一个 JS 对象的属性的修改。(通过 obox.name = xxx 操作) Attribute 是 对 html 便签属性的修改

    题目 4:如何检测浏览器的类型

    答案:可以通过检测 navigator.userAgent 在通过不通浏览器的不通来检测

    5:拆解 url 的各部分

    答 案 : 使 用 location 里 面 的 location.href location.protocol location.pathname location.search location.hash 来获取各种参数

    ES6新语法

    ES6 是什么?

    答: ES6 是新一代的 JS 语言标准,对分 JS 语言核心内容做了升级优化,规范了 JS 使用 标准,新增了 JS 原生方法,使得 JS 使用更加规范,更加优雅,更适合大型应用的开发。

    es6 的新增方法

    1)let 声明变量和 const 声明常量,两个都有块级作用域 ES5 中是没有块级作用域的, 并且 var 有变量提升,在 let 中,使用的变量一定要进行声明
    2)箭头函数 ES6 中的函数定义不再使用关键字 function(),而是利用了()=>来进行定义
    3)模板字符串模板字符串是增强版的字符串,用反引号(`)标识,可以当作普通字符 串使用,也可以用来定义多行字符串
    4)解构赋值 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值
    5)for of 循环 for…of 循环可以遍历数组、Set 和 Map 结构、某些类似数组的对象、对 象,以及字符串
    6)import、export 导入导出 ES6 标准中,Js 原生支持模块(module)。将 JS 代码分割成 不同功能的小块进行模块化,将不同功能的代码分别写在不同文件中,各模块只需导出公共 接口部分,然后通过模块的导入的方式可以在其他地方使用
    7)set 数据结构 Set 数据结构,类似数组。所有的数据都是唯一的,没有重复的值。它 本身是一个构造函数
    8)… 展开运算符可以将数组或对象里面的值展开;还可以将多个值收集为一个变量
    9)修饰器 @decorator 是一个函数,用来修改类甚至于是方法的行为。修饰器本质就 是编译时执行的函数
    10)class 类的继承 ES6 中不再像 ES5 一样使用原型链实现继承,而是引入 Class 这个概 念
    11)async、await 使用 async/await, 搭配 promise,可以通过编写形似同步的代码来处理异 步流程, 提高代码的简洁性和可读性 async 用于申明一个 function 是异步的,而 await 用 于等待一个异步方法执行完成
    12)promisePromise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件) 更合理、强大
    13)SymbolSymbol 是一种基本类型。Symbol 通过调用 symbol 函数产生,它接收一个 可选的名字参数,该函数返回的 symbol 是唯一的
    14)Proxy 代理使用代理(Proxy)监听对象的操作,然后可以做一些相应事情 ES5、ES6 和 ES2015 有什么区别? ES2015 特指在 2015 年发布的新一代 JS 语言标准,ES6 泛指下一代 JS 语言标准,包含 ES2015、ES2016、ES2017、ES2018 等。现阶段在绝大部分场景下,ES2015 默认等同 ES6。ES5 泛指上一代语言标准。ES2015 可以理解为 ES5 和 ES6 的时间分界线。

    let 有什么用,有了 var 为什么还要用 let?

    在 ES6 之前,声明变量只能用 var,var 方式声明变量其实是很不合理的,准确的说,是 因为 ES5 里面没有块级作用域是很不合理的,甚至可以说是一个语言层面的 bug(这也是很多 c++、java 开发人员看不懂,也瞧不起 JS 语言的劣势之一)。没有块级作用域回来带很多难以 理解的问题,比如 for 循环 var 变量泄露,变量覆盖等问题。let 声明的变量拥有自己的块级 作用域,且修复了 var 声明变量带来的变量提升问题。

    var、let、const 之间的区别

    1 var 声明变量可以重复声明,而 let 不可以重复声明
    2 var 是不受限于块级的,而 let 是受限于块级
    3 var 会与 window 相映射(会挂一个属性),而 let 不与 window 相映射
    4 var 可以在声明的上面访问变量,而 let 有暂存死区,在声明的上面访问变量会报 错
    5 const 声明之后必须赋值,否则会报错
    6 const 定义不可变的量,改变了就会报错
    7 const 和 let 一样不会与 window 相映射、支持块级作用域、在声明的上面访问变量 会报错

    使用箭头函数应注意什么?

    (1)用了箭头函数,this 就不是指向 window,而是父级(指向是可变的)
    (2)不能够使用 arguments 对象
    (3)不能用作构造函数,这就是说不能够使用 new 命令,否则会抛出一个错误
    (4)不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数

    介绍下 Set、Map 的区别

    应用场景 Set 用于数据重组,Map 用于数据储存
    Set:
    (1)成员不能重复 (2)只有键值没有键名,类似数组 (3)可以遍历,方法有 add, delete,has
    Map: (1)本质上是健值对的集合,类似集合 (2)可以遍历,可以跟各种数据格式转换

    Promise 构造函数是同步执行还是异步执行,那么 then 方法呢?

    promise 构造函数是同步执行的,then 方法是异步执行的

    日常前端代码开发中,有哪些值得用 ES6 去改进的编程优化或者规范?

    1、常用箭头函数来取代 var self = this;的做法。 2、常用 let 取代 var 命令。 3、常用数组/对象的结构赋值来命名变量,结构更清晰,语义更明确,可读性更好。 4、在长字符串多变量组合场合,用模板字符串来取代字符串累加,能取得更好地效果 和阅读体验。 5、用 Class 类取代传统的构造函数,来生成实例化对象。 6、在大型应用开发中,要保持 module 模块化开发思维,分清模块之间的关系,常用 import、export 方法。、

    Set 是什么,有什么作用?

    答:Set 是 ES6 引入的一种类似 Array 的新的数据结构,Set 实例的成员类似于数组 item 成员,区别是 Set 实例的成员都是唯一,不重复的。这个特性可以轻松地实现数组去重

    Map 是什么,有什么作用?

    答: Map 是 ES6 引入的一种类似 Object 的新的数据结构,Map 可以理解为是 Object 的超集,打破了以传统键值对形式定义对象,对象的 key 不再局限于字符串,也可以是 Object。 可以更加全面的描述对象的属性。

    Proxy 是什么,有什么作用?

    答: Proxy 是 ES6 新增的一个构造函数,可以理解为 JS 语言的一个代理,用来改变 JS 默认的一些语言行为,包括拦截默认的 get/set 等底层方法,使得 JS 的使用自由度更高,可 以最大限度的满足开发者的需求。比如通过拦截对象的 get/set 方法,可以轻松地定制自己 想要的 key 或者 value。下面的例子可以看到,随便定义一个 myOwnObj 的 key,都可以变成 自己想要的函数。

    Promise 是什么,有什么作用?

    答: Promise 是 ES6 引入的一个新的对象,他的主要作用是用来解决 JS 异步机制里, 回调机制产生的“回调地狱”。它并不是什么突破性的 API,只是封装了异步回调形式,使 得异步回调可以写的更加优雅,可读性更高,而且可以链式调用。

    for…in 和 for…of 有什么区别?

    答: ES6 统一了遍历标准,制 定了可遍历对象,用 for…of去遍历S6 规定,有所部署了载 了 Iterator 接口的对象(可遍历对象)都可以通过 for…of 去遍历,而 for…in 仅仅可以遍历对象。这也就意味着,数组也可以用 for…of 遍历,这极大地方便了数组的取值,且避免了很 多程序用 for…in 去遍历数组的恶习。 上面提到的扩展运算符本质上也就是 for…of 循环的一种实现。

    async 函数是什么,有什么作用?

    答: async 函数可以理解为内置自动执行器的 Generator 函数语法糖,它配合 ES6 的 Promise 近乎完美的实现了异步编程解决方案。

    module、export、import 是什么,有什么作用?

    答: module、export、import 是 ES6 用来统一前端模块化方案的设计思路和实现方案。 export、import 的出现统一了前端模块化的实现方案,整合规范了浏览器/服务端的模块化方 法,用来取代传统的 AMD/CMD、requireJS、seaJS、commondJS 等等一系列前端模块不同的 实现方案,使前端模块化更加统一规范,JS 也能更加能实现大型的应用程序开发。 import 引入的模块是静态加载(编译阶段加载)而不是动态加载(运行时加载)。 import 引入 export 导出的接口值是动态绑定关系,即通过该接口,可以取到模块内部 实时的值

    ✅实现多页签通讯

    调用 localstorge、cookies 等本地存储方式。
    方法一:localstorge 在一个标签页里被添加、修改或删除时,都会触发一个 storage 事件, 通过在另一个标签页里监听 storage 事件,即可得到 localstorge 存储的值,实现不同标签页 之间的通信。
    方法二:使用 cookie+setInterval,将要传递的信息存储在 cookie 中,每隔一定时间读取 cookie 信息,即可随时获取要传递的信息。

    Cookie、sessionStorage、localStorage的区别

    共同点
    都是保存在浏览器端!
    区别
    1)cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递;存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。
    而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
    2) 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
    3)作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

    )session和cookie有什么区别 ?

    建议答案 : session是存储服务器端,cookie是存储在客户端,所以session的安全性比cookie高。获取session里的信息是通过存放在会话cookie里的session id获取的。而session是存放在服务器的内存中里,所以session里的数据不断增加会造成服务器的负担,所以会把很重要的信息存储在session中,而把一些次要东西存储在客户端的cookie里。
    session的信息是通过sessionid获取的,而sessionid是存放在会话cookie当中的,当浏览器关闭的时候会话cookie消失,所以sessionid也就消失了,但是session的信息还存在服务器端

    )怎么给localStorage设置值,和获取值 ?

    设置值:localStorage.setItem(键,值)
    获取值:localStorage.getItem(键)

    ✅原生 JS 遍历时获取下标的三种方式

    1 设置元素自定义属性
    2 设置元素 dataset 属性
    3 forEach 遍历直接获取下标:

    JS 垃圾回收机制

    JS 的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时 这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它 们所指向的内存。

    为什么要垃圾回收

    如果没有垃圾回收机制,适时清理不被引用的值并释放相应的内存空间,JavaScript 解 释器将会消耗完系统中所有可用内存,造成系统崩溃。

    垃圾回收的两种方式

    1.标记清除
    标记清除法主要有以下三个步骤:
    1)给所有变量增加一个标记,如果是进入执行环境(比如申明变量),则标记为“进 入环境”,如果是结束执行环境(比如执行完相关函数),则标记为“离开环境”;
    2)去掉“进入环境”的变量标记以及被该变量所引用的变量标记(比如闭包);
    3)还存在标记的变量即是需要被清理的变量。
    2.引用计数
    每个对象计算指向它的指针的数量,当有一个指针指向自己,那么计数值记为1,当删除一个指向自己指针时,计数值减1,那么计数值为0的需要销毁。

    内存泄露

    指程序申请内存后,无法释放已申请的内存空间,造成内存泄露,但内存泄露堆积后会导致内存溢出。

    内存溢出

    指程序申请内存时,没有足够的内存供申请者使用。

    常见内存泄露的原因

    1 全局变量引起的内存泄露 (由于我们使用未声明的全局变量,而意外的创建了一个全局变量,而这个全局变量一直无法被回收。)
    2 闭包引起的内存泄露:慎用闭包
    3 dom 清空或删除时,事件未清除导致的内存泄漏
    4 循环引用带来的内存泄露

    如何减少垃圾回收开销

    在对象结束使用后 ,令 obj = null。这样利于解除循环引用,使得无用变量及时被回收;
    js 中开辟空间的操作有 new(), [ ], { }, function (){…}。最大限度的实现对象的重用;
    慎用闭包。闭包容易引起内存泄露。本来在函数返回之后,之前的空间都会被回收。但 是由于闭包可能保存着函数内部变量的引用,且闭包在外部环境,就会导致函数内部的 变量不能够销毁。

    垃圾回收的缺陷

    和其他语言一样,javascript 的 GC 策略也无法避免一个问题:GC 时,停止响应 其他操作,这是为了安全考虑。而 Javascript 的 GC 在 100ms 甚至以上,对一般的应用 还好,但对于 JS 游戏,动画对连贯性要求比较高的应用,就麻烦了。这就是新引擎需 要优化的点:避免 GC 造成的长时间停止响应。

    优化 GC

    分代回收(Generation GC):与 Java 回收策略思想是一致的。目的是通过区分“临 时”与“持久”对象;多回收“临时对象”区(young generation),少回收“持久对 象”区(tenured generation),减少每次需遍历的对象,从而减少每次 GC 的耗时。
    增量GC:这个方案的思想很简单,就是“每次处理一点,下次再处理一点,如此类推。

    迭代器 什么是迭代器?

    迭代:更新换代(重复)的过程,每次的迭代都必须基于上一次的结果
    迭代器:迭代取值的工具

    为什么要用迭代器?

    迭代器给你提供了一种不依赖索引取值的方式。它们的原型中都有一个Symbol.iterator方法。

    目前接触的可迭代的数据结构有:

    1.数组 Array, 2.类数组(dom 元素/arguments), 3.字符串 String, 后续还会接触: 4.Map, 5.Set也是可迭代的
    不论是哪种数据结构,迭代器是统一的接口,通过一个键为 Symbol.iterator 的方法来实 现,使各种数据结构可被便捷的访问

    迭代器的使用场景

    1. for…of 循环 省去手动 next()的麻烦,遍历的变量可满足语义化,可以中断遍历,可迭代 的数据结构均可使用 for…of
      1. 数组新增方法:keys() / values() / entries()

    数组的操作方式(哪些改变原数组)

    数组去重

    (1)双层for循环 :先定义一个包含原始数组第一个元素的数组,然后遍历原始数组,将原始数组的每个元素与新数组中每个元素进行对比,如果没有重复,则加入新数组(效率底)
    (2)array。filiter()加indexof
    利用indexof检测元素在数组中第一次出现的位置是否和元素现在位置相等,如果不等,则说明重复
    (3)Array.sort()加一行遍历冒泡
    调用数组的排序方法sort(),根据排序后的结果进行遍历及相邻元素比对,相同则跳过
    (4)ES6set去重
    set结构的一个特性就是成员值都是唯一的
    (5)Object键值对
    利用一个空的object对象,我们把数组的值存成object值,比如:object【value】=true,判断整个数组的值,如果存在object【value2】存在,则重复。
    定义数组的方法
    //对象的实例创建
    var aList = new Array(1,2,3);
    //直接量创建
    var aList2 = [1,2,3,‘asd’];
    操作数组中数据的方法
    1、获取数组的长度:aList.length;
    2、用下标操作数组的某个数据:aList[0];
    3、join() 将数组成员通过一个分隔符合并成字符串
    4、push() 和 pop() 从数组最后增加成员或删除成员
    5、unshift()和 shift() 从数组前面增加成员或删除成员
    6、reverse() 将数组反转
    7、indexOf() 返回数组中元素第一次出现的索引值
    8、splice() 在数组中增加或删除成员
    多维数组
    多维数组指的是数组的成员也是数组的数组。
    var aList = [[1,2,3],[‘a’,‘b’,‘c’]];

    alert(aList[0][1]); //弹出2;

    不会改变原数组

    1. concat()
      使用方法:array.concat(array2,array3,…,arrayX)
      返回值: 返回一个新的数组
      concat()方法用于连接两个或多个数组。该方法不会改变现有的数组,仅会返回被连接数组的一个副本。
    2. join()
      . 使用方法:array.join(separator)
      返回值: 返回一个字符串
      join()方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的,默认使用’,'号分割,不改变原数组。
    3. slice()
      使用方法:array.slice(start, end)
      返回值: 返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素
      slice()接受一或两个参数,即要返回项的起始和结束位置。
      在只有一个参数的情况下,slice()方法返回从该参数指定位置到当前数组末尾的所有项;
      如果有两个参数,改方法返回起始和结束位置之间的项——但不包括结束位置的项。
      如果参数为负数,规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
    4. some()
      使用方法:array.some(function(currentValue,index,arr),thisValue)
      返回值: 布尔值
      或 ==> some()对数组中的每一项运行给定的函数,如果该函数对任一项返回true,剩余的元素不会再执行检测;如果没有满足条件的元素,则返回false。
    5. every()
      使用方法:array.every(function(currentValue,index,arr),thisValue)
      返回值: 布尔值
      和 ==> every()对数组中的每一项运行给定的函数,如果该函数对每一项返回true,剩余的元素不会再执行检测;如果其中有一个没有满足条件的元素,则返回false。
      6.lter()
      使用方法:array.filter(function(currentValue,index,arr), thisValue)
      返回值: 返回数组
      filter()方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
      对数组的每一项都运行给定的函数,返回结果为true的项组成的数组。
    6. find() —— ES6新增的方法
      使用方法:array.find(function(currentValue, index, arr),thisValue)
      返回值: 返回符合测试条件的第一个数组元素值,如果没有符合条件的则返回 undefined
      find()方法传入一个回调函数,找到数组中符合当前搜索规则的第一个元素,返回它,并且终止搜索。

    filter()和find()方法的区别
    filter()方法是对数组的每一项都进行检查,最后返回结果为true的数组;而find()方法当找到符合的元素时,立刻返回该元素,之后的元素不再进行检查;
    filter()方法如果没有找到符合的元素返回空的数组;而find()方法没有找到符合的元素则返回undefined
    7. map()
    使用方法:array.map(function(currentValue,index,arr), thisValue)
    返回值: 返回数组
    map()方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
    8. forEach()
    使用方法:array.forEach(function(currentValue, index, arr), thisValue)
    返回值: undefined
    forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。这个方法没有返回值。
    本质上与使用for循环迭代数组一样。

    会改变原数组

    1. push()
      使用方法:array.push(item1, item2, …, itemX)
      返回值: 返回新数组的长度
      push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
    2. pop()
      使用方法:array.pop()
      返回值: 数组原来的最后一个元素的值(移除的元素)
      pop()方法用于删除并返回数组的最后一个元素。返回最后一个元素,会改变原数组。
    3. unshift()
      使用方法:array.unshift(item1,item2, …, itemX)
      返回值: 返回新数组的长度
      unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。返回新长度,改变原数组。
    4. shift()
      使用方法:array.shift()
      返回值: 数组原来的第一个元素的值(移除的元素)
      shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。返回第一个元素,改变原数组。
    5. sort()
      使用方法:array.sort(sortfunction)
      返回值: 返回排序后的数组(默认升序)
      sort() 法用于对数组的元素进行排序。
      排序顺序可以是字母或数字,并按升序或降序。
      默认排序顺序为按字母升序。
    6. reverse()
      使用方法:array.reverse()
      返回值: 返回颠倒后的数组
      reverse() 方法用于颠倒数组中元素的顺序。返回的是颠倒后的数组,会改变原数组。
    7. fill() —— ES6新增的方法
      使用方法:array.fill(value, start, end)
      返回值: 返回新的被替换的数组
      fill()方法用于将一个固定值替换数组的元素。
    8. splice()
      使用方法:array.splice(index,howmany,item1,…,itemX)
      返回值: 如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组
      splice()有多种用法:
      1、删除: 可以删除任意数量的项,只需要指定2个参数:要删除的第一项的位置和要删除的项数。
      splice(0,2) // 会删除数组中前两项
      2、插入: 可以向指定位置插入任意数量的项,只需提供3个参数:起始位置、0(要删除的项数)和要插入的项。如果要插入多个项,可以再传入第四、第五,以至任意多个项。
      splice(2,0,1,4) // 会从数组位置2的地方插入1和4
      3、替换: 可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需提供3个参数:起始位置、要删除的项数和要插入的项。插入的项不必与删除的项数相等。
      splice(2,3,1,4) // 会从数组位置2删除两项,然后再从位置2的地方插入1和4
      三、其他
      1. form() —— ES6新增的方法
      使用方法:Array.from(object, mapFunction, thisValue)
      返回值: 数组对象
      from() 方法用于字符串、拥有 length 属性的对象(伪数组)或可迭代的对象(Set/Map)来返回一个数组。

    数组扁平化五种

    数组扁平化是指将一个多维数组变为一维数组 几种办法的核心都是遍历数组添加到一个新的数组里面 5 种
    1、reduce
    2. toString & split
    3. 3. join & split
    4. 4. 递归
    5. 扩展运算符

    for 循环的方法(为什么 Object 不能 for of)

    为什么 Object 不能 for of
    因为 for of 遍历依靠的是遍历器 Iterator。for…of 正常遍历,都需要实现一个遍历器 Iterator
    常见的循环
    1 for 循环 2 for-in 循环 主要用于遍历对象 3 for-of 循环 用以遍历所有的数据结构的统一方法 4 for-each 循环 对数组的所有成员依次执行参数函数 5 map 循环 将数组所有成员一次传入参数函数,然后把每次的结果组成一个新数组返回 6 filter 循环 用于过滤数组成员,将满足条件的数组成员组合成一个新数组返回,不会改变 原数组

    模块化

    模块化的工程意义首先在于分治的思想,对功能进行分治,有利于我们的维护;其次是复用, 有利于我们的开发。将一个大问题分解成多个较为独立的与原问题性质相同的小问题,将所 有的小问题的解答组合起来即可得到大问题的答案。

    jq 和 vue 你在用的时候有什么区别

    1.从 jquery 到 vue 的转变是一个思想想的转变,就是将原有的直接操作 dom 的思想转变到 操作数据上去。
    2.传统前端开发模式中是以 jq 为核心的,而 vue 是现在一个兴起的前端 js 库,是一个精简 的 MVVM。
    3.jQuery 是使用选择器() 选 取 D O M 对 象 , 对 其 进 行 赋 值 、 取 值 、 事 件 绑 定 等 操 作 ,
    他 和 原 生 的 H T M L 的 区 别 只 在 于 可 以 更 方 便 的 选 取 和 操 作 D O M 对 象 ,而 数 据 和 界 面 是 在 一 起 的 。 比 如 需 要 获 取 l a b e l 标 签 的 内 容 :)选取 DOM 对象,对其进行赋值、取值、事件绑定等操作。 Vue 则是通过 Vue 对象将数据和 View 完全分离开来了。对数据进行操作不再需要引用相应 的 DOM 对象,可以说数据和 View 是分离的
    4.vue 适用的场景:复杂数据操作的后台页面,表单填写页面 jquery 适用的场景:一些 html5 的动画页面,一些需要 js 来操作页面样式的页面

    promise 是什么 及兼容性

    promise 是异步编程的一种解决方案,比传统的回调函数和事件更强大和合理,所谓 promise,简单来说就会一个容器,里面保存着某个未来才会结束的事情。通常是一个异步 操作,从语法上来说,promise 是一个对象,从它可以获取异步操作的信息 主要解决 js 的 回调地狱问题
    兼容性: IE 内核是不支持 Promise 可以使用第三方插件 bluebird 中对 ES6 的原生 Promise 进行了封装,解决了浏览器兼容性问 题
    promise 的几种状态:pending(进行中)fulfiled(已成功)rejected(已失败)

    回调函数:

    一个通过函数指针调用的函数就叫做回调函数。
    作用:对特定的事件或条件进行 响应。它与箭头函数不一样的是,它会拿返回的值作为参数
    (1)如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其 所指向的函数时,我们就说这是回调函数。 (2)回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的 一方调用的,用于对该事件或条件进行响应。 为何需要回调函数

    Axios

    Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中 底层: createInstance
    底层
    根据默认设置 新建一个 Axios 对象, axios 中所有的请求[axios, axios.get, axios.post 等…]内部调用的都是 Axios.prototype.request,将 Axios.prototype.request 的内部 this 绑定到新建的 Axios 对象上,从而形成一个 axios 实例。新建一个 Axios 对象时,会有两个拦 截器,request 拦截器,response 拦截器。

    axios 的特点是什么

    1 Axios 是一个基于 promise 的 HTTP 库,支持 promise 所有的 API 2 它可以拦截请求和响应
    3 它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON 类型的数据
    4 安全性更高,客户端支持防御 XSRF

    axios 有哪些常用方法

    5 axios.get(url[, config]) //get 请求用于列表和信息查询
    6 axios.delete(url[, config]) //删除
    7 axios.post(url[, data[, config]]) //post 请求用于信息的添加
    8 axios.put(url[, data[, config]]) //更新操作

    .什么情况下会转为字符串

    1)基于 alert、confirm、document.write 等输出内容时,会先把值转为字符串后在输出
    2)基于’+'进行字符串拼接时
    3)把复合类型值转换数字时候。首先会转换字符串然后再转为数字 4)给对象设置属性名时候,如果不是字符串 先转为字符串,然后在作为属性存储到对 象中(对象属性只能是字符串和数字)
    5)手动调用 toString、toFixed(将 Number 四舍五入为指定小数位数的数字)、join、String 方法时候,也是为了转换字符串

  • 9
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值