HTML ,CSS相关

1.网络中使用最多的图片格式有哪些

JPEG,GIF,PNG,最流行的是jpeg格式,可以把文件压缩到最小 在ps以jpeg格式存储时,提供11级压缩级别

2.请简述css盒子模型

一个css盒子从外到内可以分成四个部分:margin(外边距),border(边框),padding(内边距),content(内容)**
​
**默认情况下,盒子的width和height属性只是设置content(内容)的宽和高**
​
**盒子真正的宽应该是:内容宽度+左右填充+左右边距+左右边框**
​
**盒子真正的高应该是:内容高度+上下填充+上下边距+上下边框

3.视频音频标签的使用

视频:

<video src=""></video>

视频标签属性:

src 需要播放的视频地址

width/height 设置播放视频的宽高,和img标签的宽高属性一样

autoplay 是否自动播放 如果设置了autoplay则音乐在打开页面时会自动播放

controls 是否显示控制条 允许用户控制播放

poster 没有播放之前显示的展位图片

loop 是否循环播放

perload 预加载视频(缓存)与autoplay相冲突,设置了autoplay属性,perload属性会失效。

muted 静音模式

音频: 音频属性和视频属性差不多,不过宽高和poster属性不能用

</audio>

4.HTML5新增的内容有哪些?

新增语义化标签 新增表单类型 表单元素 表单属性 表单事件 多媒体标签

5.HTML5新增的语义化标签有哪些?

 语义化标签使得页面的内容结构化,见名知义

标签 描述
<header></header> 定义了文档的头部区域
<footer></footer> 定义了文档的尾部区域
<nav></nav> 定义文档的导航
<section></section> 定义文档中的节(section、区段)
<article></article> 定义页面独立的内容区域
<aside></aside> 定义页面的侧边栏内容
<detailes></detailes> 用于描述文档或文档某个部分的细节
<summary></summary> 标签包含 details 元素的标题
<dialog></dialog> 定义对话框,比如提示框

语义化标签优点: 1.提升可访问性 2.seo 3.结构清晰,利于维护

Header页面头部 main页面主要内容 footer页面底部

Nav导航栏 aside侧边栏 article加载页面一块独立内容

Section相当于div figure加载独立内容(上图下字) figcaption figure的标题

Hgroup标题组合标签 mark高亮显示 dialog 加载对话框标签(必须配合open属性)

Embed加载插件的标签 video加载视频 audio加载音频(支持格式ogg,mp3,wav)

6.Css3新增的特性

边框:

border-radius添加圆角边框       border-shadow:给框添加阴影 (水平位移,垂直位移,模糊半径,阴影尺寸,阴影颜色,insetr(内/外部阴影))border-image:设置边框图像border-image-source 边框图片的路径border-image-slice 图片边框向内偏移border-image-width 图片边框的宽度border-image-outset 边框图像区域超出边框的量border-image-repeat 图像边框是否平铺(repeat平铺 round铺满 stretch 拉伸)

背景:

Background-size 背景图片尺寸

Background-origin规定background-position属性相对于什么位置定位

Background-clip 规定背景的绘制区域(padding-box,border-box,content-box)

渐变:

Linear-gradient()线性渐变

Radial-gradient()径向渐变

文本效果:

Word-break:定义如何换行

Word-wrap:允许长的内容可以自动换行

Text-overflow:指定当文本溢出包含它的元素,应该干啥

Text-shadow:文字阴影(水平位移,垂直位移,模糊半径,阴影颜色)

转换:

Transform 应用于2D3D转换,可以将元素旋转,缩放,移动,倾斜

Transform-origin 可以更改元素转换的位置,(改变xyz轴)

Transform-style 指定嵌套元素怎么样在三位空间中呈现

2D转换方法:

rotate旋转 translate(x,y)指定元素在二维空间的位移 scale(n)定义缩放转换

3D转换方法:

Perspective(n)为3D转换 translate rotate scale

过渡:

Transition-property过渡属性名

Transition-duration 完成过渡效果需要花费的时间

Transition-timing-function 指定切换效果的速度

Transition-delay 指定什么时候开始切换效果

动画:animation

Animation-name 为@keyframes动画名称

animation-duration 动画需要花费的时间

animation-timing-function 动画如何完成一个周期

animation-delay 动画启动前的延迟间隔

animation-iteration-count 动画播放次数

animation-direction 是否轮流反向播放动画

7.清除浮动的方式有哪些?请说出各自的优点

浮动的原因是:当我们对元素进行浮动(float)时,我们的元素就会脱离文档流,像一只小船一样漂流在文档之上。

在 CSS 中,任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素。 float主要用于页面布局,如果使用后没有清除浮动,则会后患无穷

高度塌陷:当所有子元素的浮动的时候,且父元素没有设置高度,这个时候父元素就会产生高度塌陷

清除浮动方式1:给父元素单独定义高度

优点:快速简单,代码少 缺点:无法进行响应式布局

清除浮动方式2:父级定义overflow:hidden;zoom:1(针对ie6的兼容)

优点:简单快速、代码少,兼容性较高 缺点:超出部分被隐藏,布局时要注意

清除浮动方式3:在浮动元素后面加一个空标签,clear:both;height:0;overflow:hidden

优点:简单快速、代码少,兼容性较高。

缺点:增加空标签,不利于页面优化

清除浮动方式4:父级定义overflow:auto

优点:简单,代码少,兼容性好

缺点:内部宽高超过父级div时,会出现滚动条

清除浮动方式5:万能清除法:

给塌陷的元素添加伪对象

#parent {zoom:1;}    /*==for IE6/7 Maxthon2==*/
#parent:after { clear:both;content:'.';display:block;width: 0;height: 0;visibility:hidden;} 

8.定位的属性值有何区别

1、position:relative;相对定位 1> 不影响元素本身特性(无论区块元素还是内联元素会保留其原本特性) 2> 不会使元素脱离文档流(元素原本位置会被保留,即改变位置也不会占用新位置)3> 没有定位偏移量时对元素无影响(相对于自身原本位置进行偏移) 4>提升层级(用z-index样式的值可以改变一个定位元素的层级关系,从而改变元素的覆盖关系,值越大越在上面,z-index只能在position属性值为relative或absolute或fixed的元素上有效。)(两个都为定位元素,后面的会覆盖前面的定位)

2、position: absolute;绝对定位 1> 使元素完全脱离文档流(在文档流中不再占位) 2> 使内联元素在设置宽高的时候支持宽高(改变内联元素的特性) 3> 使区块元素在未设置宽度时由内容撑开宽度(改变区块元素的特性) 4> 相对于最近一个有定位的父元素偏移(若其父元素没有定位则逐层上找,直到document——页面文档对象) 5> 相对定位一般配合绝对定位使用(将父元素设置相对定位,使其相对于父元素偏移)6> 提升层级(同相对定位)

3、position: fixed;固定定位fixed生成固定定位的元素,相对于浏览器窗口进行定位。

4、position:static:默认值默认布局。元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。5、position: sticky 粘性定位粘性定位,该定位基于用户滚动的位置。它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。注意: Internet Explorer, Edge 15 及更早 IE 版本不支持 sticky 定位。 Safari 需要使用 -webkit- prefix 。

9.子元素如何在父元素中居中?

1、子元素宽高比父元素小的情况下,使用定位方法居中

<style>
父元素{
width:400px;
height:400px;
border:1px solid #000;
margin 100px auto 0;
position:relative;
}
子元素{
width:200px;
height:100px;
background:yellow;
position:absolute;
margin:auto;
top:50%;
left:50%;
right:50%;
bottom:50%;
}
</style>

2、已知子元素宽高

父元素{
width:400px;
height:400px;
border:1px solid #000;
margin 100px auto 0;
position:relative;
}
子元素{
width:200px;
height:100px;
background:yellow;
position:absolute;
margin:auto;
top:50%;
left:50%;
margin-top:-50px;/*回高度的一半*/
margin-left:-100px;/*回宽度的一半*/
}

3、固定定位后,使用transform偏移居中(css3技术,IE不支持)

父元素 {
width:400px;
height:400px;
border:1px solid #000;
margin 100px auto 0;
position:relative;
}
子元素{
width:200px;
height:100px;
background:yellow;
position:absolute;
margin:auto;
top:50%;
left:50%;
transform:translate(-50%,-50%);
/*回高度的一半和回宽度的一半*/
}

4、行内元素

<style>.parent{width: 500px;height: 300px;background-color: orange;text-align: center;    //}.son{background-color: pink;line-height: 300px;}</style>
</head>
<body><div class="parent"><span class="son">我是子元素,我要居中</span></div>
</body>

5、弹性盒子flex布局

<style>.parent{width: 500px;height: 300px;background-color: orange;display: flex;justify-content: center;  //align-items: center;    //}.son{background-color: pink;}</style>
</head>
<body><div class="parent"><span class="son">我是子元素,我要居中</span></div>
</body>

10.Border-box与content-box的区别?

Content-box 标准盒模型 width不包括padding和border.

Border-box 怪异盒模型width包括padding和border.

11.如何让元素垂直居中?

1).设置子元素和父元素的行高一样

2).子元素设置为行内块,再加vertical-align:middle

3).已知父元素高度,子元素相对定位,通过transform:translateY(-50%)

4).不知道父元素高度,子绝父相,子元素top:50%,transform:translateY(-50%)

5).创建一个隐藏节点,让隐藏节点的height为剩余高度的一半

6).给父元素display:table,子元素display:table-cell,vertical-align:middle

7).给父元素添加伪元素

8).弹性盒,父元素display:flex,子元素align-self:center

12.Css选择器有哪些,那些属性可以继承,优先级如何计算?Css3新增的伪类有哪些?

CSS是一种用于屏幕上渲染html,xml等一种语言,CSS主要是在相应的元素中应用样式,来渲染相对应用的元素,那么这样我们选择相应的元素就很重要了,如何选择对应的元素,此时就需要我们所说的选择器。在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素。选择器主要是用来确定html的树形结构中的DOM元素节点。

1、*:通用选择器通用选择器,可以匹配页面所有的元素

*{padding: 0; margin:0 font-size:14px;}

2、#X:ID选择器

id选择器比较局限,不能重用。因此需要慎重考虑。

#container { width: 960px; margin: auto;}

3、.X:类选择器

类选择器的开头用.(点)进行表示。与ID选择器的区别就是可以重用。定义多个元素的样式,好比按组进行归类,同一类的样式统一定义。

.container{width:960px; marign:auto;}
如果把两个类串在一起,选择的就是同时具有两个类名的元素,类名的顺序则无所谓,比如 class="urgent warning" , css 选择器你也可以这样写 .warning .urgent{}。

4、X Y:后代选择器

后代选择器,英文名称:descendant selector,本文的开头我们学习了什么是后代元素,比如我们要选择在li元素中包含a标签的链接(不是所有的链接),取消下划线的默认样式,我们可以这样代码实现:

li a {text-decoration: none;}   //给li元素内部的所有<a>设置属性
经验分享: 如果你的选择器看起来像X Y Z A B.error这样就错了。问问自己是否真的需要加入这么多负荷, 这样写的可读性也太差了。还有一个需要注意的,后代元素的层级问题,可能会很深。

5、X:元素选择器

假如你想针对Html预定义的标签,比如类似:p,h3,em,a,div这些标签,我们可以快速为某类标签定义样式。如下段代码所示:

a { color: red; }
ul { margin-left: 0; }

6、X:visited and X:link :链接伪类选择器 :link 伪类来定义所有还没有点击链接的样式,:visited 伪类定义我们曾经点击过或者访问过的链接样式,示例代码如下:

a:link { color: red; }
a:visted { color: purple; }

7、 X + Y:紧邻同胞选择器

若想选择同一个父元素中,相邻的同级别的元素,我们可以使用紧邻同胞选择器(adjacent selector)。如若想把紧跟在h1元素的段落上外边距去掉,你可以这么写:

h1 + p { margin-top:0 }

8、 X > Y:子元素选择器 有时候我们并想选择所有的后代元素,而是想缩小范围,只选择一个元素的子元素,比如我们只想选择 #container>ul 定义id为container的div里的ul元素,而不是曾经更深的后代元素比如li里的ul。

html文档结构:

  • List Item

    • Child
  • List Item
  • List Item
  • List Item

css代码如下:

div#container > ul {border: 1px solid black;}

代码效果:

9、后续同胞选择器

后续同胞选择器使用 ~ 表示,选择一个元素后面同属一个父元素的另一个元素。这个选择器和 X + Y 很像,但没那么严格。后续同胞选择器应用会更广泛。比如下面这个例子,我们选择所有ul后面的P元素。

html文档结构:

  • List Item

    • Child
  • List Item
  • List Item
  • List Item

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor.

css代码如下:

ul ~ p { color: red }

文档选择树形结构:

CSS3哪些属性可以继承?

 css继承特性主要是指文本方面的继承,盒模型相关的属性基本没有继承特性。
不可继承的:
display、margin、border、padding、background、height、min-height、max-height、width、min-width、max-width、overflow、position、top、bottom、left、right、z-index、float、clear、 table-layout、vertical-align、page-break-after、page-bread-before和unicode-bidi。 所有元素可继承的:
visibility和cursor 终极块级元素可继承的:
text-indent和text-align 内联元素可继承的:
letter-spacing、word-spacing、white-space、line-height、color、font、font-family、font-size、font-style、font-variant、font-weight、text-decoration、text-transform、direction 列表元素可继承的:
list-style、list-style-type、list-style-position、list-style-image

选择器优先级怎么计算?

每个规则对应一个初始"四位数":0、0、0、0
若是 行内选择符,则加1、0、0、0
若是 ID选择符,则加0、1、0、0
若是 类选择符/伪类选择符,则分别加0、0、1、0
若是 元素选择符,则分别加0、0、0、1
算法:将每条规则中,选择符对应的数相加后得到的”四位数“,从左到右进行比较,大的优先级越高。css选择器优先级最高到最低顺序为:
1.id选择器(#myid)
2.类选择器(.myclassname)
3.标签选择器(div,h1,p)
4.子选择器(ul < li)
5.后代选择器(li a)
6.伪类选择(a:hover,li:nth-child)
优先级:!important > 内联样式 > id选择器 > 类、伪类、属性选择器 > 标签、伪元素选择器
权 重: !important:10000
内联: 1000
id选择器:100
类、伪类、属性选择器:10
标签、伪元素选择器:1
通用选择器(*)、子选择器(>)、相邻兄弟选择器(+)、通用兄弟选择器(~)权重值为0
注意:!important的优先级是最高的,但出现冲突时则需比较”四位数“。
css3新增伪类选择器:   :first-of-type   :last-of-type   :only-of-type   :only-child :nth-child(n)   :nth-last-of-type(n)   :last-child   :root   :empty   :target   :enabled    :disabled   :checked   :not(selector)  

14.网页中有大量图片加载很慢 你有什么办法进行优化?

1.图片懒加载,在图片未可视区域加一个滚动条事件,判断图片位置与浏览器顶端和页面的距离,如果前者小鱼后者,优先加载
2.使用图片预加载技术,将当前展示图片的前一张和后一张优先下载

15.行内元素/块级元素/空元素有哪些?

CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,如div的display默认值为“block”,则为“块级”元素;span默认display属性值为“inline”,是“行内”元素。

1)快级元素:

1.总是从新的一行开始 2.高度、宽度都是可控的

3.宽度没有设置时,默认为100% 4.块级元素中可以包含块级元素和行内元素

5.块级文字元素中不能放入其他块级元素 6.块级大多为结构性标记

常见快级元素:

 <center>...</center>  地址文字<h1>...</h1>  标题一级<h2>...</h2>  标题二级<h3>...</h3>  标题三级<h4>...</h4>  标题四级<h5>...</h5>  标题五级<h6>...</h6>  标题六级<hr>  水平分割线<p>...</p>  段落<pre>...</pre>  预格式化<blockquote>...</blockquote>  段落缩进   前后5个字符<marquee>...</marquee>  滚动文本<ul>...</ul>  无序列表<ol>...</ol>  有序列表<dl>...</dl>  定义列表<table>...</table>  表格<form>...</form>  表单<div>...</div>

2)行内元素:

1.和其他元素都在一行

2.高度、宽度以及内边距都是不可控的

3.宽高就是内容的高度,依靠自身字体大小和图形支撑结构的,不可以改变

4.行内元素只能行内元素,不能包含块级元素

5.行内元素的paddding可以设置

6.margin只能够设置水平方向的边距,即:margin-left和margin-right,设置margin-top和margin-bottom无效

7.块级大多为结构性标记

常见行内标签:

  <b>...</b>  加粗<strong>...</strong>  加粗<sup>...</sup>  上标<sub>...</sub>  下标<i>...</i>  斜体<em>...</em>  斜体<del>...</del>  删除线<u>...</u>  下划线

3)行内块级元素: 综合块级元素与行内元素的特性,可设宽高(默认是内容宽高),也可以设置内外边距

常见行内快级元素

   <span>...</span>  <a>...</a><img/><textarea>...</textarea><button>..</button><input><br><label>...</label><select>...</select><canvas>...</canvas><progress>...</progress><cite>...</cite><code>...</code><strong>...</strong><em>...</em><audio>...</audio><video>...</video>

4)空元素:系没有内容的html元素:

<br> <meta> <hr>
<link> <input> <img>

5)显示模式转换:

display:block|inline|inline-block

6)行内元素与快级元素的比较:

  1.行内元素会在一条直线上排列(默认宽度只与内容有关),都是同一行的,水平方向排列。块级元素各占据一行(默认宽度是它本身父容器的100%(和父元素的宽度一致),与内容无关),垂直方向排列。块级元素从新行开始,结束接着一个断行。2.行内元素会在一条直线上排列(默认宽度只与内容有关),都是同一行的,水平方向排列。块级元素各占据一行(默认宽度是它本身父容器的100%(和父元素的宽度一致),与内容无关),垂直方向排列。块级元素从新行开始,结束接着一个断行。3.行内元素与块级元素属性的不同,主要是盒模型属性上:行内元素设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效其他:inline-block 的元素(如input、img)既具有 block 元素可以设置宽高的特性,同时又具有 inline 元素默认不换行的特性。当然不仅仅是这些特性,比如 inline-block 元素也可以设置 vertical-align(因为这个垂直对齐属性只对设置了inline-block的元素有效) 属性。
HTML 中的换行符、空格符、制表符等合并为空白符,字体大小不为 0 的情况下,空白符自然占据一定的宽度,使用inline-block 会产生元素间的空隙。

16.浏览器的标准模式和怪异模式区别?

标准模式:浏览器按照W3C标准解析执行代码

怪异模式:浏览器根据自己的方式解析执行代码,因为不同浏览器解析执行方式不一样,所以叫怪异模式

区别:

在怪异模式下,盒模型为怪异盒模型 而在标准模式下为标准盒子模型图片元素的垂直对齐方式:对于行内元素和table-cell元素,标准模式下vertical-align属性默认值是baseline,而在怪异模式下,table单元格中的图片的vertical-align属性默认值是bottom,因此在图片底部会有几像素的空间。元素中的字体:css中font的属性都是可以继承的,怪异模式下,对于table元素,字体的某些元素不能从其他封装元素继承中得到,特别是font-size属性。内联元素的尺寸:标准模式下,non-replaced inline元素无法自定义大写,怪异模式下,定义元素的宽高会影响元素的尺寸。元素的百分比高度:当一个元素使用百分比高度时,在标准模式下,高度取决于内容变化,在怪异迷失下,百分比被准确应用。元素溢出的处理:标准模式下,overflow取值默认值为visible,在怪异模式下,这个溢出会被当做扩展box对待,就是元素的大小由内容决定,溢出不会裁剪,元素框自动调整,包含溢出内容。

17.Margin和padding在什么场合下使用?

Margin外边距 自身边框到另一个边框之间的距离
Padding 内边距 自身边距到自身内容之间的距离当需要在border外侧添加空白时用margin,当需要在border内侧添加空白时用padding17.Margin和padding在什么场合下使用

18.弹性盒子布局属性有哪些?请阐述?

Flex布局:**Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。**

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。采用flex布局的元素,称为Flex容器(flex contianer),简称“容器” 。它的所有子元素自动转换为容器成员,称为Flex项目(flex item).

任何一个容器都可以指定为Flex布局。

.box{display: flex;
}

行内元素也可以使用Flex布局。

.box{display: inline-flex;
}

Webkit内核的浏览器,必须加上-webkit前缀。

.box{display: -webkit-flex; /* Safari */display: flex;
}

注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。

Flex-direction:弹性容器中子元素排列方式(主轴排列方式)Flex-wrap:设置弹性盒子的子元素超出父容器时是否换行Flex-flow:是flex-direction和flex-wrap简写形式Align-item:设置弹性盒子元素在侧轴上的对齐方式Align-content:设置行对齐Justify-content:设置弹性盒子元素在主轴上的对齐方式

1) flex-direction属性

flex-direction属性决定主轴(水平)的方向(即项目的排列方向)。

.box {flex-direction: row | row-reverse | column | column-reverse;
}
row(默认值):主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。 

2).flex-wrap属性

默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

.box{flex-wrap: nowrap | wrap | wrap-reverse;
}
nowrap(默认):不换行
wrap:换行 第一行在上方
wrap-reverse: 换行 第一行在下方

3).justify-content属性

justify-content属性定义了项目在主轴(水平)上的对齐方式

.box {justify-content: flex-start | flex-end | center | space-between | space-around;
}
其可能去五个值,具体的对齐方式与轴的方向有关。下面假设主轴为从左往右。
flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

4).flex-flow

flex-flow是flex-direction属性与flex-wrap属性的简写形式,默认值为row nowrap

.box {flex-flow: <flex-direction> || <flex-wrap>;
}

5).align-items属性

align-items属性定义项目在交叉轴(垂直)上如何对齐。

.box {justify-content: flex-start | flex-end | center | space-between | space-around;
}
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。
flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

6).align-content属性

align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

.box {align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
该属性取的6个值:
flex-start:与交叉轴的起点对齐。
flex-end:与交叉轴的终点对齐。
center:与交叉轴的中点对齐。
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴。

7)其它

order: 该属性定义了项目的排列属性。数值越大,排列越靠前,默认为0.flex-grow:该属性定义了项目的放大比例,默认为0。即如果存在剩余空间,也不放大。
注:如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。flex-shrink:该属性定义项目的缩小比例,默认为1,即如果空间不足够,该项目会缩小。
注:如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。flex-basis:该属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。flex:该属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。align-self:align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch
.item {align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
注意:该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

19.flex布局原理

1) flex 是 flexible Box的缩写,意为“弹性布局”,用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为flex布局

当我们为父盒子设为flex布局以后,子元素的float、clear和vertical-align属性将失效
伸缩布局 = 弹性布局 = 伸缩盒布局 = 弹性盒布局 = flex布局

2)采用flex布局的元素,称为flex容器(flex container),简称“容器”。他的所有子元素自动成为容器成员,称为flex项目(flex item),简称“项目”。

  体验中span就是子容器flex项目。体验中div就是flex父容器。子容器可以横向排列也可以纵向排列。

3)总结: 就是通过给父盒子添加flex属性,来控制子盒子的位置和排列方式。

20.Px,rem,em的区别

Px,绝对长度单位,像素px是相对于显示器屏幕分辨率来说的

em 相对长度单位,相对于当前对象内文本的字体尺寸

 注意:  em的值并不是固定的em会继承父级元素的字体大小(参考物是父元素的font-size)em中所有的字体都是相对于父元素的大小决定的

rem 相对于html根元素的font-size

21.网页的三层结构

结构(html或xhtm标记语言)表现(css样式表)行为(js)

22.媒体查询

媒体指的就是各种设备 (移动设备, PC设备)查询指的是要检测属于哪种设备 媒体查询: 通过查询当前属于哪种设备, 让网页能够在不同的设备下正常的预览

学习媒体查询的核心是:

实现页面在不同设备下正常预览 [判断当前设备]

媒体类型

将不同的设备划分为不同的类型
all (所有的设备)print (打印设备)screen (电脑屏幕,平板电脑,智能手机)

23.Rem缺点

比如:小说网站,屏幕越小的移动设备如果用了rem肯定文字就越小,就会导致看文章的时候特别费眼

24.常见的兼容性一阶段内容自己可以在网上进行百度查阅

25.垂直与水平居中的方式

初始代码,后续居中样式在此基础上面修改添加

<style type="text/css">*{margin: 0;padding: 0;}.container{width: 500px;height: 300px;background-color: dodgerblue;/* 左右居中 */margin: auto;}.center{width: 100px;height: 100px;background-color: red;}</style><body><div class="container"><div class="center"></div></div></body>

1)块级元素 1.Flex 利用Flex来居中元素是常用的垂直水平居中方式之一,几行代码就能优雅地实现元素垂直水平完美居中,简单实用。

关键语句:
display: flex;(弹性盒子)
justify-content: center;(左右居中)
align-items: center;(垂直居中)
.container{width: 500px;height: 300px;background-color: dodgerblue;margin: auto;/* 添加样式 */display: flex;justify-content: center;align-items: center;}

2.display + margin

关键语句:
父元素display: flex;(弹性盒子)
子元素margin: auto;(上下左右居中)
注意:此方法只能完美居中一个子元素,如果子元素不止一个,则所有子元素垂直居中、左右均匀占据父容器所有空间
.container{width: 500px;height: 300px;background-color: xblue;margin: auto;/* 添加样式 */display: flex;}
.center{width: 100px;height: 100px;background-color: red;/* 添加样式 */margin: auto;}

3.table-cell/table-cell + display

关键语句:父元素display: table-cell;
vertical-align: middle;
子元素margin: auto;

(或)table-cell + display

关键语句:父元素display: table-cell;
vertical-align: middle;
text-align: center;
子元素display: inline-block;
   .songtao{width: 500px;height: 300px;background-color: dodgerblue;margin: auto;  /* 失效 *//* 添加样式 */display: table-cell;vertical-align: middle;}.center{width: 100px;height: 100px;background-color: red;/* 添加样式 */margin: auto;}

4.position + translate

关键语句:
父元素position: relative;
子元素position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
   .container {width: 500px;height: 300px;background-color: dodgerblue;margin: auto;/* 添加样式 */position: relative;}.center {width: 100px;height: 100px;background-color: red;/* 添加样式 */position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);}

5.position + margin

关键语句:
父元素position: relative;
子元素position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
   .container {width: 500px;height: 300px;background-color: dodgerblue;margin: auto;/* 添加样式 */position: relative;}.center {width: 100px;height: 100px;background-color: red;/* 添加样式 */position: absolute;top: 0;bottom: 0;left: 0;right: 0;margin: auto;}

6.position+负margin

关键语句:
父元素position: relative;
子元素position: absolute;
top:50%;
left:50%;
margin: -50px;
   .scontainer {width: 500px;height: 300px;background-color: dodgerblue;margin: auto;/* 添加样式 */position: relative;}.center {width: 100px;height: 100px;background-color: red;/* 添加样式 */position: absolute;top:50%;left:50%;/* 不是所有的都能简写 */margin: -50px;}

2)行级元素

初始代码,后续居中样式在此基础上面修改添加

   <style type="text/css">* {margin: 0;padding: 0;}.container {width: 500px;height: 300px;background-color: dodgerblue;margin: auto;/* 添加样式 */position: relative;}.center {width: 100px;height: 100px;background-color: red;}
</style>
<body><div class="container"><span class="center">焘焘不绝,努力变强!</span></div>
</body>

line-height + text-align

关键语句:
父元素 text-align: center;
子元素 line-height:父元素height;
   .container {width: 500px;height: 300px;background-color: dodgerblue;margin: auto;/* 添加样式 */text-align: center;}.center {width: 100px;height: 100px;background-color: red;/* 添加样式 */line-height: 300px;}

27.三栏布局方式(两侧宽度固定,中间宽度自适应的)

CSS公共样式:

* {padding: 0;margin: 0;height: 100%;
}.left {width: 200px;background-color: aqua;
}.right {width: 200px;background-color: burlywood;
}.main {background-color: chartreuse;
}

  1. 浮动布局 左右模块各自向左右浮动,并设置中间模块的 margin 值使中间模块宽度自适应

  • 优点:简单易懂

  • 缺点:主要内容无法最先加载,当页面内容较多时会影响用户体验

<boby><style>.left {float: left;}.right {float: right;}.main {margin: 0 200px;}
</style><div class="left">Left</div><div class="right">Right</div><div class="main">Main</div>
</boby>
  1. 定位布局

  • 优点:简单易懂,并且主要内容可以优先加载

  • 缺点:容器脱离了文档流,高度未知的时候,会有问题

 <boby><style>.left,.right {position: absolute;top: 0;}
.left {left: 0;}.right {right: 0;}.main {margin: 0 200px;}</style><!-- 可以把Main提前,使主要内容可以优先加载 --><div class="main">Main</div><div class="left">Left</div><div class="right">Right</div>
</body>
  1. flex布局

  • 优点:简单实用,未来的趋势

  • 缺点:需要考虑浏览器的兼容性

<body><style>.container {display: flex;}.main {flex: 1;/* flex: 1 1 auto; */}</style><div class="container"><div class="left">Left</div><div class="main">Main</div><div class="right">Right</div></div>
</body>

4.表格布局

  • 优点:兼容性很好,当内容溢出时会自动撑开父元素

  • 缺点:seo不友好

<body><style>.container {display: table;width: 100%;}.container>div {display: table-cell;}</style><div class="container"><div class="left">Left</div><div class="main">Main</div><div class="right">Right</div></div>
</body>

5.table布局

  • 优点:简单易懂

  • 缺点:主要内容无法最先加载,当页面内容较多时会影响用户体验<body>

<body><style>.container {display: grid;width: 100%;grid-template-columns: 200px auto 200px;}</style><div class="container"><div class="left">Left</div><div class="main">Main</div><div class="right">Right</div></div>
</body>

28.Doctype作用

声明文档类型

JavaScript相关

1.Js基本数据类型有哪些

​​​​​​


字符串String 数值值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
number,string,boolean,null,undefined,symbol以及未来ES10新增的BigInt(任意精度整数)七类。
引用数据类型:对象(Object)、数组(Array)、函数(Function)。
注:Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值

2.Ajax如何使用

1)什么是Ajax?

Ajax:即异步 JavaScript 和XML。Ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。而传统的网页(不使用 Ajax)如果需要更新内容,必需重载整个网页面。

2)同步与异步的区别

同步提交:当用户发送请求时,当前页面不可以使用,服务器响应页面到客户端,响应完成,用户才可以使用页面。

异步提交:当用户发送请求时,当前页面还可以继续使用,当异步请求的数据响应给页面,页面把数据显示出来 。

3)ajax的工作原理

客户端发送请求,请求交给xhr,xhr把请求提交给服务,服务器进行业务处理,服务器响应数据交给xhr对象,xhr对象接收数据,由javascript把数据写到页面上,如下图所示:

4)实现AJAX的基本步骤

要完整实现一个AJAX异步调用和局部刷新,通常需要以下几个步骤:1.创建XMLHttpRequest对象,即创建一个异步调用对象.
2.创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
3.设置响应HTTP请求状态变化的函数.
4.发送HTTP请求.
5.获取异步调用返回的数据.
6.使用JavaScript和DOM实现局部刷新.
注意:具体的相关步骤请自行查阅相关文档及网页。

3.如何判断一个数字是NaN

NaN是非数字,但是用typeof检测是number类型

1.利用NaN的定义  用typeof判断是否为number类型并且判断是否满足isnan
2.利用NaN是唯一一个不等于任何自身的特点 n!==n
3.利用ES6中提供的Object.is()方法(判断两个值是否相等)  n==nan

4.Js中null与undefined区别

相同点:用if判断时,两者都会被转换成false
不同点:number转换的值不同。    number(null)为0   number(undefined)为NaN

Null表示一个值被定义了,但是这个值是空值

Undefined 变量声明但未赋值

5.闭包是什么?有什么特性?对页面有什么影响

闭包可以简单理解成:定义在一个函数内部的函数。其中一个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

以下情况下会产生闭包

1.函数作为参数被传递
2.函数作为返回值被传递

特点:

1.函数嵌套函数。
2.函数内部可以引用外部的参数和变量。
3.参数和变量不会被垃圾回收机制回收。

使用:

1.读取函数内部的变量;
2.这些变量的值始终保持在内存中,不会在外层函数调用后被自动清除。

优点:

1:变量长期驻扎在内存中;
2:避免全局变量的污染;
3:私有成员的存在 ;

缺点:会造成内存泄露

6.js中常见的内存泄漏

什么是内存泄露?

本质上,内存泄露可以定义为:应用程序不再需要占用内存的时候,由于某些原因,内存没有被操作系统或可用内存池回收。编程语言管理内存的方式各不相 同。只有开发者最清楚哪些内存不需要了,操作系统可以回收。一些编程语言提供了语言特性,可以帮助开发者做此类事情。另一些则寄希望于开发者对内存是否需要清晰明了。

1.意外的全局变量
2.被遗忘的计时器或回调函数
3.脱离DOM的引用
4.闭包(具体泄漏情况查阅相关文档)

7.事件委托是什么?如何确定事件源

(Event target 谁调用 谁就是事件源)

JS高程上讲:事件委托就是利用事件冒泡(事件开始时由最具体的元素接受,然后逐级向上传播到Dom最顶层节点的过程),只制定一个时间处理程序,就可以管理某一类型的所有事件。

事件代理(event delegation):事件代理又称事件委托,是javaScript中绑定事件的常用技巧。顾名思义,‘事件代理’就是把原本需要绑定的事件委托给父元素,让父元素负责事件监听。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能。

现在有一个需求:点击li添加背景颜色,并排他,点哪个哪个有背景颜色

<head>
<style>*{    margin: 0;padding: 0;}ul{list-style: none;width: 400px;border: 1px solid #000;margin: 100px auto;}li{width: 100%;height: 50px;border-bottom: 1px solid #000;box-sizing: border-box;}.selected{background-color: red;}
</style>
<script>//一般做法let oItems = document.querySelectorAll('li');let currentItem = oItems[0];for (let item of oItems){// item.onclick = change;item.onclick = function () {currentItem.className = '';this.className = 'selected';currentItem = this;}}
</script>
</head>
<boby>
<ul><li class="selected">1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li>
</ul>
</boby>

改良版:

let oItems = document.querySelectorAll('li');let currentItem = oItems[0];for (let item of oItems){item.onclick = change;//一定不要写成了item.onclick = change();}function change() {currentItem.className = '';this.className = 'selected';currentItem = this;}

事件委托的做法:监听ul的点击,而不是直接监听li的点击,li将事件冒泡到它的父元素ul,再通过事件对象拿到当前被点击的元素

let oUl = document.querySelector('ul');let oLi = document.querySelector('.selected');oUl.onclick = function (event) {event = event || window.event;//兼容所有浏览器oLi.className = '';let item = event.target;//event.target为当前点击的liitem.className = 'selected';oLi = item;}

事件捕获:由最顶层的节点开始,然后逐级向下传播到最具体的元素接受过程

事件委托的好处

1.减少事件数量,提高性能
2.预测未来元素,新添加的元素仍然可以触发该事件
3.避免内存外泄,在低版本的IE中,防止删除元素而没有移除事件而造成的内存溢出

8.什么是事件冒泡?

一个事件触发后,会在子元素和父元素之间传播,这种传播分为三个阶段,
捕获阶段(从window对象传导到目标节点(从外到里),这个阶段不会响应任何事件)。
目标阶段,(在目标节点上触发),冒泡阶段(从目标节点传导回window对象(从里到外))。
事件委托/事件代理就是利用事件冒泡的机制把里层需要响应的事件绑定到外层

事件冒泡就是事件从dom树的底层 层层向上传递,直到传递到dom树的根节点

9.本地存储与cookie的区别?

Cookie 是小甜饼的意思。顾名思义,cookie 确实非常小,它的大小限制为4KB左右。它的主要用途有保存登录信息,比如你登录某个网站市场可以看到“记住密码”,这通常就是通过在 Cookie 中存入一段辨别用户身份的数据来实现的。localStorage 是 HTML5 标准中新加入的技术,它并不是什么划时代的新东西。早在 IE 6 时代,就有一个叫 userData 的东西用于本地存储,而当时考虑到浏览器兼容性,更通用的方案是使用 Flash。而如今,localStorage 被大多数浏览器所支持,如果你的网站需要支持 IE6+,那以 userData 作为你方案是种不错的选择。sessionStorage
sessionStorage 与 localStorage 的接口类似,但保存数据的生命周期与 localStorage 不同。做过后端开发的同学应该知道 Session 这个词的意思,直译过来是“会话”。而 sessionStorage 是一个前端的概念,它只是可以将一部分数据在当前会话中保存下来,刷新页面数据依旧存在。但当页面关闭后,sessionStorage 中的数据就会被清空。
特性 COOKIE LOCALSTORAGE SESSIONSTORAGE
数据的生命期 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 除非被清除,否则永久保存 仅在当前会话下有效,关闭页面或浏览器后被清除
存放数据大小 4k左右 一般为5MB 一般为5MB
与服务器端通信 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 仅在客户端(即浏览器)中保存,不参与和服务器的通信 与localstorage相同
易用性 需要程序员自己封装,源生的Cookie接口不友好 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 与localstorage相同

10.ES6新特性

const和let、模板字符串、箭头函数、函数的参数默认值、对象和数组解构、for...of 和 for...in、ES6中的类等等。

注意:具体详情查阅相关文档

11.Let与var与const的区别

let、const声明的变量仅在块级作用域内有效,var 声明变量是全局的,没有块级作用域功能let 、const 不存在变量提升 , var 存在变量提升let 、const在同一块作用域内不能重复声明变量,var 可以重复声明

1.const声明一个只读的常量。一旦声明,常量的值就不能改变,而且必须初始化。

const与let下面特点一样,但是也有不同点,let声明的是变量,const声明的是常量,只读,修改值会报错,const保存的是内存地址,可以给对象或数组添加属性或元素,但是不能重新复写。

const b = 2;//正确
// const b;//错误,必须初始化
console.log('函数外const定义b:' + b);//有输出值
// b = 5;
// console.log('函数外修改const定义b:' + b);//无法输出

2.var定义的变量可以修改,如果不初始化会输出undefined,不会报错

(var在函数内命名的变量是只在整个函数作用域内起作用,出了这个函数作用域就不能用了)

 var a = 1;// var a;//不会报错console.log('函数外var定义a:' + a);//可以输出a=1function change(){a = 4;console.log('函数内var定义a:' + a);//可以输出a=4} change();console.log('函数调用后var定义a为函数内部修改值:' + a);//可以输出a=4

3.let (ES6新增的命令,用来声明变量)是块级作用域,函数内部使用let定义后,对函数外部没有影响(即只在自己所在的块级作用域内起作用 其它都会报错 未定义)

(let不像var那样会发生“变量提升”现象。所以,变量一定要在声明后使用,否则报错。)变量arg1用var命令声明,会发生变量提升,即脚本开始运行时,变量arg1已经存在了,但是没有值,所以会输出undefined。
变量arg2用let命令声明,不会发生变量提升。这表示在声明它之前,变量arg2是不存在的,这时如果用到它,就会抛出一个错误。
 let c = 3;console.log('函数外let定义c:' + c);//输出c=3function change(){let c = 6;console.log('函数内let定义c:' + c);//输出c=6} change();console.log('函数调用后let定义c不受函数内部定义影响:' + c);//输出c=3

12.数组方法有哪些?请阐述。

push() : 从后面添加元素,返回值为添加完后的数组的长度arr.pop() : 从后面删除元素,只能是一个,返回值是删除的元素arr.shift() : 从前面删除元素,只能删除一个 返回值是删除的元素arr.unshift() : 从前面添加元素, 返回值是添加完后的数组的长度arr.splice(i,n) : 删除从i(索引值)开始之后的那个元素。返回值是删除的元素arr.concat() : 连接两个数组 返回值为连接后的新数组str.split() : 将字符串转化为数组arr.sort() : 将数组进行排序,返回值是排好的数组,默认是按照最左边的数字进行排序,不是按照数字大小排序的arr.reverse() : 将数组反转,返回值是反转后的数组arr.slice(start,end) : 切去索引值start到索引值end的数组,不包含end索引的值,返回值是切出来的数组arr.forEach(callback) : 遍历数组,无return  即使有return,也不会返回任何值,并且会影响原来的数组arr.map(callback) : 映射数组(遍历数组),有return 返回一个新数组 。arr.filter(callback) : 过滤数组,返回一个满足要求的数组(具体方法请查阅相关文档)

13.json如何新增/删除指定的元素

//-- json删除指定的元素:
var a = {
name: 'jackson'
age: 20
}
console.log(Object.keys(a))
delete a["name"]
console.log(Object.keys(a))//--     json新增元素
a["newAttr"] = "newValue"
console.log(Object.keys(a))

运行结果:

14.什么是面向对象?请阐述

面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想是将数据作为第一位,这是对数据一种优化,操作起来更加的方便,简化了过程。Js本身是没有class类型的,但是每个函数都有一个prototype属性,prototype指向一个对象,当函数作为构造函数时,prototype就起到类似于class的作用面向对象有三个特点: 封装(隐藏对象的属性和实现细节,对外提供公共访问方式),继承(提高代码复用性,继承是多态的前提),多态(是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象)。

15,普通函数与构造函数的区别?

1.构造函数也是一个普通函数,创建方式和普通函数一样,但是构造函数习惯上首字母大写2.调用方式不一样,普通函数直接调用,构造函数要用关键字new来调用a. 普通函数的调用方式:直接调用 person();b.构造函数的调用方式:需要使用new关键字来调用 new Person();3.调用时,构造函数内部会创建一个新对象,就是实例,普通函数不会创建新对象4.构造函数内部的this指向实例,普通函数内部的this指向调用函数的对象(如果没有对象调用,默认为window)
function Person(name,job,age)
{this.name=name;this.job=job;this.age=age;this.sayHi=function(){alert("Hi")}} 5.构造函数默认的返回值是创建的对象(也就是实例),普通函数的返回值由return语句决定6.构造函数的函数名与类名相同Person( ) 这个构造函数,Person 既是函数名,也是这个对象的类名7.构造函数的执行流程A、立刻在堆内存中创建一个新的对象B、将新建的对象设置为函数中的thisC、逐个执行函数中的代码D、将新建的对象作为返回值

16.请简述原型 /原型链/(原型继承)

  任何对象实例都有一个原型,也叫原型对象,这个原型对象由对象的内置属性_proto_指向它的构造函数的prototype指向的对象,即任何对象都是由一个构造函数创建的,但是不是每一个对象都有prototype,只有方法才有prototype。什么是原型链?原型链基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。我们知道,每个构造函数都有一个原型对象,每个原型对象都有一个指向构造函数的指针,而实例又包涵一个指向原型对象的内部指针。原型链的核心就是依赖对象的_proto_的指向,当自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至到Object时,就没有_proto_指向了。
因为_proto_实质找的是prototype,所以我们只要找这个链条上的构造函数的prototype。其中Object.prototype是没有_proto_属性的,它==null。每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含指向原型对象内部的指针。我们让原型对象(1)等于另一个原型对象的实例(2),  此时原型对象(2)将包含一个指向原型对象(1)的指针,
再让原型对象(2)的实例等于原型对象(3),如此层层递进就构成了实例和原型的链条,这就是原型链的概念每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数想指针(constructor),而实例对象都包含一个指向原型对象的内部指针(__proto__)。如果让原型对象等于另一个原型对象的实例,此时的原型对象将包含一个指向另一个原型的指针(__proto__),另一个原型也包含着一个指向另一个构造函数的指针(constructor)。假如另一个原型又是另一个类型的实例……这就构成了实例与原型的链条。也叫原型链。原型继承是js的一种继承方式,原型链作为实现继承的主要方法,其基本思路是利用原型让一个引用类型继承另一个引用类型的属性和方法。
原型继承:利用原型中的成员可以被和其相关的对象共享这一特性,可以实现继承,这种实现继承的方式,就叫做原型继承.

17.谈一谈你对Promise理解

关于promise面试大概问题(有可能会问一些其它的,多记一点,稳一点):知道Promise嘛?聊聊对Promise的理解?(说了一下Promise对象代表一个异步操作,有三种状态,状态转变为单向...)那它是为了解决什么问题的?(emmm当异步返回值又需要等待另一个异步就会嵌套回调,Promise可以解决这个回调地狱问题)那它是如何解决回调地狱的?(Promise对象内部是同步的,内部得到内部值后进行调用.then的异步操作,可以一直.then .then ...)好,你说可以一直.then .then ...那它是如何实现一直.then 的?(emmm... 这个.then链式调用就是...额这个...)Promise有哪些方法 all和race区别是什么具体说一下 .catch() 和 reject  ()

1)什么是Promise?

Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,用它来传递异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。 promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);且Promsie必须为这三种状态之一,状态一旦改变,任何其他的操作都无法改变这个状态。创造promise实例后,它会立即执行。

注意:状态只能由 Pending 变为 Fulfiled 或由 Pending 变为 Rejected,且状态发生改变之后,会一直保持着这个状态。

var promiseExample =  new Pormise (function (resolve, reject) {//..some codeif(/*异步操作成功*/) {resolve(value)}else{reject(error)}
})class Promise{// 构造器constructor(executor){// 成功let resolve = () => { };// 失败let reject = () => { };// 立即执行executor(resolve, reject);}
}x

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们也是函数,由JS引擎提供,不用自己部署。

(1) resolve函数:将Promise对象的状态从“pending(进行中)”变成“Resolved(已完成)”。在异步操作成功时调用resolve函数,并将异步操作的相关结果作为参数传递出去。比如上面代码resolve(value)中的value,就是传递出去的参数。

(2) reject函数:将Promise对象的状态从“pending(进行中)”变成“Rejected(已失败)”。在异步操作失败时调用reject函数,并将异步操作报出的错误(通常是Error对象的实例)作为参数传递出去。比如上面代码reject(error)中的error,就是传递出去的参数。

2)Promise用来解决的问题

回调的本质是将回调函数作为参数传递给另一个函数,当处理比较复杂的需求时,回调函数作为参数一层层嵌套,代码结构会非常庞大臃肿,代码维护难度极高,这就叫回调地狱。

promsie可以支持多个并发的请求,获取并发请求的数据

promise可以解决异步的问题,但本身不能说pormise是异步的

3)Promise基本用法

Promise状态只能在内部进行操作,内部操作在Promise执行器函数执行。Promise必须接受一个函数作为参数,我们称该函数为执行器函数,执行器函数又包含resolve和reject两个参数,它们是两个函数。

resolve: 将Promise对象的状态从 Pending(进行中) 变为 Fulfilled(已成功)

reject: 将Promise对象的状态从 Pending(进行中) 变为 Rejected(已失败),并抛出错误。

4)Promise如何解决回调地狱问题

(1)Promise实现了链式调用(new Promise().then().then()),代码更优雅,可读性更高

(2)错误处理要好得多,所有错误都由块末尾的一个.catch块处理,而不是在“金字塔”的每一层单独处理。

(3)Promise.all实现了多个异步任务并发运行并为其结果创建承诺的功能

注意:被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数。同步回调:回调函数立即执行      异步回调:须等某个异步操作完成后,才执行回调函数。

18.请简述async的用法

Async就是generation和promise的语法糖,async就是将generator的*换成async,将yiled换成await

用同步方式执行异步操作

函数前必须加一个async,异步操作方法前加一个await关键字,意思就是等一下,执行完了再继续走,注意:await只能在async函数中运行,否则会报错

Promise如果返回的是一个错误的结果,如果没有做异常处理,就会报错,所以用try..catch捕获一下异常就可以了

19.一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?

1. 当发送一个 URL 请求时,不管这个 URL 是 Web 页面的 URL 还是 Web 页面上每个资源的 URL,浏览器都会开启一个线程来处理这个请求,同时在远程 DNS 服务器上启动一个 DNS 查询。这能使浏览器获得请求对应的 IP 地址。2. 浏览器与远程 Web 服务器通过 TCP 三次握手协商来建立一个 TCP/IP 连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,然后服务器响应并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。3. 一旦 TCP/IP 连接建立,浏览器会通过该连接向远程服务器发送 HTTP 的 GET 请求。远程服务器找到资源并使用 HTTP 响应返回该资源4. 此时,Web 服务器提供资源服务,客户端开始下载资源

其它相关问题

1.css预处理是什么? sass 和 less又是什么? 为什么使用它们

1)什么是css预处理器

CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。

通俗的说,“CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题”,例如你可以在 CSS 中使用变量、简单的逻辑程序、函数(如右侧代码编辑器中就使用了变量$color)等等在编程语言中的一些基本特性,可以让你的 CSS 更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。

2)css预处理器的作用

  • 帮助更好地组织CSS代码

  • 提高代码复用率

  • 提升可维护性

Sass和less都是css预处理器,是css上的一种抽象层,是一种特殊的语法,最终会编译成css,less是一种动态样式语言,给css赋予了动态语言的特性,比如:变量,继承,嵌套。Less既可以在客户端运行,在可以在服务端运行(需要借助node)

3.Js继承方法(prototype、call、apply)

js的原型继承--prototype

1)什么是prototype?

js中,俗话说“一切皆对象”。用new 出来的都是函数对象;否则就是普通对象

函数对象都有prototype(原型对象);而普通对象则只有__proto__(原型指针)

函数对象的一个特点:可以实现不同类之间的方法继承

函数的子类可以共享父类的方法,而父类不能想用子类的方法

注:具体使用方法查阅相关文档

2)apply()、call()方法的继承

obj.call(thisObj, arg1, arg2, ...);
obj.apply(thisObj, [arg1, arg2, ...]);

obj是父级,thisObj是子级;第二个参数apply可以接收一个数组,而call只能是每项逐个接收。

apply和call 本来就是为了扩展函数的作用域而生的,换句话说就是为了改变this的指向存在的。

当一个object没有某种方法,但是其他的有,我们可以借助call和apply来用其他对象的方法来做操作,也可以传参数。

apply:调用一个对象的一个方法,用另一个对象替换当前对象。

call:调用一个对象的一个方法,用另一个对象替换当前对象。

从定义中可以看出,call和apply都是调用一个对象的一个方法,用另一个对象替换当前对象。而不同之处在于传递的参数,apply最多只能有两个参数——新this对象和一个数组argArray,如果arg不是数组则会报错相同点:两个方法产生的作用是完全一样的。call, apply作用就是借用别人的方法来调用,就像调用自己的一样.
不同点:方法传递的参数不同

3.为什么会造成跨域/请简述同源策略

浏览器的同源策略导致了跨域,感觉就是浏览器在搞事情。嗯嗯,浏览器为什么要搞事情呢?是不想给好日子我们过?对于这样的质问,浏览器甩锅道:“同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。”这么官方的话术真难懂,

1)首先,我们先了解一下什么是浏览器的同源策略

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。它是浏览器最核心也是最基本的安全功能。

同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

origin又是什么呢?

Web内容的源由用于访问它的URL的方案(协议),主机(域名)和端口定义。只有当方案(协议),主机和端口都匹配时,两个对象具有相同的起源。某些操作仅限于同源内容,而可以使用 CORS(Cross-origin resource sharing) “跨域资源共享” 解除这个限制。

所谓同源是指域名(主机名或者IP地址)、端口、协议相同。不同的客户端脚本(JavaScriptActionScript)在没明确授权的情况下,浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。

如果两个 URL 的 protocolport (en-US) (如果有指定的话)和 host都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。

同源与不同源的例子:

不同源的例子:
1. 域名(主机名或者IP地址)不同
http://news.company.com/index.html与http://www.company.com/index.html不同源,域名不同,news子域与www子域不同。
http://company.com/index.html与http://www.company.com/index.html 不同源,域名不同,顶级域与www子域不是一个概念。
2. 端口不同
http://www.company.com:8080/index.html与
http://www.company.com/index.html不同源,端口不同,8080与默认的80端口不同。
3. 协议不同
https://www.company.com/index.html与
http://www.company.com/index.html 不同源,协议不同,https与http是不同协议。同源的例子:
http://www.company.com/a/c/index.html与
http://www.company.com/b/d/index.html 属于同源,域名,端口,协议均相同。

2)跨域的产生

在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题。在请求的过程中我们要想回去数据一般都是post/get请求,所以..跨域问题出现

跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号(如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。

3)常见跨域场景

当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。常见跨域场景如下图所示:

**如果是协议和端口造成

1.如果是协议和端口造成的跨域问题“前台”是无能为力的。
2.在跨域问题上,仅仅是通过“URL的首部”来识别而不会根据域名对应的IP地址是否相同来判断。“URL的首部”可以理解为“协议, 域名和端口必须匹配”。

这里你或许有个疑问:请求跨域了,那么请求到底发出去没有?

跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了

4.Web前端性能优化-如何提高页面加载速度

1. 优化图片 图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方) 2. 减少HTTP的请求3. 优化CSS(压缩合并css,如 margin-top, margin-left...) 避免css表达式4. 网址后加斜杠(如www.campr.com/目录,会判断这个目录是什么文件类型,或者是目录。)  cdn(内容发布网络)托管5. 标明高度和宽度(如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了) 6. 将样式放在头部,将脚本放在底部 或使用外部的JavaScript和CSS

5.什么是懒加载和预加载

1.懒加载

1)什么是懒加载

懒加载也叫延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。用户滚动到它们之前,可视区域外的图像不会加载。这与图像预加载相反,在长网页上使用延迟加载将使网页加载更快。在某些情况下,它还可以帮助减少服务器负载。常适用图片很多,页面很长的电商网站场景中。

2)为什么要使用懒加载(懒加载的优点)

  • 能提升用户的体验,不妨设想下,用户打开像手机淘宝长页面的时候,如果页面上所有的图片都需要加载,由于图片数目较大,等待时间很长,用户难免会心生抱怨,这就严重影响用户体验。

  • 减少无效资源的加载,这样能明显减少了服务器的压力和流量,也能够减小浏览器的负担。

  • 防止并发加载的资源过多会阻塞js的加载,影响网站的正常使用。

3)懒加载实现的原理

首先将页面上的图片的 src 属性设为空字符串,而图片的真实路径则设置在data-original属性中, 当页面滚动的时候需要去监听scroll事件,在scroll事件的回调中,判断我们的懒加载的图片是否进入可视区域,如果图片在可视区内将图片的 src 属性设置为data-original 的值,这样就可以实现延迟加载。

代码实现

//懒加载代码实现
var viewHeight = document.documentElement.clientHeight // 可视区域的高度function lazyload () {// 获取所有要进行懒加载的图片var eles = document.querySelectorAll('img[data-original][lazyload]')Array.prototype.forEach.call(eles, function (item, index) {var rectif (item.dataset.original === '')returnrect = item.getBoundingClientRect()// 图片一进入可视区,动态加载if (rect.bottom >= 0 && rect.top < viewHeight) {!function () {var img = new Image()img.src = item.dataset.originalimg.onload = function () {item.src = img.src}item.removeAttribute('data-original')item.removeAttribute('lazyload')}()}})
}
// 首屏要人为的调用,否则刚进入页面不显示图片
lazyload()document.addEventListener('scroll', lazyload)

2.预加载

1)什么是预加载

资源预加载是另一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到。预加载简单来说就是将所有所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。

2)为什么要用预加载

在网页全部加载之前,对一些主要内容进行加载,以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,直到所有内容加载完毕。

预加载的核心要点如下:
1.图片等静态资源在使用之前的提前请求;
2.资源后续使用时可以从缓存中加载,提升用户体验;
3.页面展示的依赖关系维护(必需的资源加载完才可以展示页面,防止白屏等);实现预加载主要有三个方法:
1.html中img标签最初设置为display:none;
2.js脚本中使用image对象动态创建好图片;
3.使用XMLHttpRequest对象可以更加精细的控制预加载过程,缺点是无法跨域:

3.两者的对比

两者都是提高页面性能有效的办法,

两者主要区别是一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。

6.this指向及改变它的指向方法

在JavaScript中,this通常指向的是我们正在执行的函数本身,或者是,指向该函数所属的对象。

全局的this → 指向的是Window 直接通过函数调用的方式打印出来的 this指向的是全局变量Window

对象中的this → 指向其本身 通过new的方式调用的函数当做为构造函数,为了能够创建一个实例对对象,它的 this值指向生成的实例对象。

事件中this → 指向事件对象

1、this指向情况:

1)作为对象的方法调用

当函数作为对象的方法被调用时,this指向该对象

var obj = {a: 'yuguang',getName: function(){console.log(this === obj);console.log(this.a);}
};obj.getName(); // true yuguang

2)作为普通函数调用

当函数不作为对象的属性被调用,而是以普通函数的方式,this总是指向全局对象(在浏览器中,通常是Window对象)

window.name = 'yuguang';
var getName = function(){console.log(this.name);
};
getName(); // yuguangwindow.name = '老王'
var obj = {name: 'yuguang',getName: function(){console.log(this.name);}
};
var getNew = obj.getName;
getNew(); // 老王

3)构造器调用

除了一些内置函数,大部分Js中的函数都可以成为构造器,它们与普通函数没什么不同

构造器普通函数的区别在于被调用的方式 当new运算符调用函数时,总是返回一个对象,this通常也指向这个对象

var MyClass = function(){this.name = 'yuguang';
}
var obj = new MyClass();
obj.name; // yuguang

但是,如果显示的返回了一个object对象,那么此次运算结果最终会返回这个对象。

var MyClass = function () {this.name = 1;return {name: 2}
}
var myClass = new MyClass();
console.log('myClass:', myClass); // { name: 2}

只要构造器不显示的返回任何数据,或者返回非对象类型的数据,就不会造成上述问题。

4)call或apply调用

跟普通的函数调用相比,用callapply可以动态的改变函数的this

var obj1 = {name: 1,getName: function (num = '') {return this.name + num;}
};var obj2 = {name: 2,
};
// 可以理解成在 obj2的作用域下调用了 obj1.getName()函数
console.log(obj1.getName()); // 1
console.log(obj1.getName.call(obj2, 2)); // 2 + 2 = 4
console.log(obj1.getName.apply(obj2, [2])); // 2 + 2 = 4

5)箭头函数

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。

因此,在下面的代码中,传递给getVal函数内的this并不是调用者自身,而是外部的this~

this.val = 2;
var obj = {val: 1,getVal: () => {console.log(this.val);}
}
obj.getVal(); // 2

2、this指向的改变

this的可以指向不同的对象

1)call方法

function print(){console.log('name:' + this.name)console.log(arguments) //输出传入的参数
}
//对象
var obj = {name: 'xiaolu',age: 21
}
//调用call
print.call(obj, 1,2,3)

2)apply方法

function print() {console.log('name:' + this.name)console.log(arguments) //传出输入的参数
}
//对象
var obj = {name: 'xiaolu',age: 21
}
//调用 apply
print.apply(obj, [1,2,3])

call方法和apply方法这二者输出的值是相同的。那二者之间又有什么区别吗

3)bind方法

function print() {console.log('name:' + this.name)console.log(arguments) //传出输入的参数
}
//对象
var obj = {name: 'xiaolu',age: 21
}
//调用bind方法
var fn1 = print.bind(obj, 1,2,3)
var fn2 = print.bind(obj, [1,2,3])
fn1();
fn2();

**相同之处:这三者都能改变this指向,第一个传递的参数都是this指向的对象,三者都是采用后续传参的形式**

不同之处:1.call的传参是单个传递的,而 apply后续传递的参数是数组形式,而 bind没有规定,传递值和数组都可以。 2.call和 apply函数的执行是直接执行的,而 bind函数会返回一个函数,然后我们想要调用的时候才会执行。

7.什么是jsonp工作原理是什么?jsonp与ajax又有什么联系呢

**JSONP全称 JSON with Padding,是解决跨域的一种办法。**

Js跨域请求数据是不可以的,但是js跨域请求js脚本是可以的,所以可以把要请求的数据封装成一个js语句,做一个方法的调用。跨域请求js脚本可以得到此脚本。得到js脚本之后会立即执行。可以把数据做为参数传递到方法中。就可以获得数据。从而解决跨域问题。

JSONP原理:(动态创建script标签,回调函数) 浏览器在js请求中,是允许通过script标签的src跨域请求,可以在请求的结果中添加回调方法名,在请求页面中定义方法,就可获取到跨域请求的数据。

jsonp与 ajax又有什么差异呢?

1、ajax和jsonp这两种技术在调用方式上"看起来"很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;

2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。

3、所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。

4、jsonp是一种方式或者说非强制协议,如同ajax一样,它也不一定非要json格式来传递数据,如果你愿意,字符换也行,只不过这样不利于jsonp提供公开服务。

8.数组去重的方式

使用indexof()方法 使用lastindexof()方法 和indexof方法一样 indexof从头部开始匹配 lastindexof从尾部匹配 ES6的set结构 set不接受重复数据 使用sort方法先将原数组排序,然后与相邻的比较,如果不同则存入新数组 使用filiter和indexof方法 使用ES6 的set和扩展运算符 使用set和Array.from()方法 array.from可以将set结构转成数组 用splice和双层循环 使用includes方法 具体情况查阅相关文档

9.深拷贝与浅拷贝

基本类型 & 引用类型

ECMAScript中的数据类型可分为两种:

  • 基本类型:undefined, null, Boolean, String, Number, Symbol

  • 引用类型:Object, Array, Date, Function, RegExp等

不同类型的存储方式:

  • 基本类型:基本类型值在内存中占据固定大小,保存在栈内存

  • 引用类型:引用类型的值是对象,保存在堆内存中,而栈内存存储的是对象的变量标识符以及对象在堆内存中的存储地址

不同类型的复制方式:

  • 基本类型:从一个变量向另外一个新变量复制基本类型的值,会创建这个值的一个副本,并将该副本复制给新变量

let foo = 1;
let bar = foo;
console.log(foo === bar); // -> true// 修改foo变量的值并不会影响bar变量的值
let foo = 233;
console.log(foo); // -> 233
console.log(bar); // -> 1
  • 引用类型:从一个变量向另一个新变量复制引用类型的值,其实复制的是指针,最终两个变量最终都指向同一个对象

let foo = {name: 'leeper',age: 20
}
let bar = foo;
console.log(foo === bar); // -> true// 改变foo变量的值会影响bar变量的值
foo.age = 19;
console.log(foo); // -> {name: 'leeper', age: 19}
console.log(bar); // -> {name: 'leeper', age: 19}

深拷贝 & 浅拷贝

  • 深拷贝:指针赋值,并且内容拷贝、

  • 浅拷贝:只是简单的指针赋值

  • 数组浅拷贝: 如果是数组,可以使用数组的一些方法实现:slice(),concat()返回一个新数组的特性实现拷贝。用扩展运算符spread实现

  • 数组深拷贝: JSON.parse(JSON.stringify())不仅适用于数组还适用于对象。不能拷贝函数,undefined,symbol。

10.为什么js是弱类型语言

弱类型语言实现相对于强类型语言来说的,在强类型语言中,变量类型有多种,比如int char float Boolean 不同类型相互转换有时需要强制转换,而jacascript只有一种类型var,为变量赋值时会自动判断类型并转换,所以是弱类型语言。

11.怎样转换less为css

使用node将less文件转化为css文件

12.echarts使用最多的是图表以及图标组合

13.for'循环,foeEach循环与map循环之间的差异

for循环是遍历数组最常用到的一种循环

map(数组方法):

特性:

  1. map不改变原数组但是会 返回新数组

  2. 可以使用break中断循环,可以使用return返回到外层函数

注意: Map方法不会对空数组进行检测,map会返回一个新数组,不会对原数组产生影响

forEach(数组方法):

特性:

  1. 便利的时候更加简洁,效率和for循环相同,不用关心集合下标的问题,减少了出错的概率。

  2. 没有返回值

  3. 不能使用break中断循环,不能使用return返回到外层函数

注意

  1. forEach() 对于空数组是不会执行回调函数的。

  2. for可以用continue跳过循环中的一个迭代,forEach用continue会报错。

  3. forEach() 需要用 return 跳过循环中的一个迭代,跳过之后会执行下一个迭代。

三者性能对比:

for 循环当然是最简单的,因为它没有任何额外的函数调用栈和上下文;

forEach 其次,因为它其实比我们想象得要复杂一些,它的函数签名实际上是array.forEach(function(currentValue, index, arr), thisValue)它不是普通的 for 循环的语法糖,还有诸多参数和上下文需要在执行的时候考虑进来,这里可能拖慢性能

map 最慢,因为它的返回值是一个等长的全新的数组,数组创建和赋值产生的性能开销很大。

14.类与继承

创建类:

  • 使用function和this关键字

  • 原型方法 用prototype和this关键字

  • 使用object.create()方法构造

  • 原型与原型链

继承:

  • 原型链继承

  • 借用构造函数继承

  • 拷贝继承

  • 组合继承

  • 原型式继承

  • 寄生式继承

  • 寄生组合式继承

详细概念请查阅相关文档

15.同步与异步/阻塞与非阻塞的区别

同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)

同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作。这时程序是阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。 因此 简单的说,同步就是必须一件一件事做,等前一件做完了才能做下一件事。

异步,与同步相对,当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作。当这个调用完成后,一般通过状态、通知和回调来通知调用者。

阻塞和非阻塞关注的是*程序在等待调用结果(消息,返回值)时的状态*.

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

16.重绘与回流是什么

在讨论重绘与回流之前,我们要知道:

  1. 浏览器使用流式布局模型 (Flow Based Layout)。

  2. 浏览器会把HTML解析成DOM,把CSS解析成CSSOMDOMCSSOM合并就产生了Render Tree

  3. 有了Render Tree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上。

  4. 由于浏览器使用流式布局,对Render Tree的计算通常只需要遍历一次就可以完成,但table及其内部元素除外,他们可能需要多次计算,通常要花3倍于同等元素的时间,这也是为什么要避免使用table布局的原因之一。

一句话:回流必将引起重绘,重绘不一定会引起回流。

回流(Reflow):当Render tree中的一部分或者全部因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,这就叫回流,每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候一定会发生回流,因为要构建Render tree

在回流的时候,浏览器会使渲染树中收到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,这就是重绘(Repaint)

Render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,不会影响布局,就叫重绘

17.http和https是什么?有什么特点

什么是HTTP?

超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法。

什么是HTTPS?

《图解HTTP》这本书中曾提过HTTPS是身披SSL外壳的HTTP。HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。

PS:TLS是传输层加密协议,前身是SSL协议,由网景公司1995年发布,有时候两者不区分。

HTTP VS HTTPSx

HTTP特点:

  • 无状态:协议对客户端没有状态存储,对事物处理没有“记忆”能力,比如访问一个网站需要反复进行登录操作

  • 无连接:HTTP/1.1之前,由于无状态特点,每次请求需要通过TCP三次握手四次挥手,和服务器重新建立连接。比如某个客户机在短时间多次请求同一个资源,服务器并不能区别是否已经响应过用户的请求,所以每次需要重新响应请求,需要耗费不必要的时间和流量。

  • 基于请求和响应:基本的特性,由客户端发起请求,服务端响应

  • 简单快速、灵活

  • 通信使用明文、请求和响应不会对通信方进行确认、无法保护数据的完整性

HTTPS(基于HTTP协议,通过SSL或TLS提供加密处理数据,验证对方身份以及数据完整性保护)特点:

  • 内容加密:采用混合加密技术,中间者无法直接查看明文内容

  • 验证身份:通过证书认证客户端访问的是自己的服务器

  • 保护数据完整性:防止传输的内容被中间人冒充或者篡改

18.箭头函数与普通函数的区别

  • 箭头函数语法更加简洁,清晰

  • 箭头函数没有prototype(原型),所以箭头函数本身没有this

  • 箭头函数不会创建this,会捕获其所在的上下文的this值,作为自己的this值

  • call | apply | bind 无法改变箭头函数中的this的指向

  • 箭头函数不能作为构造函数使用

  • 箭头函数不能绑定arguments,取而代之是用rest参数...代替arguments对象,来访问箭头函数的参数列表

  • 箭头函数不能作为generator函数,不能使用yield关键字

19.原型和继承,prototype,call和apply继承的区别(第一个参数是相同的,第二个的区别在哪)

JavaScript 中没有类的概念的,主要通过原型链来实现继承。通常情况下,继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联(原型对象指针),这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。

说起原型则离不开构造函数

构造函数分为 实例成员 和 静态成员

实例成员就是在构造函数内部,通过this添加的成员。实例成员只能通过实例化的对象来进行访问

在构造函数本身上添加的成员,只能通过构造函数来访问

通过构造函数创建对象,该过程也称为实例化

在javascript里面,对象都有一个隐藏对象 “[[Prototype]]”, 获取该对象可以通过 target.__proto__Object.getPrototype(target) 拿到。该对象就是我们说的原型对象。该对象可以用来存放一些数据和方法

继承是面向对象软件技术当中的一个概念,与多态、封装共为面向对象的三个基本特征。继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。

apply()接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。

call()方法第一个参数与apply()方法相同,但传递给函数的参数必须列举出来。

20.什么是js内存泄漏

**内存泄漏是指一块被分配的内存既不能使用又不能回收,直到浏览器进程结束**

内存溢出一般是内存泄漏造成的,占用的内存不需要用到了但是没有及时释放,内存泄漏积累的多了轻的话影响系统性能,严重直接引起内存溢出系统崩溃。

操作可能会导致内存泄漏的几个因素:

  • 全局变量引起的内存泄漏:根据JavaScript的垃圾回收机制我们知道,全局变量是不会被回收的,所以一些意外的、不需要的全局变量多了,没有释放,就造成了内存泄漏。

  • 闭包:闭包其实也是跟全局变量挂钩了,但是闭包只是因为被全局变量引用了,内部的变量因为被闭包引用得不到释放,也会造成内存泄漏。

  • 计时器、回调、监听等事件没有移除:计时器、回调、事件监听等没有清除是一直存在的,一直存在没有被释放就会造成内存泄漏。

  • 给DOM添加属性或方法:给DOM添加点击方法、添加属性等,也会造成变量引用得不到释放,造成内存泄漏。

21.释放内存的方法

赋值为null

22.你如何对网上的文件和资源进行优化?

  • 文件合并(目的是减少http请求)

  • 文件压缩(目的是直接减少文件下载的体积)

  • 使用cdn托管资源

  • 使用缓存

  • gizp压缩你的js和css文件

  • meta标签优化(title,description,keywords)、heading标签的优化、alt优化

  • 反向链接,网站外链接优化

23.请简述ajax的执行过程以及常见的HTTP状态码

ajax详细执行过程请查阅相关文档

常见的HTTP状态码:

  • 100:这个状态码是告诉客户端应该继续发送请求,这个临时响应是用来通知客户端的,部分的请求服务器已经接受,但是客户端应继续发送求请求的剩余部分,如果请求已经完成,就忽略这个响应,而且服务器会在请求完成后向客户发送一个最终的结果

  • 200:这个是最常见的http状态码,表示服务器已经成功接受请求,并将返回客户端所请求的最终结果

  • 202:表示服务器已经接受了请求,但是还没有处理,而且这个请求最终会不会处理还不确定

  • 204:服务器成功处理了请求,但没有返回任何实体内容 ,可能会返回新的头部元信息

  • 301:客户端请求的网页已经永久移动到新的位置,当链接发生变化时,返回301代码告诉客户端链接的变化,客户端保存新的链接,并向新的链接发出请求,已返回请求结果

  • 404:请求失败,客户端请求的资源没有找到或者是不存在

  • 500:服务器遇到未知的错误,导致无法完成客户端当前的请求。

  • 503:服务器由于临时的服务器过载或者是维护,无法解决当前的请求

24.懒加载与预加载的区别,预加载在什么时间加载合适

两者都是提高页面性能有效的办法,

两者主要区别是一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。

预加载使用场景:在网页全部加载之前,对一些主要内容进行加载,以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,直到所有内容加载完毕

详细对比查看上面第5小节

25.jquery选择器有哪些?

一、基本选择器** 基本选择器是jQuery中最常用也是最简单的选择器,它通过元素的id、class和标签名等来查找DOM元素。 1、ID选择器 #id 描述:根据给定的id匹配一个元素, 返回单个元素(注:在网页中,id名称不能重复) 示例:$("#test") 选取 id 为 test 的元素

2、类选择器 .class 描述:根据给定的类名匹配元素,返回元素集合 示例:$(".test") 选取所有class为test的元素

3、元素选择器 element 描述:根据给定的元素名匹配元素,返回元素集合 示例:$("p") 选取所有的<p>元素

4、* 描述:匹配所有元素,返回元素集合 示例:$("") 选取所有的元素

5、selector1,selector2,...,selectorN 描述:将每个选择器匹配到的元素合并后一起返回,返回合并后的元素集合 示例:$("p,span,p.myClass") 选取所有<p>,<span>和class为myClass的<p>标签的元素集合

二、层次选择器 层次选择器根据层次关系获取特定元素。 1、后代选择器 示例:$("p span") 选取<p>元素里的所有的<span>元素(注:后代选择器选择父元素所有指定选择的元素,不管是儿子级,还是孙子级)

2、子选择器 $("parent>child") 示例:$("p>span") 选择<p>元素下的所有<span>元素 (注:子选择器只选择直属于父元素的子元素)

3、同辈选择器 $("prev+next") 描述:选取紧接在prev元素后的next元素,返回元素集合 示例:$(".one+p") 选取class为one的下一个<p>同辈元素集合

4、同辈选择器 $("prev~siblings") 描述:选取prev元素后的所有siblings元素,返回元素集合 示例:$("#two~p")选取id为two的元素后所有<p>同辈元素集合

三、过滤选择器 1>基本过滤选择器 1、 :first 描述:选取第一个元素,返回单个元素 示例:$("p:first") 选取所有<p>元素中第一个<p>元素

2、 :last 描述:选取最后一个元素,返回单个元素 示例:$("p:last") 选取所有<p>元素中最后一个<p>元素

3、 :not(selector) 描述:去除所有与给定选择器匹配的元素,返回元素集合 示例:$("input:not(.myClass)") 选取class不是myClass的<input>元素

4、 :even 描述:选取索引是偶数的所有元素,索引从0开始,返回元素集合

5、 :odd 描述:选取索引是奇数的所有元素,索引从0开始,返回元素集合

6、 :eq(index) 描述:选取索引等于index的元素,索引从0开始,返回单个元素

7、 :gt(index) 描述:选取索引大于index的元素,索引从0开始,返回元素集合

8、 :lt(index) 描述:选取索引小于于index的元素,索引从0开始,返回元素集合

9、 :focus 描述:选取当前获取焦点的元素

2>内容过滤选择器 1、:contains(text) 描述:选取含有文本内容为text的元素,返回元素集合 示例:$("p:contains('我')") 选取含有文本“我”的元素

2、:empty 描述:选取不包含子元素或者文本元素的空元素,返回元素集合 示例:$("p:empty") 选取不包含子元素或者文本元素的空<p>元素(<p></p>)

3、:has(selector) 描述:选取含有选择器所匹配的元素的元素,返回元素集合 示例:$("p:has(p)") 选取含有<p>元素的<p>元素(<p><p/></p>)

4、:parent 描述:选取含有子元素或者文本的元素,返回元素集合 示例:$("p:parent") 选取含有子元素或者文本元素的<p>元素(<p><p/></p>或者<p>文本</p>)

3>可见性过滤选择器 1、:hidden 描述:选取所有不可见的元素,返回元素集合

2、:visible 描述:选取所有可见的元素,返回元素集合

4>属性过滤选择器(返回元素集合) 1、[attribute] 示例:$("p[id]") 选取拥有id属性的p元素

2、[attribute=value] 示例:$("input[name=text]") 选取拥有name属性等于text的input元素

3、[attribute!=value] 示例:$("input[name!=text]") 选取拥有name属性不等于text的input元素

4、[attribute^=value] 示例:$("input[name^=text]") 选取拥有name属性以text开始的input元素

5、[attribute$=value] 示例:$("input[name$=text]") 选取拥有name属性以text结束的input元素

6、[attribute=value] 示例:$("input[name=text]") 选取拥有name属性含有text的input元素

7、[attribute~=value] 示例:$("input[class~=text]") 选取拥有class属性以空格分割的值中含有text的input元素

8、attribute1[attributeN] 描述:合并多个属性过滤选择器

5>表单对象属性过滤选择器(返回元素集合) 1、:enabled 描述:选取所有可用元素

2、:disabled 描述:选取所有不可用元素

3、:checked 描述:选取所有被选中的元素(单选框,复选框) 示例:$("input:checked") 选取所有被选中的<input>元素

4、:selected 描述:选取所有被选中的选项元素(下拉列表) 示例:$("select option:selected") 选取所有被选中的选项元素

Jquery插入节点的方法

append() 向每个匹配的元素内部追加内容

appendTo() 将所有匹配的元素追加到指定元素中,实际上,使用该方法是颠倒了常规的$(A).append(B)的操作 将A追加到B中

prepend() 向每个匹配的元素内部前置内容

prependTo() 将所有匹配的元素前置到指定的元素中。实际上,使用该方法是颠倒了常规的$(A).prepend(B)的操作,即不是将B前置到A中,而是将A前置到B中

after() 在每个匹配的元素之后插入内容

insertAfter() 将所有匹配的元素插入到指定元素的后面。实际上,使用该方法是颠倒了常规的$(A).after(B)的操作,即不是讲B插入到A后面,而是将A插入到B后面

before() 在每个匹配的元素之前插入内容

insertBefore() 将所有匹配的元素插入到指定的元素的前面。实际上,使用该方法是颠倒了常规的$(A).before(B)的操作,即不是将B插入到A前面,而是将A插入到B前面

26.js函数节流与函数防抖的区别?

函数节流函数防抖,两者都是优化高频率执行js代码的一种手段。

函数节流是指一定时间内js方法只执行一次。

函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次

函数节流是 声明一个变量当标志位,记录当前代码是否在执行,如果正在执行,取消这次方法执行,直接return,如果空闲,正常触发方法执行

// 函数节流
var canRun = true;
document.getElementById("throttle").onscroll = function(){if(!canRun){// 判断是否已空闲,如果在执行中,则直接returnreturn;}canRun = false;setTimeout(function(){console.log("函数节流");canRun = true;}, 300);
};

函数节流的要点是,声明一个变量当标志位,记录当前代码是否在执行。如果空闲,则可以正常触发方法执行。如果代码正在执行,则取消这次方法执行,直接return。

函数防抖是需要一个延时器来辅助实现,延迟执行需要执行的代码,如果方法多次触发,把上次记录的延迟执行代码用cleartimeout清除掉,重新开始,如果计时完毕,没有方法来访问触发,则执行代码

// 函数防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){clearTimeout(timer); // 清除未执行的代码,重置回初始化状态timer = setTimeout(function(){console.log("函数防抖");
}, 300);
};  

函数防抖的要点,也是需要一个setTimeout来辅助实现。延迟执行需要跑的代码。如果方法多次触发,则把上次记录的延迟执行代码用clearTimeout清掉,重新开始。如果计时完毕,没有方法进来访问触发,则执行代码。

27.Get与Post(自行查阅)

28.什么是CSRF攻击?

CSRF(Cross Site Request Forgery)跨站点请求伪造攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份再攻击页面对目标网站发起伪造用户操作的请求,达到攻击目的。**

尽管听起来像跨站脚本(XSS),但它与 XSS 非常不同,XSS 利用站点内的信任用户,而 CSRF 则通过伪装成受信任用户的请求来利用受信任的网站。与 XSS 攻击相比,CSRF 攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难 以防范,所以被认为比 XSS 更具危险性。

避免方法:

  • CSRF 漏洞进行检测的工具,如 CSRFTester、CSRF Request Builder...

  • 验证 HTTP Referer 字段

  • 添加并验证 token

  • 添加自定义 http 请求头

  • 敏感操作添加验证码

  • 使用 post 请求

29.手写一个深拷贝

自己提前写一下

30.什么时候用深拷贝/浅拷贝

无论深浅,都是需要的,当深拷贝发生时通常表明存在着一个聚合关系,当浅拷贝发生时,通常表明存在着相识关系

举个简单例子:当实现一个组合模式Composite Pattern时通常都会实现深拷贝

当实现一个观察者模式Observer Pattern,时,就需要实现浅拷贝

vue相关

1.Vue的核心是什么

Vue是一套构建用户界面的渐进式自底向上增量开发的MVVM(Model-View-ViewModel)框架,vue的核心只关注视图层。

MVVM(Model-View-ViewModel)是一种软件架构设计模式,它是一种简化用户界面的事件驱动编程方式。

  • View是视图层,也就是用户界面。前端主要由HTML和CSS来构成,为了更方便地展现ViewModel或者Model层的数据。

  • Model是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则。

  • ViewModel由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者从后端获取得到Model数据进行转换出来,做二次封装,以生成符合View层使用预期的视图数据模型。视图状态和行为都封装在ViewModel里。这样的封装使得ViewModel可以完整地去描述View层。

注意:在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者。ViewModel是连接View和Model的中间件。

为什么使用MVVM:

  • 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候,View也可以不变。

  • 可复用:可以把一些视图逻辑放到一个ViewModel里面,让很多View重用这段视图逻辑。

  • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。

  • 可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

Vue核心思想:

  • 数据驱动(视图的内容随着数据的改变而改变)

  • 组件化(可以增加代码的复用性,可维护性,可测试性,提高开发效率,方便重复使用,体现了高内聚低耦合)

2.请简述你对vue的理解

Vue是一套构建用户界面的渐进式的自底向上增量开发的MVVM框架,核心是关注视图层,vue的核心是为了解决数据的绑定问题,为了开发大型单页面应用和组件化,所以vue的核心思想是数据驱动和组件化,这里也说一下MVVM思想,MVVM思想是 模型 视图 vm是v和m连接的桥梁,当模型层数据修改时,VM层会检测到,并通知视图层进行相应修改

3.请简述vue的单向数据流与双向数据流

1、单项数据流

单向数据流(Unidirectional data flow)方式使用一个上传数据流和一个下传数据流进行双向数据通信,两个数据流之间相互独立。单向数据流指只能从一个方向来修改状态。

1)Vue中的单项数据流

  • 对于vue来说,组件之间的数据传递具有单项数据流 这样的特性。

  • 父组件总是通过 props 向子组件传递数据; 父级prop的更新会向下流动到子组件中,每次父组件发生更新,子组件所有的prop都会刷新为最新的值;

  • 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定;

  • 父级 prop 的更新会向下流动到子组件中,但是反过来则不行;数据从父组件传递给子组件,只能单向绑定,子组件内部不能直接修改父组件传递过来的数据,(可以使用data和computed解决)

  • 这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解;

  • 每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值;

  • 这意味着不应该在一个子组件内部改变 prop。如果这样做,Vue 会在浏览器的控制台中发出警告。

2)单项数据流的优(1)/缺点(.)

  1. 所有状态的改变可记录、可跟踪,源头易追溯;

  2. 所有的数据,具有唯一出口和入口,使得数据操作更直观更容易理解,可维护性强;

  3. 当数据变化时,页面会自动变化

  4. 当你需要修改状态,完全重新开始走一个修改的流程。这限制了状态修改的方式,让状态变得可预测,容易调试。

  • 页面渲染完成后,有新数据不能自动更新,需要手动整合新数据和模板重新渲染

  • 代码量上升,数据流转过程变长,代码重复性变大

  • 由于对应用状态独立管理的严格要求(单一的全局 store,如:Vuex),在处理局部状态较多的场景时(如用户输入交互较多的“富表单型”应用),会显得啰嗦及繁琐。

2、双向数据流

双向数据流中,Model(可以理解为状态的集合) 中可以修改自己或其他Model的状态, 用户的操作(如在输入框中输入内容)也可以修改状态。(双向数据流也可以叫双向数据绑定)

1)当我们在前端开发中采用 MV* 的模式时,M - model,指的是模型,也就是数据,V - view,指的是视图,也就是页面展现的部分。

将从服务器获取的数据进行“渲染”,展现到视图上。每当数据有变更时,我们会再次进行渲染,从而更新视图,使得视图与数据保持一致

页面也会通过用户的交互,产生状态、数据的变化,这个时候,我们则编写代码,将视图对数据的更新同步到数据

2)使用双向数据流优(1)/缺点(.)

  1. 数据模型变化与更新,会自动同步到页面上,用户在页面的数据操作,也会自动同步到数据模型

  2. 无需进行和单向数据绑定的那些相关操作;

  3. 在表单交互较多的场景下,会简化大量业务无关的代码。

  • 无法追踪局部状态的变化;

  • “暗箱操作”,增加了出错时 debug 的难度;

  • 由于组件数据变化来源入口变得可能不止一个,数据流转方向易紊乱。

  • 改变一个状态有可能会触发一连串的状态的变化,最后很难预测最终的状态是什么样的。使得代码变得很难调试

4.Vue常用的修饰符有哪些

修饰符:.lazy 改变后触发,光标离开input输入框的时候值才会改变

               .number 将输出字符串转为number类型.trim 自动过滤用户输入的首尾空格

事件修饰符:

  • .stop 阻止点击事件冒泡,相当于原生js中的event.stopPropagation()

  • .prevent 防止执行预设的行为,相当于原生js中event.preventDefault()

  • .capture 添加事件侦听器时使用事件捕获模式,就是谁有该事件修饰符,就先触发谁

  • .self 只会触发自己范围内的事件,不包括子元素

  • .once 只执行一次

键盘修饰符:

  • .enter 回车键 .tab 制表键 .esc返回键 .space 空格键

  • .up向上键 .down 向下键 .left向左建 .right向右键

系统修饰符:

  • .ctrl .alt .shift .meta

5.v-text与{{}}与v-html区别

v-text 将数据解析为纯文本,不能输出真正的html,与花括号的区别是在页面加载时不显示双花括号

{{}} 将数据解析为纯文本,不能显示输出html

v-html 可以渲染输出html

v-text 指令:操作网页元素中的纯文本内容。{{}}是他的另外一种写法

v-text与{{}}区别:

  • v-text与{{}}等价,{{}}叫模板插值,v-text叫指令。

  • 有一点区别就是,在渲染的数据比较多的时候,可能会把大括号显示出来,俗称屏幕闪动:

6.v-on可以绑定多个方法吗

可以 如果绑定多个事件,可以用键值对的形式 事件类型:事件名

如果绑定是多个相同事件,直接用逗号分隔就行

注意: v-on指令在vue中用于绑定DOM/自定义事件的响应处理函数,可以用在HMTL原生标签上,也可以用于自定义的vue组件标签上。

7.Vue循环key作用

Key值的存在保证了唯一性,Vue在执行时,会对节点进行检查,如果没有key值,那么vue检查到这里有dom节点,就会对内容清空并赋新值,如果有key值存在,那么会对新老节点进行对比,比较两者key是否相同,进行调换位置或删除操作

8.什么是计算属性?

计算属性是用来声明式的描述一个值依赖了其他的值,当它依赖的这个值发生改变时,就更新DOM

当在模板中把数据绑定到一个计算属性上时,vue会在它依赖的任何值导致该计算属性改变时更新DOM

每个计算属性都包括一个getter和setter,读取时触发getter,修改时触发setter

9.简单讲述一下Vue单页面(SPA)和多页面(MPA)

1、SPA

1)简述SPA

SPA 全称 Single Page Application,即单页面应用。一般也称为 CSR(Client Side Render),即客户端渲染。它所需的资源,如 HTML、CSS 和 JS 等,在一次请求中就加载完成,也就是不需刷新地动态加载。浏览器(Client)渲染顾名思义就是所有的页面渲染、逻辑处理、页面路由、接口请求均是在浏览器中发生。对于 SPA 来说,页面的切换就是组件或视图之间的切换。

简单来说,SPA应用程序只有一个html文件,在vue中可以通过vue-router来局部切换组件,而非刷新整个页面,来实现无刷新切换页面的技术

SPA应用程序避免了由于在服务器上呈现页面而导致的中断。 这消除了 Web 开发世界在提供无缝用户体验方面通常面临的最大问题。

2)SPA原理

js会感知到url的变化,通过这一点可以用js监听url中hash值的变化,通过onhashchange事件,由于哈希值的变换并不会引发页面的刷新和跳转,当监听到hash变化,就可以动态的切换组件,就可以实现无刷新切换页面技术

  • 注意. 在vue-router中 vue不支持onhashchange事件,它希望你使用vue-router中的钩子函数解决

3)SPA的优缺点

优点:

1.页面切换快:页面每次切换跳转时,并不需要做html文件的请求,这样就节约了很多http发送时延,我们在切换页面的时候速度很快。

2.用户体验好:页面片段间的切换快,包括移动设备, 尤其是在网络环境差的时候, 因为组件已经预先加载好了, 并不需要发送网络请求, 所以用户体验好

缺点:

1.首屏加载速度慢:首屏时需要请求一次html,同时还要发送一次js请求,两次请求回来了,首屏才会展示出来。相对于多页应用,首屏时间慢。

2.不易于seo(搜索引擎优化):SEO效果差,因为搜索引擎只认识html里的内容,不认识js的内容,而单页应用的内容都是靠js渲染生成出来的,搜索引擎不识别这部分内容,也就不会给一个好的排名,会导致SPA应用做出来的网页在百度和谷歌上的排名差。

2、MPA

1)简述MPA

MPA多页面应用 MultiPage Application ,指有多个独立页面的应用(多个html页面),每个页面必须重复加载js、css等相关资源。多页应用跳转,需要整页资源刷新。

SPA 对比最大的不同即是页面路由切换由原生浏览器文档跳转(navigating across documents)控制。 页面跳转,是返回 HTML 的。

2)MPA优缺点

优点:

1.首屏加载速度快:当我们访问页面的时候,服务器返回一个html,页面就会展示出来,这个过程只经历了一个HTTP请求,所以页面展示的速度非常快。

2.SEO效果好:搜索引擎在做网页排名的时候,要根据网页的内容才能给网页权重,来进行网页的排名。搜索引擎是可以识别html内容的,而我们每个页面所有的内容都放在html中,所以这种多页应用SEO排名效果好。

缺点:

1.页面切换慢:因为每次跳转都需要发送一个 HTTP 请求,如果网络状态不好,在页面之间来回跳转时,就会发生明显的卡顿,影响用户体验。

2.用户体验不佳:如果网络慢,页面很容易半天加载不出来,用户体验非常不好

思考:通过二者之间的比较,想一想为什么要使用SPA应用开发?

通过上面的分析,我们不难发现,SPA和MPA各有优缺点,那我们为什么还要开发SPA呢,其实,Vue还提供了一些其它的技术来解决这些缺点,比如说服务器端渲染技术(SSR),通过这些技术可以完美解决这些缺点,解决完这些问题,实际上单页面应用对于前端来说是非常完美的页面开发解决方案。

10.Vuex是什么?怎样使用?在哪种场景使用?

1、什么是Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件/模式。它采用集中式存储管理应用的所有组件的状态,而更改状态的唯一方法是提交mutation,例this.$store.commit('SET_VIDEO_PAUSE', video_pauseSET_VIDEO_PAUSE为mutations属性中定义的方法 。Vuex通过创建一个集中的数据存储,方便程序中的所有组件进行访问,简单来说 vuex就是vue的状态管理工具

1)Vuex的核心(5个属性)

  • State就是数据源存放地,对应一般vue对象的data,state里面存放的数据是响应式的,state数据发生改变,对应这个数据的组件也会发生改变 用this.$store.state.xxx调用

  • Getters 相当于store的计算属性,主要是对state中数据的过滤,用this.$store.getters.xxx调用

  • Mutations 处理数据逻辑的方法全部放在mutations中,当触发事件想改变state数据的时候使用mutations,用this.$store.commit调用,给这个方法添加一个参数,就是mutation的载荷(payload)

  • Actions 异步操作数据,但是是通过mutation来操作 用this.$store.dispatch来触发,actions也支持载荷

  • module 是 store 分割的模块,每个模块拥有自己的 state、getters、mutations、actions。

2、怎样引用Vuex(Vue3使用Vuex)

  • 先安装依赖 npm install vuex --save

  • 在项目目录src文件夹中创建store文件夹

  • 在store文件夹中新建index.js文件,写入:

// vue3中创建store实例对象的方法createStore()按需引入
import { createStore } from 'vuex'export default createStore({state: {},mutations: {},actions: {},getters: {},modules: {}
})
  • 使用的时候在template模板中使用:

    //首先先导入vuex:
    import { useStore } from 'vuex'
    //开始使用
    <template><div id="nav"><p>{{$store.state.name}}</p><button @click="mutationsA">+</button></div><router-view/>
    </template>
    <script>
    import { useStore } from 'vuex'
    export default {name: 'App',setup () {const store = useStore()  //记得加这一句//这一句是使用vuex仓库,注释掉这一句,直接使用useStore会报错console.log(store.state.name)console.log(store.getters.newname)const mutationsA = () => {store.commit('updatename')}return { mutationsA }}
    }

3、Vuex使用场景

组件之间的状态,登录状态,加入购物车,音乐播放.在需要集中式管理数据的大型项目中,用 vuex 来管理*业务组件*(不是通用组件)*

11.Vue中路由跳转方式(声明式/编程式)**

vue中的路由是路径与组件的映射关系,使用的目的是为了在一个页面中,可以切换应用场景。

动态路由也称路由传参

Vue中路由跳转有两种,分别是声明式和编程式

1)标签路由 router-link(用router-link进行跳转的叫声明式 router-view 路由出口,路由模板显示的位置)

注意:router-link中,链接如果是’/'开头则表示从根路由开始;如果开头不带‘/’,则从当前路由开始。 (1)不带参数

<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}">

(2)带参数

<router-link :to="{name:'home', params: {id:1}}">
// params传参数 (类似post)
// 路由配置 path: "/home/:id" 或者 path: "/home:id"
// 不配置path ,第一次可请求,刷新页面id会消失(比如,点击某件商品图片的“查看详情”,跳转到该商品的详情页面,刚开始进入详情页面时能拿到数据(根据商品id获取),刷新页面后,id丢失,页面就取不到相应的数据了)
// 配置path,刷新页面id会保留
// html 取参  $route.params.id
// script 取参  this.$route.params.id<router-link :to="{name:'home', query: {id:1}}">
// query传参数 (类似get,url后面会显示参数)
// 路由可不配置
// html 取参  $route.query.id

2)编程式路由this.$router.push() (用js方法进行跳转的叫编程)

(1)不带参数

this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})

(2)带参数

  • query

this.$router.push({name:'Home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})
// query传参数 (类似get,页面url后面会显示参数)
// 路由可不配置
// html 取参 $route.query.id
// script 取参 this.$route.query.id
  • params传参

this.$router.push({name:'home',params: {id:'1'}})  // 只能用 name
// params传参数
// 路由配置 path: "/home/:id"
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
// html 取参 $route.params.id
// script 取参 this.$route.params.id

3)this.$router.replace() (与this.$router.push()相似)

4) this.$router.go(n)

this.$router.go(n)
//向前或者向后跳转n个页面,n可为正整数或负整数

用js方式进行跳转的叫编程式导航 this.$router.push()

12.路由中name属性有什么作用?

在router-link中使用name导航到对应路由 使用name导航的同时,给子路由传递参数

13.Vue跨域的解决方式

出现跨域的原因:一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即跨域。

可以配置代理服务器的中间件(代理服务)

**注意:还有一些其它的方法请查阅相关文档**

14.Vue的生命周期请简述

vue的生命周期就是vue实例的创建到vue实例的销毁 。期间会有8个钩子函数的调用

  • beforeCreate(创建实例)

  • created(创建完成)、

  • beforeMount(开始创建模板)

  • mounted(创建完成)、

  • beforeUpdate(开始更新)

  • updated(更新完成)、

  • beforeDestroy(开始销毁)

  • destroyed(销毁完成)

Vue实例的生命周期函数主要可以分为以下三部分:

创建期间、运行期间以及销毁期间的生命周期函数

创建期的生命周期函数如下:

  • beforeCreate:beforeCreate函数在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项对象还未创建,el 和 data 并未初始化,因此无法访问methods, data, computed等上的方法和数据。

  • created:created函数表示vue实例已经在内存中创建完成,并且数据data 和方法methods 也已经创建完成,但是还没有开始编译模板;

  • beforeMount:beforeMount函数表示此时已经完成了模板的编译,但是还没有挂载到页面中;

  • mounted:mounted函数表示已经将编译好的模板,挂载到了页面指定的容器中显示;

运行期间的生命周期函数如下:

  • beforeUpdate:beforeUpdate函数表示状态更新之前执行此函数,此时data中的状态值是最新的,但是界面上显示的数据还是旧的,因为此时还没有开始重新渲染DOM节点;

  • updated:updated函数表示vue实例更新完毕之后调用此函数,此时data中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了;

销毁期间的生命周期函数:

  • beforeDestroy:beforeDestroy函数表示在vue实例销毁之前调用。这个时候,实例仍然完全可用;

  • destroyed:destroyed函数在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用

15.Vue生命周期的作用

给了用户在不同阶段添加自己代码的机会(我也不知道这怎么说,看个人理解)

16.DOM渲染在哪个生命周期阶段内完成?

DOM渲染在mounted周期中就已经完成了

17.Vue路由的实现

前端路由就是更新视图但不请求页面,利用锚点完成切换,页面不会刷新。

定义路由组件(粗略步骤):

  • 定义路由,使用component进行路由映射组件,用name导航到对应路由

  • 创建router实例,传入routes配置

  • 创建和挂载根实例

  • 用router-link设置路由跳转

  1. 定义路由组件

  2. 定义路由,使用component进行路由映射组件,用name导航到对应路由

  3. 创建router实例,传入routes配置

  4. 创建和挂载根实例

  5. 用router-link设置路由跳转

18.说一下你对锚点的认识

**锚点是网页制作中超级链接的一种,又叫命名锚记。**

命名锚记像一个迅速定位器一样是一种页面内的超级链接,运用相当普遍。

使用命名锚记可以在文档中设置标记,这些标记通常放在文档的特定主题处或顶部。然后可以创建到这些命名锚记的链接,这些链接可快速将访问者带到指定位置。

创建到命名锚记的链接的过程分为两步:

  1. 创建命名锚记。

  2. 创建到该命名锚记的链接。

<a id="top">这里是TOP部分</a>
<a href="#top">点击我连接到TOP</a>

19.Vue路由模式中hash和history讲一下(主要检验面试者是否有开发经验)

形式上:Hash模式地址栏(url)中有#,开发当中默认使用这个模式。如果用户考虑url的规范,那么就需要使用history模式因为·history模式没有#,是个正常url,适合推广宣传,history模式下刷新,会出现404情况,需要后台配置

使用 JavaScript 来对 loaction.hash 进行赋值,改变 URL 的 hash 值 。可以使用 hashchange 事件来监听 hash 值的变化

HTML5 提供了 History API 来实现 URL 的变化。其中最主要的 API 有以下两个:history.pushState() 和 history.repalceState()。

这两个 API 可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录。 注意:具体情况查阅相关文档

20.讲述一下Vue路由传参的两种方式:params和query

动态路由也可以叫路由传参,就是根据不同的选择在同一个组件渲染不同的内容

  • query

this.$router.push({name:'Home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})
// query传参数 (类似get,页面url后面会显示参数)
// 路由可不配置
// html 取参 $route.query.id
// script 取参 this.$route.query.id
  • params传参

this.$router.push({name:'home',params: {id:'1'}})  // 只能用 name
// params传参数
// 路由配置 path: "/home/:id"
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
// html 取参 $route.params.id
// script 取参 this.$route.params.id

用法上:query用path引入,params用name引入,接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name

url展示上:params类似于post,query类似于get,也就是安全问题,params传值相对更安全点,query通过url传参,刷新页面还在,params刷新页面不在了

21.Vue数据绑定的几种方式

  • 单向绑定 双大括号 {{}} html内字符串绑定

  • v-bind绑定 html属性绑定

  • 双向绑定 v-model

  • 一次性绑定 v-once 依赖于v-model

注意:具体情况请查阅相关文档

22.Vue注册一个全局组件

Vue.componnet(“组件的名字”{对象  template <div>组建的内容</div>})

23.Vue的路由钩子函数/路由守卫有哪些

  • 全局守卫:beforeEach(to,from,next)和afterEach(to,from)

  • 路由独享守卫:beforeEnter

  • 组件内的守卫:路由进入/更新/离开之前 beforeRouterEnter/update/leave

24.Vue中如何进行动态路由设置?有哪些方式?怎样获取传递过来的数据

动态路由也可以叫路由传参

动态路由有query和params两种方式传参

  • query用path引入,query用this.$route.query.name接收参数

  • params用name引入,params用this.$route.params.name接收参数

25.Element UI常用的组件有哪些?请简述一下你常用到的 并且它们的属性有哪些?

Container布局容器

  • <el-container>外层容器

  • <el-header>顶栏容器

  • <el-aside>侧边栏容器

  • <el-main>主要内容容器

  • <el-footer>底栏容器

Dropdown 下拉菜单

  • <el-container split-buton> 下拉按钮

  • <el-container-menu> 下拉菜单

  • <el-container-item> 下拉项

Table 表格

Tabs 标签页

Form 表单

Pagination 分页

Message 消息提示

26.Vue-cli如何自定义指令

注:自行查阅相关文档

27.Vue指令有哪些

  • v-for:循环数组,对象,字符串,数字

  • v-on:绑定事件监听

  • v-bind:动态绑定一个或者多个属性

  • v-model:表单控件或者组件上创建双向绑定

  • v-if v-else v-else-if 条件渲染

  • v-show 根据表达式真假,切换元素的display

  • v-html 更新元素的innerhtml

  • v-text 更新元素的textcontent

  • v-pre 跳过这个元素和子元素的编译过程

  • v-clock 这个指令保持在元素上知道关联实例结束编译

  • v-once 只渲染一次

28.Vue如何定义一个过滤器

过滤器本质就是一个有参数有返回值的方法

new Vue({filters:{myCurrency:function(myInput){return 处理后的数据}}
})

使用方法:

<h1>{{表达式 | 过滤器}}</h1>

过滤器高级用法:可以指定参数,告诉过滤器按照参数进行数据的过滤

29.对Vue中keep-alive的理解

概念:keep-alive是vue的内置组件,当它动态包裹组件时,会缓存不活动的组件实例,它自身不会渲染成一个DOM元素也不会出现在父组件链中

作用:在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间以及性能消耗,提高用户体验。

生命周期函数:Activated在keep-alive组件激活时调用,deactivated在keep-alive组件停用时调用

30.如何让组件中的css在当前组件中生效呢?

在style中加上scoped

注: 给style添加scoped,只针对当前Vue组件内标签生效

<style scoped lang=""></style>

31.Vue生命周期一共有几个阶段? 创建 加载 更新 销毁

  • Beforecreate创建前(创建实例)

  • Created 创建后(创建完成)

  • Beforemount 加载前(开始创建模板)

  • Mounted 加载后(创建完成)

  • Beforeupdate 更新前(开始更新)

  • Updated 更新后(更新完成)

  • Beforedestroy 销毁前(开始销毁)

  • Destroyed 销毁后(销毁完成)

页面第一次加载会触发 beforecreate created beforemount mounted

DOM渲染在mounted周期中就已经完成

32.MVVM与MVC的区别

在MVVM(Model-View-ViewModel)框架下视图和模型是不能直接通信的,只能通过ViewModel进行交互,它能够监听到数据的变化,然后通知视图进行自动更新,而当用户操作视图时,VM也能监听到视图的变化,然后通知数据做相应改动,这实际上就实现了数据的双向绑定。并且V和VM可以进行通信。

MVC(Model-View-controller)模型视图控制器,视图是可以直接访问模型,所以,视图里面会包含模型信息,MVC关注的是模型不变,所以,在MVC中,模型不依赖视图,但是视图依赖模型

MVVM 模型 视图 和vm vm是作为模型和视图的桥梁,当模型层数据改变,vm会检测到并通知视图层进行相应的修改

  • MVC中Controller演变成MVVM中的ViewModel

  • MVVM通过数据来显示视图层而不是节点操作

  • MVVM主要解决了MVC中大量的dom操作使页面渲染性能降低,加载速度变慢,影响用户体验

33.Vue组件中的data为什么是函数?

Data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响

如果是引用类型(对象),当多个组件共用一个数据源时,一处数据改变,所有的组件数据都会改变,所以要利用函数通过return返回对象的拷贝,(返回一个新数据),让每个实例都有自己的作用域,相互不影响。

34.你了解Vue双向绑定的原理吗

了解一下什么是双向绑定

所谓的双向绑定建立在MVVM的模型基础上的:

  • 数据层 Model:应用的数据以及业务逻辑

  • 视图层 View:应用的展示效果,各类的UI组件等

  • 业务逻辑层 ViewModel: 负责将数据和视图关联起来

  1. 数据变化后更新视图

  2. 视图变化后更新数据

包含两个主要的组成部分

  • 监听器 Observer:对所有的数据属性进行监听

  • 解析器 Compiler:对每个元素节点的指令进行扫描和解析,根据指令替换数据,绑定对应的更新函数

Vue双向绑定具体实现原理:

  1. new Vue() 实例的过程中,执行初始化。对data通过Object.defineProperty进行响应化处理,这个过程发生在Observer中,每个key都会有一个dep实例来存储watcher实例数组。

  2. 对模板进行编译时,v- 开头的关键词作为指令解析,找到动态绑定的数据,从data中获取数据并初始化视图,这个过程发生在 Compiler 里。如果遇到了 v-model,就监听input事件,更新data对应的数值。

  3. 在解析指令的过程中,会定义一个更新函数和Watcher,之后对应的数据变化时 Watcher 会调用更新函数。new Watcher 的过程中会去读取data的key,触发getter的依赖收集,将对应的watcher添加到dep里。

  4. 将来data中数据一旦发生变化,会首先找到对应的dep,通知所有的watcher执行更新函数。

Vue数据双向绑定是通过数据劫持和观察者模式来实现的,

  • 数据劫持,object.defineproperty它的目的是:当给属性赋值的时候,程序可以感知到,就可以控制改变属性值

  • 观察者模式 当属性发生改变的时候,使用该数据的地方也发生改变

35.Vue中组件怎么传值

组件是可以复用的vue实例

  • 正向:父传子 父组件自定义属性传值,把要传递的数据绑定在属性上,发送,子组件通过props接收并使用

  • 逆向:子传父 子组件通过this.$emit(自定义事件名,要发送的数据)触发,父组件设置一个监听事件来接收,然后拿到数据

36.Bootstrap原理

网格系统的实现原理,通过定义容器大小,平分12份,(24份或者32份),再调整内外边距,结合媒体查询,就成了强大的响应式网格系统。 比如 row col-xs-4

37.如果一个组件在多个项目中使用怎么办呢?

方案一:npm 发布引用

公共组件编写完成后,将其发布到 npm。发布流程如下:在npm 注册一个账号进入 common 的控制台,输入命令 npm login,按照提示输入刚注册的账号密码输入命令 npm publish 即可需要用该组件的项目通过 npm install 命令将公共组件以 node_module 的方式引入。另外,每次改动代码再次发布时,需要修改 package.json 文件中的版本号,不然发布不成功。

方案二:npm link

首先进入公共包,在控制台输入 npm link 这会创建一个软连接,并保存到目录 C:\Users\Administrator\AppData\Roaming\npm\node_modules 下面。然后进入 使用该公共组件的项目,在控制台输入 npm link common。

方案三:npm 本地 file 引用(推荐)

进入使用该公共项目的文件夹,在控制台输入命令:npm install ../common/ 其 中…/common/是 common 的相对路径,这里也可以输入绝对路径这样就将 common 这个工程以 node_module 的方式引入到需要使用的项目中了。可以 正常使用公共项目在 index.js 中导出的组件了。命令执行完后,package.json里会多一条记录**

38.插槽(槽口)请简述

询问内容大概有大概分这几点,首先槽口(插槽)可以放什么内容?放在哪?什么作用?

可以放任意内容,在子组件中使用,是为了将父组件中的子组件模板数据正常显示。

具名插槽和匿名插槽,作用域插槽。说白了就是在组件上的属性,可以在组件元素内使用,

可以在父组件中使用slot-scope从子组件获取数据

39.计算属性(computed)与watch的区别

一、computed

computed 用来计算属性,Vue 官方建议对于任何复杂逻辑,都应当使用 computed

以下是 vue 官网中的代码示例:

<div id="example"><p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } }
})

结果:

Original message: "Hello"
Computed reversed message: "olleH"computed不需要括号,可以像用属性一样用\

一些特性:

根据依赖会自动缓存,如果依赖不变,那么就不需要重新计算值

  • 支持缓存,只有依赖数据发生改变,才会重新进行计算

  • 不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化

  • computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于 data 中声明过或者父组件传递的props中的数据通过计算得到的值

  • 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed

  • 如果 computed 属性值是函数,那么默认会走 get 方法;函数的返回值就是属性的属性值;在computed 中的,属性都有一个 get 和一个 set 方法,当数据变化时,调用 set 方法

二、watch** 一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个 property

一些特性

  • 不支持缓存,在数据发生改变时,会直接触发相应的操作;

  • watch 支持异步;

  • 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;

  • 当一个属性发生变化时,需要执行对应的操作;一对多;

  • 监听数据必须是 data 中声明过或者父组件传递过来的 props 中的数据,当数据变化时,触发其他操作,函数有两个参数:

immediate

组件加载立即触发回调函数执行

watch: {firstName: {handler(newName, oldName) {this.fullName = newName + ' ' + this.lastName;},// 代表在wacth里声明了firstName这个方法之后立即执行handler方法immediate: true}
}
复制代码

deep

deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改 obj 里面任何一个属性都会触发这个监听器里的 handler

watch: {obj: {handler(newName, oldName) {console.log('obj.a changed');},immediate: true,deep: true}
}

总结:Computed watch 区别就是computed的缓存功能,当无关数据数据改变时,不会重新计算,直接使用缓存中的值。计算属性是用来声明式的描述一个值依赖了其他的值,当所依赖的值后者变量发生变化时,计算属性也跟着改变,

Watch监听的是在data中定义的变量,当该变量变化时,会触发watch中的方法

40.mvvm框架是什么?它和其它框架(jquery)的区别是什么?哪些场景适合?

Mvvm和其他框架的区别是 vue数据驱动 通过数据来显示视图而不是节点操作

适用于数据操作比较多的场景

41.Vue首屏加载慢的原因,怎样解决,白屏时间又是什么

第一次加载页面有很多组件数据需要渲染

解决方案:

  • 路由懒加载 : component: () => import("路由地址")

  • UI框架按需加载

白屏时间:即用户点击一个链接或打开浏览器输入URL地址后,从屏幕空白到显示第一个画面的时间。

白屏时间的长短将直接影响用户对该网站的第一印象。

白屏时间的重要性:

当用户点开一个链接或者是直接在浏览器中输入URL开始进行访问时,就开始等待页面的展示。页面渲染的时间越短,用户等待的时间就越短,用户感知到页面的速度就越快。这样可以极大的提升用户的体验,减少用户的跳出,提升页面的留存率。

42.Vue双数据绑定过程中,怎样在一边数据发生了改变去通知另一边数据发生改变

数据劫持和观察者模式

Vue数据双向绑定是通过数据劫持和观察者模式来实现的,

数据劫持,object.defineproperty它的目的是:当给属性赋值的时候,程序可以感知到,就可以控制属性值的有效范围,可以改变其他属性的值

观察者模式它的目的是当属性发生改变的时候,使用该数据的地方也发生改变

43.Vuex流程

  • 在vue组件里面,通过dispatch来触发actions提交修改数据的操作,

  • 然后通过actions的commit触发mutations来修改数据,

  • mutations接收到commit的请求,就会自动通过mutate来修改state,

  • 最后由store触发每一个调用它的组件的更新

44.Vuex怎样请求异步数据

  • 首先在state中创建变量

  • 然后在action中调用封装好的axios请求,异步接收数据,commit提交给mutations

  • Mutations中改变state中的状态,将从action中获取到的值赋值给state

45.Vuex中的action如何提交给mutation的

Action函数接收一个与store实例具有相同方法和属性的context对象,可以调用context.commit提交一个mutation,或者通过context.state和context.getters获取state和getters

46.Router和route的区别

  • router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。

  • route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等

47.说一下Vuex的state、getter、mutation、actions特性?

State:

  • State就是数据源的存放地

  • State里面的数据是响应式的,state中的数据改变,对应这个数据的组件也会发生改变

  • State通过mapstate把全局的state和getters映射到当前组件的计算属性中

Getter:

  • Getter可以对state进行计算操作,它就是store的计算属性

  • Getter可以在多组件之间复用

  • 如果一个状态只在一个组件内使用,可以不用getters

Mutation:

更改vuex store中修改状态的唯一办法就是提交mutation,可以在回调函数中修改store中的状态

actions:

Action类似于mutation,不同的是 action提交的是mutation,不是直接变更状态,可以包含任意异步操作

48.Vuex的优势

优点:解决了非父子组件的通信,减少了ajax请求次数,有些可以直接从state中获取

缺点:刷新浏览器,vuex中的state会重新变为初始状态,解决办法是vuex-along,得配合计算属性和sessionstorage来实现

49.Vue路由懒加载

使用路由懒加载是为了给客户更好的客户体验,首屏组件加载速度更快一些,解决白屏问题。

懒加载简单来说就是延迟加载或按需加载,即在需要的时候再进行加载

//未用懒加载,vue中路由代码如下:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'Vue.use(Router)export default new Router({routes: [{path: '/',name: 'HelloWorld',component:HelloWorld}]
})
//vue异步组件实现懒加载:  component:resolve=>(require(['需要加载的路由的地址']),resolve)
import Vue from 'vue'
import Router from 'vue-router'
/* 此处省去之前导入的HelloWorld模块 */
Vue.use(Router)export default new Router({routes: [{path: '/',name: 'HelloWorld',component: resolve=>(require(["@/components/HelloWorld"],resolve))}]
})

50.v-if与v-for的优先级

v-for 比 v-if 具有更高的优先级

不要把v-if与v-for用在同一个元素上,原因:v-for比v-if优先,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候。

前端面试相关题(简易)相关推荐

  1. 前端面试真题系列(一)-李游Leo-专题视频课程

    前端面试真题系列(一)-49人已学习 课程介绍         在鱼龙混杂的前端行业中,面试一直是一门非常重要的课程,尤其是笔试题. 而真实的面试题意味着你已经得到了面试邀请,在进入这家公司之前的第一 ...

  2. 12 道腾讯前端面试真题及答案整理

    年底了,又到了跳槽季啦,该刷题走起了.这里总结了一些被问到可能会懵逼的面试真题,有需要的可以看下- 1. 谈谈你对 dns-prefetch 的理解 DNS 是什么-- Domain Name Sys ...

  3. 前端面试 100 题:能搞懂80%的请把简历给我

    引言 半年时间,几千人参与,精选大厂前端面试高频 100 题,这就是「壹题」. 在 2019 年 1 月 21 日这天,「壹题」项目正式开始,在这之后每个工作日都会出一道高频面试题,主要涵盖阿里.腾讯 ...

  4. offer收割攻略,Web前端面试真题JavaScript系列(带详解)

    临近秋招,不少小伙伴开始了求职之路,面试是十分重要的考验,其次也离不开面试题.网上的面试题零零散散,十分混乱,正好我抽时间帮助大家总结一下.难易程度肯定是从简到难,今天是第一篇的续集--基础篇中的Ja ...

  5. web前端面试100题

    1.一些开放性题目 1.自我介绍:除了基本个人信息以外,面试官更想听的是你与众不同的地方和你的优势. 2.项目介绍 3.如何看待前端开发? 4.平时是如何学习前端开发的? 5.未来三到五年的规划是怎样 ...

  6. 前端面试35k题库2021-@莫成尘

    H5/C3/ES6/JS Html5 h5.css3.es6的新属性 h5新特性: 拖拽释放(Drag and drop) API 语义化更好的内容标签(header,nav,footer,aside ...

  7. 【前端面试知识题】- 3. HTML CSS

    序列号 内容 链接 1 前端知识面试题 - http&https(2022版) https://blog.csdn.net/qq_43061290/article/details/126651 ...

  8. 前端面试基础题总结 (必会)

    回答问题的原则: 能用量词, 尽可能用量词, 注意: 不要一直然后然后, 要有条理 推荐: 总分总结构 / 第一, 第二, 第三, 第四 ...0. 事件冒泡和捕获?事件冒泡:当子元素(事件源)事件触 ...

  9. 【面试题】2022前端面试真题

    中国电信集成(过了) vue生命周期 webpack打包机制 v-if v-show 如何实现一个深拷贝 敏捷开发的思维模式 牧原股份一面((过了,主动放弃二面) 讲一下react hooks内部实现 ...

最新文章

  1. LoadRunner之二“集合点”
  2. 在普通Java类里使用spring里注入的service、dao等
  3. Unity3D 学习教程 4 创建物体
  4. 814. Binary Tree Pruning
  5. 每日一函数2015/05/17 ---2
  6. Charles使用1
  7. pass information between XXX.Aspx and XXX.Aspx.cs
  8. 计算机网络 | 网络层 :IP协议详解
  9. redis分布式锁java代码_基于redis实现分布式锁
  10. Oracle Database 11g Express Edition使用限制,与其他版本的区别
  11. javascript中为某个对象(控件)绑定事件的几种方法
  12. python如何安装第三方库
  13. win7 IE9 internet explorer[IE] [IE 9]已停止工作
  14. linux cp 复制目录下文件到另一个目录下
  15. 如何在Win10中运行Win7小游戏 扫雷,蜘蛛纸牌,红心大战,纸牌,空当接龙?
  16. 漂亮的字体 手写_20种漂亮的草书和手写字体可供下载
  17. AutoRun机制详解
  18. iphone开发笔记一 mac os 10.7.2安装与配置
  19. switch语句查询水果价格
  20. linux mc服务器 mod_官方minecraft服务器简单开服方法[linux][minecraft1.5.2]

热门文章

  1. setup time和hold time
  2. ChatGPT深度体验记录,期待GPT-4(测试各领域知识,正常聊天,写代码,写诗歌,模拟人格,机器翻译,语法改错等)
  3. java实现购物券消费方案
  4. centos6.9 yum安装中出现Loading mirror speeds from cached hostfile No package......
  5. Code 39码与Code 128码区别
  6. pl sql 和if loop结构
  7. Session与Cookie的区别与联系
  8. 发明计算机作文300字,发明作文300字
  9. 用户权限影响瑞星安装
  10. vue实现仿网易云音乐客户端