前端面试题型汇总

目录

HTML

HTML语义化

的作用

SEO中的TDK

HTML5中新增标签

块级元素和内联元素

img中的alt和title的区别

title与h1的区别、b与strong的区别、i与em的区别

元标签

label标签的作用

iframe的缺点

HTML和XHTML的区别

repaint和reflow

为什么div+css的格式替代了table

CSS

css样式初始化

块级元素和内联元素样式区别

css的盒模型

伪类和伪元素

position各属性区别

display各属性区别

float浮动对元素的影响

display:none和visibility:hidden的区别

display,float,position的相互影响

样式中属性的继承

BFC块级格式化上下文

css hack

css选择器及其权重优先级

清除浮动的几种方法

css3过渡(transition)、变化(transform)、动画(animation)

 transition和animation的区别

媒体查询,@media

水平、垂直居中的几种方式

省略文本的样式

bix-sizing属性

双栏布局和三栏布局

css预处理,less和sass

css sprite

z-index属性 

src和href引入地址的区别

flex弹性布局

JavaScript

基本数据类型

undefined和null的区别

判断数据类型的方式(比较typeof与instanceof)

参数的按值传递的理解

执行环境和作用域链

模仿块级作用域

js原型和原型链

作用域链和原型链的区别

js创建对象的方式

js实现继承的方式

对闭包的理解

this指向问题 

模拟new实现创建对象

防抖函数

节流函数 

DOM操作

DOM0级和DOM2级的事件处理程序

事件冒泡和事件捕获

不同浏览器如何阻止事件冒泡

跨浏览器的事件对象EventUtil

事件委托及其好处

JSON和XML的对比

Ajax请求的实现

浏览器的同源策略

常用的跨域方案

cookie、localStorage、sessionStorage的区别

在地址栏里输入一个URL,到这个页面呈现出来,中间会发生什么?

call、bind、apply区别

get、post的区别

“ ===”、“ ==”的区别

同步和异步的区别

深拷贝

简易处理

复杂处理

js中import和require的区别

js拼接两个数组的方式

String、Number类型运算 

数组去重的几种方式

 

 

JS面试题

Vue面试题

vue的生命周期

v-for中:key的作用

组件中的data为什么是个函数

 虚拟DOM节点 

vue-cli 脚手架 目录 解析

MVVM是什么? 

MVVM的优缺点? 

Vue组件通信

computed和watch有什么区别?

Vue组件的按需加载

vue mixins和extends的区别

Webpack面试题

什么是Webpack

webpack与grunt、gulp的不同?

分别介绍bundle,chunk,module是什么

分别介绍什么是loader?什么是plugin?

什么 是模块热更新?

 如何可以自动生成webpack配置?

webpack-dev-server和http服务器如nginx有什么区别?

webpack和gulp区别(模块化与流的区别)

Git面试题

git和svn的优缺点。

Git 里面的 origin

fetch和merge和pull的区别

常用命令

浏览器和网络协议

http 和 https 有何区别

TCP传输的三次握手 

从输入URL到页面加载成功显示经历了什么 

常见的HTTP状态码

浏览器的内核分别是什么

优雅降级和渐进增强

浏览器是如何渲染页面

关于事件循环 

垃圾回收机制方式

Web攻击技术

性能优化




HTML

  • HTML语义化

  • 用正确的标签做正确的事情。
  • html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;即使在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的;
  • 搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO;
  • 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。
  • <!DOCTYPE>的作用

  • 不是一个HTML标签,是一个用于告诉浏览器当前HTML版本的指令
  • 告知浏览器按照何种规范解析页面
  •  添加了<!DOCTYPE>,就等同于开启了标准模式
  • SEO中的TDK

  • 在SEO中,所谓的TDK其实就是title、description、keywords这三个标签,这三个标签在网站的优化过程中,title标题标    签,description描述标签,keywords关键词标签。

  • SEO中TDK详细介绍

  • HTML5中新增标签

新增语义化标签

  • 块级元素和内联元素

常用的块级元素:

   address , center , div , dl ,, form , h1 , h2 , h3 , h4 , h5 , h6 , menu , ol , p , table , ul , li

常用内联的元素:

  a , b , br , em , font , img , input , label , select , small , span , textarea  

内联元素和块级元素的float属性区别

  • img中的alt和title的区别

  • alt是给搜索引擎识别,在图像无法显示时的替代文本;

  • title是关于元素的注释信息,主要是给用户解读。当鼠标放到文字或是图片上时有title文字显示。

  • (因为IE不标准)在IE浏览器中alt起到了title的作用,变成文字提示。在定义img对象时,将alt和title属性写全,可以保证在各种浏览器中都能正常使用。

  • title与h1的区别、b与strong的区别、i与em的区别

  • title属性没有明确意义只表示是个标题,H1则表示层次明确的标题,对页面信息的抓取也有很大的影响;
  • strong是标明重点内容,有语气加强的含义,使用阅读设备阅读网络时:<strong>会重读,而<B>是展示强调内容。
  • i内容展示为斜体,em表示强调的文本;
  • <meta>元标签

提供有关页面的元信息,比如针对搜索引擎和更新频度的描述和关键词。

  • label标签的作用

label标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。

<label for="Name">Number:</label>

<input type="text" id="Name"/>

  • iframe的缺点

  • 会阻塞主页面的Onload事件;
  • 搜索引擎的检索程序无法解读这种页面,不利于SEO;
  • iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。

使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript。动态给iframe添加src属性值,这样可以绕开以上两个问题。

  • HTML和XHTML的区别

  • XHTML 元素必须被正确地嵌套。

错误:<p><span>this is example.</p></span>

正确:<p><span>this is example.</span></p>

  • XHTML 元素必须被关闭。

错误:<p>this is example.

正确:<p>this is example.</p>

  • 标签名必须用小写字母。

错误:<P>this is example.<P>

正确:<p>this is example.</p>

  • 空标签也必须被关闭

错误:<br>

正确:<br/>

  • XHTML 文档必须拥有根元素。

所有的 XHTML 元素必须被嵌套于 <html> 根元素中。

  • repaint和reflow

  • repaint就是重绘,reflow就是回流

  • 在性能优先的前提下,reflow的性能消耗要比repaint的大。

  •  repaint是某个dom元素进行重绘,reflow是整个页面进行重排,也就是对页面所有的dom元素渲染。

  •  repaint的触发:

  1)不涉及任何dom元素的排版问题的变动为repaint,例如元素的color、text-align等改变。

  2)color的修改,text-align的修改,a:hover也会造成重绘,伪类引起的颜色等变化不会导致页面的回流,仅仅会触发重绘。

  •   reflow的触发:

 1)width、height、border、margin、padding的修改

 2)通过hover造成元素表现的改动,如display:none会导致回流

 3)appendChild等dom元素操作。

 4)font类style 的修改。

 5)   background的修改,现在经过浏览器厂家的优化,部分background的修改只会触发repaint。
 

  • 如何尽量避免回流reflow:

a、尽可能在dom末稍通过修改class来修改元素的style属性,尽可能减少受影响的dom元素。

b、避免设置多项内联样式,使用常用的class方式进行设置样式,以避免设置样式时访问dom的低效率。

c、设置动画元素position属性为fixed或absolute:由于当前元素从dom流中独立出来,因此受影响的只有当前元素。

d、牺牲平滑度满足性能:动画精度太强,会造成更多的repaint/reflow,牺牲精度,能满足性能的损耗,获取性能和平滑度的平衡。

f、避免使用table进行布局,table每个元素的大小以及内容的改变,都会导致整个table进行重新计算,造成大幅度的repaint或者reflow。改用div则可以针对性的repaint和避免不必要的reflow。

g、避免在css中使用运算式
 

  • 为什么div+css的格式替代了table

  • div+css编写出来的文件比用table边写出来的文件小。
  • table必须在页面完全加载后才显示,div则是逐行显示。
  • table的嵌套性太多,没有div简洁

CSS

  • css样式初始化

  • 原因

因为浏览器的兼容的问题,不同浏览器有些标签的默认值是不同的,如果没有CSS初始化往往会出现浏览器之间的页面显示差异。

  • 弊端

初始化样式会对SEO有一定的影响

  • 淘宝初始化样式
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin:0; padding:0; }
body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; }
h1, h2, h3, h4, h5, h6{ font-size:100%; }
address, cite, dfn, em, var { font-style:normal; }
code, kbd, pre, samp { font-family:couriernew, courier, monospace; }
small{ font-size:12px; }
ul, ol { list-style:none; }
a { text-decoration:none; }
a:hover { text-decoration:underline; }
sup { vertical-align:text-top; }
sub{ vertical-align:text-bottom; }
legend { color:#000; }
fieldset, img { border:0; }
button, input, select, textarea { font-size:100%; }
  • 块级元素和内联元素样式区别

  • 内联元素:
  1. 内联元素(inline)不会独占一行,相邻的内联元素会排在同一行。其宽度随内容的变化而变化。 

  2. 内联元素不可以设置宽高 

  3. 内联元素可以设置margin,padding,但只在水平方向有效。

 

  • 块状元素:
  1. 块级元素会独占一行,默认情况下宽度自动填满其父元素宽度 
  2. 块级元素可以设置宽高 
  3. 块级元素可以设置margin,padding
  • 内联块状元素 inline-block:

表现为同行显示并可修改宽高内外边距等属性。简单来说就是将对象呈现为inline对象,但是对象的内容作为block对象呈现(可以设置宽高和margin值)。之后的内联对象会被排列在同一内联。比如我们可以给一个span标签设置inline-block属性值,使其既具有block的宽度高度特性又具有inline的同行特性。

  • css的盒模型

 IE 盒子模型、W3C 盒子模型;

  • 盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border);
  • 区  别: IE的content部分把 border 和 padding计算了进去;
  • 伪类和伪元素

  • 伪类

伪类选择元素基于的是当前元素处于的状态,或者说元素当前所具有的特性,而不是元素的id、class、属性等静态的标志。由于状态是动态变化的,所以一个元素达到一个特定状态时,它可能得到一个伪类的样式;当状态改变时,它又会失去这个样式。由此可以看出,它的功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类。

:link

伪类将应用于未被访问过的链接,与:visited互斥。

:hover

伪类将应用于有鼠标指针悬停于其上的元素。

:active

伪类将应用于被激活的元素,如被点击的链接、被按下的按钮等。

:visited

伪类将应用于已经被访问过的链接,与:link互斥。

  • 伪元素

与伪类针对特殊状态的元素不同的是,伪元素是对元素中的特定内容进行操作,它所操作的层次比伪类更深了一层,也因此它的动态性比伪类要低得多。实际上,设计伪元素的目的就是去选取诸如元素内容第一个字(母)、第一行,选取某些内容前面或后面这种普通的选择器无法完成的工作。它控制的内容实际上和元素是相同的,但是它本身只是基于元素的抽象,并不存在于文档中,所以叫伪元素。

:first-letter

伪元素的样式将应用于元素文本的第一个字(母)。

:first-line

伪元素的样式将应用于元素文本的第一行。

:before

在元素内容的最前面添加新内容。

:after

在元素内容的最后面添加新内容。

  • position各属性区别

  • relative  相对定位

不影响元素本身特性(无论区块元素还是内联元素会保留其原本特性)

 不会使元素脱离文档流(元素原本位置会被保留,即改变位置也不会占用新位置)

没有定位偏移量时对元素无影响(相对于自身原本位置进行偏移)

用z-index样式的值可以改变一个定位元素的层级关系,从而改变元素的覆盖关系,值越大越在上面(z-index只能在position属性值为relative或absolute或fixed的元素上有效。) (两个都为定位元素,后面的会覆盖前面的定位)

  • absolute  绝对定位

使元素完全脱离文档流(在文档流中不再占位)

使内联元素在设置宽高的时候支持宽高(改变内联元素的特性)

使区块元素在未设置宽度时由内容撑开宽度(改变区块元素的特性)

相对于最近一个有定位的父元素(定位属性除static之外)偏移(若其父元素没有定位则逐层上找,直到document)

相对定位一般配合绝对定位使用(将父元素设置相对定位,使其相对于父元素偏移)

可使用z-index改变显示层级

  • fixed  固定定位

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

  • static  默认值

默认布局。元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。

  • sticky  粘性定位

粘性定位,该定位基于用户滚动的位置。

它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。

  • display各属性区别

  • block

单独占一行,可以设置width,height,maigin四个方向,padding四个方向;

元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度;

  • inline

多个内联元素占同一行,直到放不下才换行。设置width,height,margin-top,margin-bottom,padding-top,padding-bottom无效;(通过添加背景颜色可以看出有设置上述属性,但是不会影响其他元素的布局)

  • inline-block

像inline一样放置(比如和它相邻的元素处在同一行),像block一样表现。比如:input,select,img等。

float属性、position:absolute绝对定位 和上述替换元素表现为inline-block

  • none

inline和inline-block出现的问题

水平呈现的元素间,换行显示或空格分隔的情况下会有间距

解决方法

  • 相邻inline-block元素不分行写,写在同一行并且中间无空格
  • select父元素使用font-size:0
  • float浮动对元素的影响

float(对块级、行内、内联块元素的影响)

  • display:none和visibility:hidden的区别

  • display:none是彻底消失,不在文档流中占位,浏览器也不会解析该元素;
  • visibility:hidden是视觉上消失了,可以理解为透明度为0的效果,在文档流中占位,浏览器会解析该元素;
  • 使用visibility:hidden比display:none性能上要好,display:none切换显示时,页面产生回流(当页面中的一部分元素需要改变规模尺寸、布局、显示隐藏等,页面重新构建,此时就是回流。所有页面第一次加载时需要产生一次回流),而visibility切换是否显示时则不会引起回流。
  • display,float,position的相互影响

 position跟display、overflow、float这些特性相互叠加后会怎么样?

display属性规定元素应该生成的框的类型;position属性规定元素的定位类型;float属性是一种布局方式,定义元素在哪个方向浮动。
类似于优先级机制:position:absolute/fixed优先级最高,有他们在时,float不起作用,display值需要调整。float 或者absolute定位的元素,只能是块元素或表格。

  • 样式中属性的继承

一、无继承性的属性

1、display:规定元素应该生成的框的类型

2、文本属性

vertical-align:垂直文本对齐

text-decoration:规定添加到文本的装饰

text-shadow:文本阴影效果

white-space:空白符的处理

unicode-bidi:设置文本的方向

3、盒子模型的属性:width、height、margin 、margin-top、margin-right、margin-bottom、margin-left、border、border-style、border-top-style、border-right-style、border-bottom-style、border-left-style、border-width、border-top-width、border-right-right、border-bottom-width、border-left-width、border-color、border-top-color、border-right-color、border-bottom-color、border-left-color、border-top、border-right、border-bottom、border-left、padding、padding-top、padding-right、padding-bottom、padding-left

4、背景属性:background、background-color、background-image、background-repeat、background-position、background-attachment

5、定位属性:float、clear、position、top、right、bottom、left、min-width、min-height、max-width、max-height、overflow、clip、z-index

6、生成内容属性:content、counter-reset、counter-increment

7、轮廓样式属性:outline-style、outline-width、outline-color、outline

8、页面样式属性:size、page-break-before、page-break-after

9、声音样式属性:pause-before、pause-after、pause、cue-before、cue-after、cue、play-during

二、有继承性的属性

1、字体系列属性

font:组合字体

font-family:规定元素的字体系列

font-weight:设置字体的粗细

font-size:设置字体的尺寸

font-style:定义字体的风格

font-variant:设置小型大写字母的字体显示文本,这意味着所有的小写字母均会被转换为大写,但是所有使用小型大写字体的字母与其余文本相比,其字体尺寸更小。

font-stretch:对当前的 font-family 进行伸缩变形。所有主流浏览器都不支持。

font-size-adjust:为某个元素规定一个 aspect 值,这样就可以保持首选字体的 x-height。

2、文本系列属性

text-indent:文本缩进

text-align:文本水平对齐

line-height:行高

word-spacing:增加或减少单词间的空白(即字间隔)

letter-spacing:增加或减少字符间的空白(字符间距)

text-transform:控制文本大小写

direction:规定文本的书写方向

color:文本颜色

3、元素可见性:visibility

4、表格布局属性:caption-side、border-collapse、border-spacing、empty-cells、table-layout

5、列表布局属性:list-style-type、list-style-image、list-style-position、list-style

6、生成内容属性:quotes

7、光标属性:cursor

8、页面样式属性:page、page-break-inside、windows、orphans

9、声音样式属性:speak、speak-punctuation、speak-numeral、speak-header、speech-rate、volume、voice-family、pitch、pitch-range、stress、richness、、azimuth、elevation

三、所有元素可以继承的属性

1、元素可见性:visibility

2、光标属性:cursor

四、内联元素可以继承的属性

1、字体系列属性

2、除text-indent、text-align之外的文本系列属性

五、块级元素可以继承的属性

1、text-indent、text-align

  • BFC块级格式化上下文

满足下列css声明之一的元素便会生成BFC

  • 根元素
  • float的值不为none
  • overflow的值不为visible(常用 overflow:hidden创建BFC区域)
  • display的值为inline-block、table-cell、table-caption
  • position的值不为static或relative

BFC(块级格式上下文)

  • css hack

由于不同厂商的流览器或某浏览器的不同版本(如IE6-IE11,Firefox/Safari/Opera/Chrome等),对CSS的支持、解析不一样,导致在不同浏览器的环境中呈现出不一致的页面展现效果。这时,我们为了获得统一的页面效果,就需要针对不同的浏览器或不同版本写特定的CSS样式,我们把这个针对不同的浏览器/不同版本写相应的CSS code的过程,叫做CSS hack

CSS hack

  • css选择器及其权重优先级

1.id选择器( # myid)

2.类选择器(.myclassname)

3.标签选择器(div, h1, p)

4.相邻选择器(h1 + p)

5.子选择器(ul > li)

6.后代选择器(li a)

7.通配符选择器( * )

8.属性选择器(a[rel = "external"])

9.伪类选择器(a:hover, li:nth-child)

 

优先级:

  1. important的权值为最高 1,0,0,0

  2. ID的权值为 0,1,0,0

  3. 类的权值为 0,0,1,0

  4. 标签的权值为 0,0,0,1

  5. 伪类选择的权值为 0,0,1,0

  6. 通配选择符的权值 0,0,0,0

 

比较同一级别的个数,数量多的优先级高,如果相同即比较下一级别的个数:

important > 内联 > ID > 类| 伪类| 属性选择 > 标签 | 伪元素 > 通配符 > 继承

这也就解释了为什么11个标签的定义会比不上1个类的定义,1个类加11个标签会比不上2个类的权重高。

CSS选择器、优先级与匹配原理

  • 清除浮动的几种方法

什么时候需要清除浮动

浮动元素碰到包含它的边框或者浮动元素的边框停留。由于浮动元素不在文档流中,所以文档流的块框表现得就像浮动框不存在一样。浮动元素会漂浮在文档流的块框上。
浮动带来的问题:

  1. 父元素的高度无法被撑开,影响与父元素同级的元素
  2. 与浮动元素同级的非浮动元素(内联元素)会跟随其后
  3. 若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构。

清除浮动的方法:

1.父级div定义 height

原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。

优点:简单、代码少、容易掌握

缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题

 

2,结尾处加空div标签 clear:both

原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度

优点:简单、代码少、浏览器支持好、不容易出现怪问题

缺点:不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不好

 

3,父级div定义 伪类:after 和 zoom

原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题

优点:浏览器支持好、不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等)

缺点:代码多、不少初学者不理解原理,要两句代码结合使用才能让主流浏览器都支持

.clearfix:after{
  display:table;
  clear:both;
  content:"";
  height:0px;
}
.clearfix {*zoom:1;} /*照顾IE6,IE7就可以了*/

 

4,父级div定义 overflow:hidden(利用BFC检测区域的浮动的盒子高度

原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden生成BFC时,浏览器会自动检查浮动区域的高度

优点:简单、代码少、浏览器支持好

缺点:不能和position配合使用,因为超出的尺寸的会被隐藏。

  • 动画(animation)

animation动画的基本使用方式

  •  transition和animation的区别

  • css3过渡(transition)、变化(transform)、动画(animation)
  • transition是过渡,animation是动画。transition只能从一种状态过渡到另外一种状态,animation可以定制复杂动画,可以定义动画的区间等。
  • transition必须通过一些行为才能触发(js或者伪类来触发),animation的话直接就可以触发。
  • 媒体查询,@media

菜鸟教程——@media

利用CSS中的@media实现响应式布局

  • link和@import 导入css文件的区别
  • link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;
  • @import属于CSS范畴,只能加载CSS。
  • link引用CSS时,在页面载入时同时加载;
  • @import需要页面网页完全载入以后加载。
  • link是XHTML标签,无兼容问题;
  • @import是在CSS2.1提出的,低版本的浏览器不支持。
  • link支持使用Javascript控制DOM去改变样式;
  • @import不支持使用Javascript控制DOM去改变样式。
  • 水平、垂直居中的几种方式

html中div如何水平和垂直居中的几种css方法代码

干货!各种常见布局实现

  • 省略文本的样式

/*省略文本*/
white-space:nowrap; 
overflow: hidden;
text-overflow: ellipsis;
  • box-sizing属性

box-sizing属性可以指定盒子模型种类

content-box指定盒子模型为W3C的标准盒子模型

è¿éåå¾çæè¿°

border-box指定盒子模型为IE盒子模型(width包含border和padding)

  • 双栏布局和三栏布局

干货!各种常见布局实现

  • css预处理,less和sass

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

详说css与预处理器

  • css sprite

原理:

将许多的小图片整合到一张大图片中,利用css中的background-image属性,background-position属性定位某个图片位置,来达到在大图片中引用某个部位的小图片的效果。

优点:

  • 减少网页的http请求,提升网页加载速度。
  • 合并多张小图片成大图,能减少字节总数(大图大小<=多张小图大小).

缺点:

  • 前期需要处理图片将小图合并,多些许工程量。
  • 对于需要经常改变的图片维护起来麻烦。
  • z-index属性 

z-index失效的原因

注意点:

         (1):z-index属性只作用在被定位了的元素上。所以如果你在一个没被定位的元素上使用z-index的话,是不会有效果的.

          (2)同一个父元素下的元素的层叠效果会受父元素的z-index影响,如果父元素的z-index值很小,那么子元素的z-index值很大也不起作用

失效的情况:

1、父标签 position属性为relative;

2、问题标签无position属性(不包括static);

3、问题标签含有浮动(float)属性。

4、问题标签的祖先标签的z-index值比较小

解决方法:

第一种:  position:relative改为position:absolute;

第二种:浮动元素添加position属性(如relative,absolute等);

第三种:去除浮动。

第四种:提高父标签的z-index值

  • src和href引入地址的区别

  • href表示超文本引用,用在link和a等元素上,href是引用和页面关联,是在当前元素和引用资源之间建立联系。
  • src表示引用资源,表示替换当前元素,用在img,script,iframe上,src是页面内容不可缺少的一部分。
  •  
  • src是source的缩写,是指向外部资源的位置,指向的内部会迁入到文档中当前标签所在的位置;在请求src资源时会将其指向的资源下载并应用到当前文档中,例如js脚本,img图片和frame等元素。<script src="js.js"></script>当浏览器解析到这一句的时候会暂停其他资源的下载和处理,直至将该资源加载,编译,执行完毕,图片和框架等元素也是如此,类似于该元素所指向的资源嵌套如当前标签内,这也是为什么要把js饭再底部而不是头部。
  • <link href="common.css" rel="stylesheet"/>当浏览器解析到这一句的时候会识别该文档为css文件,会下载并且不会停止对当前文档的处理,这也是为什么建议使用link方式来加载css而不是使用@import。
  • flex弹性布局

Flex 布局语法教程

JavaScript

  • 基本数据类型

  • undefined 
  • null 
  • string 
  • boolean 
  • number 
  • symbol(ES6)

一种引用类型 

  • Object
  • undefined和null的区别

  • null: 代表“空值”,代表一个空对象指针,使用typeof运算得到 “object”,所以可以认为它是一个特殊的对象值。
  • undefined: Undefined类型,当一个声明了一个变量未初始化时,得到的就是undefined。

null是javascript的关键字,可以认为是对象类型,它是一个空对象指针,和其它语言一样都是代表“空值”,

不过 undefined 却是javascript才有的。

undefined是在ECMAScript第三版引入的,为了区分空指针对象和未初始化的变量,它是一个预定义的全局变量。

没有返回值的函数返回为undefined,没有实参的形参也是undefined。

  • 判断数据类型的方式(比较typeof与instanceof)

相同点:

  • JavaScript 中 typeof 和 instanceof 常用来判断一个变量是否为空,或者是什么类型的。

typeof的定义和用法:返回值是一个字符串,用来说明变量的数据类型。

Instanceof定义和用法:instanceof 用于判断一个变量是否属于某个对象的实例,返回布尔值

  • typeof 一般只能返回如下几个结果:number,boolean,string,function,object,undefined。
  • typeof 来获取一个变量是否存在,如 if(typeof a!="undefined"),而不要去使用 if(a) 因为如果 a 不存在(未声明)则会出错。
  • 对于 Array,Null 等特殊对象使用 typeof 一律返回 object,这正是 typeof 的局限性。

常见面试题:判断JS数据类型的四种方法

  • 参数的按值传递的理解

ECMAScript中所有函数的参数都是按值传递的。

javascript 参数按值传递的理解

  • 执行环境和作用域链

执行环境:

当JavaScript解释器初始化执行代码时,它首先默认进入全局执行环境;从此刻开始,函数的每次调用都会创建一个新的执行环境;每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中,在函数执行完后栈将其环境弹出,保存在其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出也随之销毁,例如关闭网页或退出浏览器)

作用域链:

当代码在一个环境中执行时,会创建变量对象的一个作用域链,作用域链中的下一个变量对象包含(外部)环境,一直延续到全局执行环境,全局执行环境的变量对象始终是作用域链中的最后一个对象。

简述一下作用域链

       访问一个变量属性时先在当前内部作用域中查找,未找到时就会到外部作用域进行往上查找,直到全局作用域为止,由此形成作用域链。

  • 模仿块级作用域

  • 使用立即执行函数
  • function函数作用域
  • es6中的let、const命令创建
  • js原型和原型链

简述一下原型链:

       所有函数都有一个prototype属性,所有引用类型(对象)都有__proto__属性,当对象调用当前实例不存在的属性和函数的时候就会沿着__proto__属性向上查找prototype原型对象中的属性和函数,直到Object原型对象为止,由此形成原型链。

javascript深入学习原型到原型链

prototype和__proto__的区别

  • 作用域链和原型链的区别

  • 作用域是针对变量的
  • 原型链是针对构造函数的

javascript中作用域链和原型链的区别

  • js创建对象的方式

  • 工厂模式
  • 构造函数模式
  • 原型模式
  • 组合模式
  • 寄生构造函数模式
  • 稳妥构造函数模式

javascript创建对象的方式

  • js实现继承的方式

  • 原型链继承
  • 借用构造函数继承
  • 组合继承
  • 原型式继承
  • 寄生式继承
  • 寄生组合式继承

javascript继承的方式

  • 对闭包的理解

什么是闭包:

由于作用域的关系,我们在函数外部是无法直接访问到函数内部的变量的,但是函数内部可以把这个变量传给全局变量或者返回出来,这样外部作用域就可以访问函数内部作用域的变量了;

简单的说,闭包就是有权限访问另一个函数内部作用域的变量的函数;

优点:

主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染

缺点:

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

练习题:

  • this指向问题 

this 永远指向最后调用它的那个对象

  • 在调用函数时使用new关键字,函数内的this是一个全新的对象。
  • 如果applycallbind方法用于调用、创建一个函数,函数内的 this 就是作为参数传入这些方法的对象。
  • 当函数作为对象里的方法被调用时,函数内的this是调用该函数的对象。比如当obj.method()被调用时,函数内的 this 将绑定到obj对象。
  • 如果调用函数不符合上述规则,那么this的值指向全局对象(global object)。浏览器环境下this的值指向window对象,但是在严格模式下('use strict'),this的值为undefined
  • 如果符合上述多个规则,则较高的规则(1 号最高,4 号最低)将决定this的值。
  • ES6的箭头函数,将忽略上面的所有规则,this被设置为它被创建时的上下文。

改变 this 指向的方法:

  • 使用 ES6 的箭头函数
  • 在函数内部使用 _this = this
  • 使用 applycallbind
  • new 实例化一个对象

javascript深入学习this指向问题

简述JavaScript中的this

  • 模拟new实现创建对象

通过new创建对象经历4个步骤

  1. 创建一个新Object对象;[var o = {};]
  2. 将构造函数的作用域赋给新对象(因此this指向了这个新对象)执行构造函数中的代码(为这个新对象添加属性);       [Person.apply(o)] [Person原来的this指向的是window]
  3. 为其绑定原型对象
  4. 返回新生成的对象
     
  • 防抖函数

防抖:在高频发的事件调用时,每次将定义好的定时器清除掉,只有当高频发事件调用最后一次的时候,由于没有再调用该事件函数,没有清除定义的定时器,那么定时器将正常工作,即定时器等待时间内连续调用10次后显示1,连续调用20次后显示的还是1。

通俗来讲就是,你要我在30s内搬100块砖,我偷懒,我结束时才搬一块。

主要用于 防止表单重复提交。


javascript的防抖和节流

  • 节流函数 

节流:在高频发的事件调用时,不会清除定义好的定时器。假设你的定时器为1s,加入if判断语句,如果你高频发事件的调用间隔小于1s,那么你在这1s的定时器等待时间内调用的次数都当成一次,即连续调用10次后如果花了三秒钟则显示3,连续调用20次后如果花了三秒钟那么也显示3,就是看你的调用时间。注意,将若干函数调用合成为一次(稀释函数的执行频率),并在给定时间过去之后,调用一次(仅仅只会调用一次)。

通俗来讲就是,你要我在30s内搬100块砖,我搬,不过我每1s(定时器范围)才搬一块,多了我不干,所以我最后才搬了30块砖。

主要用于搜索框请求频率的稀释。


javascript的防抖和节流

  • DOM操作

原生JS中DOM节点相关API合集

  • DOM0级和DOM2级的事件处理程序

DOM0级

分为2个:一是在标签内写onclick事件

      二是在JS写οnclick=function(){}函

  • <input id="myButton" type="button" value="Press Me" οnclick="alert('thanks');" >
  • document.getElementById("myButton").onclick = function () {
        alert('thanks');
    }

为什么没有1级DOM

DOM级别1于1998年10月1日成为W3C推荐标准。1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。在2级DOM中除了定义了一些DOM相关的操作之外还定义了一个事件模型 ,这个标准下的事件模型就是我们所说的2级DOM事件模型 。

DOM2级

有两个用来添加和移除事件处理程序的函数:addEventListener()和removeEventListener()。

它们都有三个参数:第一个参数是事件名(如click);

         第二个参数是事件处理程序函数;

           第三个参数如果是true则表示在捕获阶段调用,为false表示在冒泡阶段调用。

  • addEventListener():可以为元素添加多个事件处理程序,触发时会按照添加顺序依次调用。
  • removeEventListener():不能移除匿名添加的函数。
document.getElementById("myTest").attachEvent("onclick", function(){alert(1)});
//IE下使用attachEvent(),等价于
document.getElementById("myTest").addEventListener("click", function(){alert(1)}, false);

dom0(属性绑定,兼容性好)和dom2(函数绑定,兼容性不好,万恶的IE事件绑定的区别

  • 如果定义了两个dom0级事件,dom0级事件会覆盖
  • dom2不会覆盖,会依次执行
  • dom0和dom2可以共存,不互相覆盖,但是dom0之间依然会覆盖
  • 为啥不直接都用dom0呢??按照W3C标准所推崇的——结构,行为,样式分离。  DOM0级的耦合度是最高的,所以说是其中最“笨”的方法。所以说这里要依次判断,如果浏览器能用好方法就用好方法,不然在降低标准,不然再降,到DOM0就是极限了。

DOM0级事件处理和DOM2级事件处理

  • 事件冒泡和事件捕获

事件冒泡(常用)

IE中采用的事件流是事件冒泡,先从具体的接收元素,然后逐步向上传播到不具体的元素。

事件捕获(不常用)

先由不具体的元素接收事件,最具体的节点最后才接收到事件。

DOM事件流

  • 不同浏览器如何阻止事件冒泡

  • event.stopPropagation();||event.cancelBubble=true;

事实上stoppropagation和cancelBubble的作用是一样的,都是用来阻止浏览器默认的事件冒泡行为。不同之处在于stoppropagation属于W3C标准,适用于Firefox等浏览器,但是不支持IE浏览器(IE8以下)。相反cancelBubble不符合W3C标准,而且只支持IE浏览器。所以很多时候,我们都要结合起来用。不过,cancelBubble在新版本chrome,opera浏览器中已经支持。

  • event.preventDefault()阻止标签默认事件; 

JS阻止冒泡和取消默认事件(默认行为)

javascript 事件冒泡及其阻止方法

  • 跨浏览器的事件对象EventUtil

在JavaScript中,DOM0级、DOM2级与旧版本IE(8-)为对象添加事件的方法不同

为了以跨浏览器的方式处理事件,需要编写一段“通用代码”,即跨浏览器的事件处理程序

习惯上,这个方法属于一个名为EventUtil的对象

编写并使用该对象后,可保证处理事件的代码能在大多数浏览器下一致的运行

EventUtil对象的封装及其使用

  • 事件委托及其好处

把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。

优点:

  • 减少内存消耗
  • 动态绑定事件(因为事件是绑定在父层的,和目标元素的增减是没有关系的)

局限性:

  • focus、blur 之类的事件本身没有事件冒泡机制,所以无法委托
  • mousemove、mouseout 这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也不适合事件委托

JavaScript 事件委托 (事件代理) 详解

  • JSON和XML的对比

JSON对象的两个很重要的方法

JSON.parse() //JSON字符串转换为JSON对象

JSON.stringify() //JSON对象转化为字符串
  • JSON相对于XML来讲,数据的体积小,传递的速度更快些
  • JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互
  • XML对数据描述性比较好;
  • JSON的速度要远远快于XML

JSON用法

  • Ajax请求的实现

原生Ajax和jQuery版本的使用

  • 浏览器的同源策略

同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。是用于隔离潜在恶意文件的重要安全机制

属于同源,必须同时满足以下三个相同

  • 域名
  • 协议
  • 端口
  • 常用的跨域方案

  • JSONP:

Ajax不能跨域,但是script标签和img标签都可以跨域。动态创建script,即新创建script标签,将回调函数名通过后缀的方式写入url地址,服务端收到后进行处理,将包含有json数据格式的对象封装在这个回调函数的参数里里面。客户端收到这个动态script的有参数的回调函数调用,执行操作,更新数据。

缺点:

  1、无法发送post请求

  2、要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。

JSONP原理及详细使用(含jQuery调用)


  • CORS(跨域资源共享)

CORS的整个过程都由浏览器自动完成,前端无需做任何设置,跟平时发送ajax请求并无差异。实现CORS的关键在于服务器,只要服务器实现CORS接口,就可以实现跨域通信。

CORS原理及详细使用

CORS 使用详解 + 例子

  • cookie、localStorage、sessionStorage的区别

存储大小:

cookie数据大小不能超过4k。

sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

生命周期:

localStorage    存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;

sessionStorage  数据在当前浏览器窗口关闭后自动删除。

注意:

通过点击链接(或者用了 window.open)打开的新标签页之间是属于同一个 session 的,但新开一个标签页总是会初始化一个新的 session,即使网站是一样的,它们也不属于同一个 session。


cookies,sessionStorage 和 localStorage 的区别

  • 在地址栏里输入一个URL,到这个页面呈现出来,中间会发生什么?

  1. 输入url后,首先需要找到这个url域名的服务器ip,为了寻找这个ip,浏览器首先会寻找缓存,查看缓存中是否有记录,缓存的查找记录为:浏览器缓存-》系统缓存-》路由器缓存,缓存中没有则查找系统的hosts文件中是否有记录,如果没有则查询DNS服务器用以解析ip地址。
  2. 得到服务器的ip地址后,浏览器根据这个ip以及相应的端口号,构造一个http请求,这个请求报文会包括这次请求的信息,主要是请求方法,请求说明和请求附带的数据,并将这个http请求封装在一个tcp包中,这个tcp包会依次经过传输层,网络层,数据链路层,物理层到达服务器,服务器解析这个请求来作出响应,返回相应的html给浏览器。
  3. 因为html是一个树形结构,浏览器根据这个html来构建DOM树,在dom树的构建过程中如果遇到JS脚本和外部JS连接,则会停止构建DOM树来执行和下载相应的代码,这会造成阻塞,这就是为什么推荐JS代码应该放在html代码的后面,之后根据外部央视,内部央视,内联样式构建一个CSS对象模型树CSSOM树,构建完成后和DOM树合并为渲染树,这里主要做的是排除非视觉节点,比如script,meta标签和排除display为none的节点,之后进行布局,布局主要是确定各个元素的位置和尺寸。
  4. 之后是渲染页面,因为html文件中会含有图片,视频,音频等资源,在解析DOM的过程中,遇到这些都会进行并行下载,浏览器对每个域的并行下载数量有一定的限制,一般是4-6个,当然在这些所有的请求中我们还需要关注的就是缓存,缓存一般通过Cache-Control、Last-Modify、Expires等首部字段控制。 
  • callbindapply区别

call与apply都属于Function.prototype的一个方法,所以每个function实例都有call、apply属性;

作用
call()方法和apply()方法的作用相同:改变this指向。

区别(接收参数的方式不同)

  • call():第一个参数是对象,其余参数都直接传递给函数(参数必须逐个列举出来)。
  • apply():第一个参数是对象,传递给函数的是参数数组或者arguments类数组对象。

传递参数并非call()和apply()真正的作用,真正强大的地方是能修改函数运行的作用域(改变this指向)

javascript中的call()与apply()

  • getpost的区别

  • Get 请求能缓存,Post 不能
  • Post 相对 Get 安全,因为Get 请求都包含在 URL 里,且会被浏览器保存历史纪录,Post 不会,但在抓包的情况下都是一样的。
  • Post 可以通过 request body来传输比 Get 更多的数据,Get 没有这个技术
  • URL有长度限制,会影响 Get 请求,但是这个长度限制是浏览器规定的,不是 RFC 规定的
  • Post 支持更多的编码类型且不对数据类型限制
  • “ ===”、“ ==”的区别

  • ==,当且仅当两个运算数相等时,它返回 true,即不检查数据类型
  • ===,只有在无需类型转换运算数就相等的情况下,才返回 true,需要检查数据类型
  • 同步和异步的区别

同步是阻塞模式,异步是非阻塞模式。

  • 同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
  • 异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
  • JS模块化的好处

  • 执行上下文

  • 深拷贝

  • 浅拷贝是指创建一个对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,那么拷贝的就是基本类型的值,如果属性是引用类型,那么拷贝的就是内存地址,所以如果其中一个对象修改了某些属性,那么另一个对象就会受到影响。
  • 深拷贝是指从内存中完整地拷贝一个对象出来,并在堆内存中为其分配一个新的内存区域来存放,并且修改该对象的属性不会影响到原来的对象。

深拷贝和浅拷贝的实现方式分别有哪些?

  • 浅拷贝:(1) Object.assign的方式 (2) 通过对象扩展运算符 (3) 通过数组的slice方法 (4) 通过数组的concat方法。
  • 深拷贝:(1) 通过JSON.stringify来序列化对象 (2) 手动实现递归的方式

使用变量 a 拷贝对象 b,改变 a 中的值 b 中的值也会跟着改变,这叫做浅拷贝。要想让 a 独立于 b 就需要深拷贝。(非基本类型)

简易处理

function deepClone() {
    return JSON.parse(JSON.stringify(obj))
}复制代码

既然是简易处理就有他的不足,上面主要是用了 JSON 的序列化和反序列化。而 JSON 是不支持function和 undefined 的,因此碰到这些情况会缺失,但是已经能够满足大部分情况了。

复杂处理

Object.assign  (伪深度拷贝,只能拷贝第一层

定义:将源对象(source)的所有可枚举属性,复制到目标对象(target)

用法:

合并多个对象
var target = { a: 1, b: 1 };
var source1 = { b: 2, c: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
复制代码

完全深拷贝就需要采用递归的方式了

function clone(obj) {

    function whichType(o) {
        if (o === null) return "Null";
        if (o === undefined) return "Undefined";
        return Object.prototype.toString.call(o).slice(8, -1); //返回数据类型
    }

    var result;

    var oType = whichType(obj);
    if (oType === "Object") {
        result = {};
    } else if (oType === "Array") {
        result = [];
    } else {
        return obj;
    }

    for (var key in obj) {
        // key值为 对象的key值, 数组的下标值
        var copy = obj[key];
        if (whichType(copy) == "Object" || whichType(copy) == "Object") {
            result[key] = clone(copy); //递归调用
        } else {
            result[key] = copy; //基本类型直接返回
        }
    }
    return result;
}

递归实现深拷贝解析 (面试回答)

为什么要实现深拷贝呢?对于复杂数据类型,浅拷贝引用的是内存地址,当修改拷贝的数据时会影响原来的数据,因此复杂数据类型需要使用深拷贝来克隆数据。

为什么序列化和反序列化不行呢? JSON 是不支持function和 undefined 的,因此碰到这些情况会缺失,只能使用递归实现深拷贝。

如何实现数据深拷贝的递归方式呢?深拷贝的递归实现方式,首先需要判断传入的数据的类型,对于基本数据类型或者 null

 和 undefined 则直接返回,对于复杂数据类型(Array和Object),使用 Object.prototype.toString.call (数据) 的方式获取到数据类型,然后使用 for in 循环来得到 复杂数据类型的每个属性值(for in 取出的是对象的key值,数组的下标值),对于每个属性值,如果还是复杂数据类型(嵌套对象等),则继续调用此函数递归求解到基本数据类型为止,如果是基本数据类型,则返回,最后返回克隆的数据即可实现深拷贝。

  • js中import和require的区别

ES6标准发布后,module成为标准,标准使用是以export指令导出接口,以import引入模块。但是在我们一贯的node模块中,我们依然采用的是CommonJS规范,使用require引入模块,使用module.exports导出接口。

遵循规范

  • require 是 CommonJS/AMD规范引入方式
  • import是es6的一个语法标准,如果要兼容浏览器的话必须转化成es5的语法

调用时间

  • require是运行时调用,所以require理论上可以运用在代码的任何地方
  • import是编译时调用,所以必须放在文件开头

本质

  • require是赋值过程,其实require的结果就是对象、数字、字符串、函数等,再把require的结果赋值给某个变量
  • import是解构过程,但是目前所有的引擎都还没有实现import,我们在node中使用babel支持ES6,也仅仅是将ES6转码为ES5再执行,import语法会被转码为require

参考文章:import和require的区别

  • js拼接两个数组的方式

  •  方法一:使用for循环
var arr = ['tom', 'jerry'];
var arr2 = [1, 2];

for(var i=0; i<arr2.length; i++){
     arr.push(arr2[i])
}
console.log(arr);
// ['tom', 'jerry', 1, 2]
  • 方法二:使用concat(),注意concat()方法生成了一个新的数组,并不改变原来的数组。
var arr = ['tom', 'jerry'];
var arr2 = [1, 2];

var newArr = arr.concat(arr2);
console.log(newArr);
// ["tom", "jerry", 1, 2]
  • 方法三: 使用apply劫持数组的push方法(推荐,apply具体使用方法参考MDN)
var arr = ['tom', 'jerry'];
var arr2 = [1, 2];

arr.push.apply(arr, arr2);
console.log(arr)
// ["tom", "jerry", 1, 2]
  •  方法四:使用es6中的 ‘点语法’ 扩展运算符(推荐)
var arr = ['tom', 'jerry'];
var arr2 = [1, 2];

arr.push(...arr2);
console.log(arr)
// ["tom", "jerry", 1, 2]
  • 备注:扩展运算符(...)
扩展运算符( spread )是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]
  • String、Number类型运算 

console.log(1 + "2" + "2");

console.log(1 + +"2" + "2");

console.log(1 + -"1" + "2");

console.log(+"1" + "1" + "2");

console.log( "A" - "B" + "2");

console.log( "A" - "B" + 2);

以上代码将输出到控制台:
 

"122"

"32"

"02"

"112"

"NaN2"

NaN

这里的基本问题是JavaScript(ECMAScript)是一种松散类型的语言,它对值执行自动类型转换以适应正在执行的操作。让我们来看看这是如何与上面的每个例子进行比较。

  • 示例1:1 +“2”+“2”输出:“122”说明:第一个操作在1 +“2”中执行。由于其中一个操作数(“2”)是一个字符串,所以JavaScript假定需要执行字符串连接,因此将1的类型转换为“1”,1 +“2”转换为“12”。然后,“12”+“2”产生“122”。
  • 示例2:1 + +“2”+“2”输出:“32”说明:根据操作顺序,要执行的第一个操作是+“2”(第一个“2”之前的额外+被视为一个一元运算符)。因此,JavaScript将“2”的类型转换为数字,然后将一元+符号应用于它(即将其视为正数)。结果,下一个操作现在是1 + 2,当然这会产生3.但是,我们有一个数字和一个字符串之间的操作(即3和“2”),所以JavaScript再次转换数值赋给一个字符串并执行字符串连接,产生“32”。
  • 示例3:1 + - “1”+“2”输出:“02”说明:这里的解释与前面的示例相同,只是一元运算符是 - 而不是+。因此,“1”变为1,然后在应用 - 时将其变为-1,然后将其加1到产生0,然后转换为字符串并与最终的“2”操作数连接,产生“02”。
  • 示例4:+“1”+“1”+“2”输出:“112”说明:尽管第一个“1”操作数是基于其前面的一元+运算符的数值类型转换的,当它与第二个“1”操作数连接在一起时返回一个字符串,然后与最终的“2”操作数连接,产生字符串“112”。
  • 示例5:“A” - “B”+“2”输出:“NaN2”说明:由于 - 运算符不能应用于字符串,并且既不能将“A”也不能将“B”转换为数值, “ - ”B“产生NaN,然后与字符串”2“串联产生”NaN2“。
  • 例6:“A” - “B”+2输出:NaN说明:在前面的例子中,“A” - “B”产生NaN。但是任何运算符应用于NaN和其他数字操作数仍然会产生NaN。 
  • 数组去重的几种方式

let originalArray = [1,2,3,4,5,3,2,4,1];

// 方式1
const result = Array.from(new Set(originalArray));
console.log(result); // -> [1, 2, 3, 4, 5]

// 方式2
const result = [];
const map = new Map();
for (let v of originalArray) {
    if (!map.has(v)) {
        map.set(v, true);
        result.push(v);
    }
}
console.log(result); // -> [1, 2, 3, 4, 5]

// 方式3
const result = [];
for (let v of originalArray) {
    if (!result.includes(v)) {
        result.push(v);
    }
}
console.log(result); // -> [1, 2, 3, 4, 5]

// 方式4
for (let i = 0; i < originalArray.length; i++) {
    for (let j = i + 1; j < originalArray.length; j++) {
        if (originalArray[i] === originalArray[j]) {
            originalArray.splice(j, 1);
            j--;
        }
    }
}
console.log(originalArray); // -> [1, 2, 3, 4, 5]

// 方式5
const obj = {};
const result = originalArray.filter(item => obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true));
console.log(result); // -> [1, 2, 3, 4, 5]

 

 

JS面试题

 例:

var a={},

    b={key:'b'},

    c={key:'c'};


a[b]=123;

a[c]=456;

console.log(a[b]);

此代码的输出将是456(不是123)。

原因如下:设置对象属性时,JavaScript会隐式地将参数值串联起来。在这种情况下,由于b和c都是对象,它们都将被转换为“[object Object]”。因此,a [b]和a [c]都等价于[“[object Object]”],并且可以互换使用。因此,设置或引用[c]与设置或引用[b]完全相同。

例:

  var a = 10;
  var obj = {
      a: 20,
      say: () => {  // 此处改为箭头函数
          console.log(this.a);
      }
  };
  obj.say(); // -> 10

37个JavaScript基础面试题

Vue面试题

  • vue的生命周期

Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。

每一个组件或者实例都会经历一个完整的生命周期,总共分为三个阶段:初始化、运行中、销毁。

  1. 实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作
  2. 挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
  3. 接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
  4. 接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情...
  5. 当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿
  6. 当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom
  7. 当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等
  8. 组件的数据绑定、监听...去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以
  • v-for中:key的作用

需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。key的作用主要是为了高效的更新虚拟DOM

Vue2.0 v-for 中 :key 到底有什么用?

  • 组件中的data为什么是个函数

组件是可复用的vue实例,一个组件被创建好之后,就可能被用在各个地方,而组件不管被复用了多少次,组件中的data数据都应该是相互隔离,互不影响的,基于这一理念,组件每复用一次,data数据就应该被复制一次,之后,当某一处复用的地方组件内data数据被改变时,其他复用地方组件的data数据不受影响。每个组件实例可以维护一份被返回对象的独立拷贝。

  •  虚拟DOM节点 

 优点:

  • 保证性能下限: 虚拟DOM可以经过diff找出最小差异,然后批量进行patch,这种操作虽然比不上手动优化,但是比起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限
  • 无需手动操作DOM: 虚拟DOM的diff和patch都是在一次更新中自动进行的,我们无需手动操作DOM,极大提高开发效率
  • 跨平台: 虚拟DOM本质上是JavaScript对象,而DOM与平台强相关,相比之下虚拟DOM可以进行更方便地跨平台操作,例如服务器渲染、移动端开发等等

缺点:

  • 无法进行极致优化: 在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化,比如VScode采用直接手动操作DOM的方式进行极端的性能优化

虚拟DOM实现原理?

  • 虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象
  • 状态变更时,记录新树和旧树的差异
  • 最后把差异更新到真正的dom中

虚拟DOM详细实现见虚拟DOM原理

  • vue-cli 脚手架 目录 解析

 

  • MVVM是什么? 

  • Model 层: 对应数据层的域模型,它主要做域模型的同步。通过 Ajax/fetch 等 API 完成客户端和服务端业务 Model 的同步。在层间关系里,它主要用于抽象出 ViewModel 中视图的 Model。
  • View 层:作为视图模板存在,在 MVVM 里,整个 View 是一个动态模板。除了定义结构、布局外,它展示的是 ViewModel 层的数据和状态。View 层不负责处理状态,View 层做的是 数据绑定的声明、 指令的声明、 事件绑定的声明。
  • ViewModel 层:把 View 需要的层数据暴露,并对 View 层的 数据绑定声明、 指令声明、 事件绑定声明 负责,也就是处理 View 层的具体业务逻辑。ViewModel 底层会做好绑定属性的监听。当 ViewModel 中数据变化,View 层会得到更新;而当 View 中声明了数据的双向绑定(通常是表单元素),框架也会监听 View 层(表单)值的变化。一旦值变化,View 层绑定的 ViewModel 中的数据也会得到自动更新。

  • 简述一下MVVM模式

MVVM模式,即Model-View-ViewModel,其中,

Model是数据层,里面包含页面渲染所需要的数据。

View是视图层,即所呈现出来的页面。

VM层,是Model层和View层的桥梁。

View 和 Model 没有直接的联系,而是通过VM层进行交互,View 和 Model 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。开发者只需关注业务逻辑,不需要手动操作DOM。

  • MVVM的优缺点? 

优点:

  1. 分离视图(View)和模型(Model),降低代码耦合,提高视图或者逻辑的重用性: 比如视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定不同的"View"上,当View变化的时候Model不可以不变,当Model变化的时候View也可以不变。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑
  2. 提高可测试性: ViewModel的存在可以帮助开发者更好地编写测试代码
  3. 自动更新dom: 利用双向绑定,数据更新后视图自动更新,让开发者从繁琐的手动dom中解放

缺点:

  1. Bug很难被调试: 因为使用双向绑定的模式,当你看到界面异常了,有可能是你View的代码有Bug,也可能是Model的代码有问题。数据绑定使得一个位置的Bug被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。另外,数据绑定的声明是指令式地写在View的模版当中的,这些内容是没办法去打断点debug的
  2. 一个大的模块中model也会很大,虽然使用方便了也很容易保证了数据的一致性,当时长期持有,不释放内存就造成了花费更多的内存
  3. 对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高
  • Vue中MVVM实现的基本原理

  • Vue组件通信

  • computed和watch有什么区别?

computed:

  1. computed是计算属性,也就是计算值,它更多用于计算值的场景
  2. computed具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时才会重新调用对应的getter来计算
  3. computed适用于计算比较消耗性能的计算场景

watch:

  1. 更多的是「观察」的作用,类似于某些数据的监听回调,用于观察props $emit或者本组件的值,当数据变化时来执行回调进行后续操作
  2. 无缓存性,页面重新渲染时值不变化也会执行
  • Vue组件的按需加载

// 工厂函数执行 resolve 回调
Vue.component('async-webpack-example', function (resolve) {
  // 这个特殊的 `require` 语法将会告诉 webpack
  // 自动将你的构建代码切割成多个包, 这些包
  // 会通过 Ajax 请求加载
  require(['./my-async-component'], resolve)
})

  • vue-router的核心原理

vue-router通过hash与History两种方式实现前端路由,更新视图但不重新请求页面”是前端路由原理的核心之一

  • vue mixins和extends的区别

混合mixins和继承extends

看看官方文档怎么写的,其实两个都可以理解为继承,mixins接收对象数组(可理解为多继承),extends接收的是对象或函数(可理解为单继承)。

关于mixins和extend你可以理解为mvc的c(controller),这一层。可见通用的成员变量(包括属性和方法)抽象成为一个父类,提供给子类继承,这样可以让子类拥有一些通用成员变量,然而子类也可以重写父类的成员变量。这样的整个编程思想就很面向对象,也就是继承性。

  • Vue的SEO优化

前后端分离之SEO优化--------以vue为例

Webpack面试题

  • 什么是Webpack

WebPack可以看做是模块打包机,在webpack里一切文件皆模块。它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

  • webpack与grunt、gulp的不同?

  • Gulp/Grunt是一种能够优化前端的开发流程的工具。
  • WebPack是一种模块化的解决方案,不过Webpack的优点使得Webpack在很多场景下可以替代Gulp/Grunt类的工具。

webpack入门手册

grunt入门手册

他们的工作方式也有较大区别:

  • Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。
  • Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。

三者都是前端构建工具,grunt和gulp在早期比较流行,现在webpack相对来说比较主流,不过一些轻量化的任务还是会用gulp来处理,比如单独打包CSS文件等。

  • grunt和gulp是基于任务和流的。类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程。
  • webpack是基于入口的。webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能。
  • gulp和grunt是流管理工具,通过一个个task配置执行用户需要的功能,如格式检验,代码压缩等,值得一提的是,经过这两者处理的代码只是局部变量名被替换简化,整体并没有发生改变,还是你的代码。
  • webpack则进行了更彻底的打包处理,更加偏向对模块语法规则进行转换。主要任务是突破浏览器的鸿沟,将原本浏览器不能识别的规范和各种各样的静态文件进行分析,压缩,合并,打包,最后生成浏览器支持的代码,因此,webapck打包过后的代码已经不是你写的代码了,或许你再去看,已经看不懂啦
  • NPM和webpack的关系

NPM和webpack的关系(转载)

  • 分别介绍bundle,chunk,module是什么

  • bundle:是由webpack打包出来的文件,
  • chunk:代码块,一个chunk由多个模块组合而成,用于代码的合并和分割。
  • module:是开发中的单个模块,在webpack的世界,一切皆模块,一个模块对应一个文件,webpack会从配置的entry中递归开始找出所有依赖的模块。
  • 分别介绍什么是loader?什么是plugin?

  • loader:模块转换器,用于将模块的原内容按照需要转成你想要的内容
  • plugin:在webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果,是用来自定义webpack打包过程的方式,一个插件是含有apply方法的一个对象,通过这个方法可以参与到整个webpack打包的各个流程(生命周期)。
  • 什么 是模块热更新?

模块热更新是webpack的一个功能,他可以使得代码修改过后不用刷新浏览器就可以更新,是高级版的自动刷新浏览器。

好处:保持应用的数据状态,节省调试时间,样式调试更快

  •  如何可以自动生成webpack配置?

webpack-cli /vue-cli /etc ...脚手架工具

  • webpack-dev-server和http服务器如nginx有什么区别?

webpack-dev-server使用内存来存储webpack开发环境下的打包文件,并且可以使用模块热更新,他比传统的http服务对开发更加简单高效。

  • webpack和gulp区别(模块化与流的区别)

gulp强调的是前端开发的工作流程,我们可以通过配置一系列的task,定义task处理的事务(例如文件压缩合并、雪碧图、启动server、版本控制等),然后定义执行顺序,来让gulp执行这些task,从而构建项目的整个前端开发流程。

webpack是一个前端模块化方案,更侧重模块打包,我们可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源。

Git面试题

  • git和svn的优缺点。

Git是分布式版本控制系统,SVN是集中式版本控制系统

SVN优缺点 

  • 优点: 
  1. 管理方便,逻辑明确,符合一般人思维习惯。 
  2. 易于管理,集中式服务器更能保证安全性。 
  3. 代码一致性非常高。 
  4. 适合开发人数不多的项目开发。 
  • 缺点: 
  1. 服务器压力太大,数据库容量暴增。 
  2. 如果不能连接到服务器上,基本上不可以工作,看上面第二步,如果服务器不能连接上,就不能提交,还原,对比等等。 
  3. 不适合开源开发(开发人数非常非常多,但是Google app engine就是用svn的)。但是一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理,从而很好的解决开发人数众多的问题。

Git优缺点 

  • 优点: 
  1. 适合分布式开发,强调个体。 
  2. 公共服务器压力和数据量都不会太大。 
  3. 速度快、灵活。 
  4. 任意两个开发者之间可以很容易的解决冲突。 
  5. 离线工作。 
  • 缺点: 
  1. 学习周期相对而言比较长。 
  2. 不符合常规思维。 
  3. 代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息。
  • Git 里面的 origin

origin 是默认的远程版本库名称,你可以在 .git/config 之中进行修改,事实上 git push origin master 的意思是 git push origin master:master (将本地的 master 分支推送至远端的 master 分支,如果没有就新建一个)

  • fetch和merge和pull的区别

 pull相当于git fetch 和 git merge,即更新远程仓库的代码到本地仓库,然后将内容合并到当前分支。

  •  git fetch:相当于是从远程获取最新版本到本地,不会自动merge
  •  git merge :  将内容合并到当前分支
  •  git pull:相当于是从远程获取最新版本并merge到本地
  • 常用命令

  • git show # 显示某次提交的内容 git show $id
  • git add <file> # 将工作文件修改提交到本地暂存区
  • git rm <file> # 从版本库中删除文件
  • git reset <file> # 从暂存区恢复到工作文件
  • git reset HEAD^ # 恢复最近一次提交过的状态,即放弃上次提交后的所有本次修改
  • git diff <file> # 比较当前文件和暂存区文件差异 git diff
  • git log -p <file> # 查看每次详细修改内容的diff
  • git branch -r # 查看远程分支
  • git merge <branch> # 将branch分支合并到当前分支
  • git stash # 暂存
  • git stash pop #恢复最近一次的暂存
  • git pull # 抓取远程仓库所有分支更新并合并到本地
  • git push origin master # 将本地主分支推到远程主分支

浏览器和网络协议

  • http 和 https 有何区别

  • http是HTTP协议运行在TCP之上。所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。
  • https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。此外客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份
  • TCP传输的三次握手 

为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。用TCP协议把数据包送出去后,TCP不会对传送 后的情况置之不理,它一定会向对方确认是否成功送达。握手过程中使用了TCP的标志:SYN和ACK。

发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。 
最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。 
若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。

  • 从输入URL到页面加载成功显示经历了什么 

  1. 当发送一个URL请求时,不管这个URL是Web页面的URL还是Web页面上每个资源的URL,浏览器都会开启一个线程来处理这个请求,同时在远程DNS服务器上启动一个DNS查询。这能使浏览器获得请求对应的IP地址。
  2. 浏览器与远程`Web`服务器通过`TCP`三次握手协商来建立一个`TCP/IP`连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。
  3. 一旦`TCP/IP`连接建立,浏览器会通过该连接向远程服务器发送`HTTP`的`GET`请求。远程服务器找到资源并使用HTTP响应返回该资源,值为200的HTTP响应状态表示一个正确的响应。
  4. 此时,`Web`服务器提供资源服务,客户端开始下载资源。请求返回后,便进入了我们关注的前端模块简单来说,浏览器会解析`HTML`生成`DOM Tree`,其次会根据CSS生成CSS Rule Tree,而`javascript`又可以根据`DOM API`操作`DOM`

总结:

  1. DNS解析
  2. TCP连接
  3. 发送HTTP请求
  4. 服务器处理请求并返回HTTP报文
  5. 浏览器解析渲染页面
  6. 连接结束
  • 常见的HTTP状态码

常见:

  •     100  Continue 继续,发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
  •     200  OK   正常返回信息
  •     201  Created 请求成功并且服务器创建了新的资源
  •     202  Accepted 服务器已接受请求,但尚未处理
  •     301  Moved Permanently  请求的网页已永久移动到新位置。
  •     302  Found  临时性重定向。
  •     303  SeeOther  临时性重定向,且总是使用 GET 请求新的 URI。
  •     304  Not Modified 自从上次请求后,请求的网页未修改过。
  •     400  BadRequest  服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
  •     401  Unauthorized  请求未授权。
  •     403  Forbidden  禁止访问。
  •     404  NotFound  找不到如何与 URI 相匹配的资源。
  •     500  InternalServer Error  最常见的服务器端错误。
  •     503  ServiceUnavailable 服务器端暂时无法处理请求(可能是过载或维护)。

汇总:

  • 2开头 (请求成功)表示成功处理了请求的状态代码。

200   (成功)  服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 
201   (已创建)  请求成功并且服务器创建了新的资源。 
202   (已接受)  服务器已接受请求,但尚未处理。 
203   (非授权信息)  服务器已成功处理了请求,但返回的信息可能来自另一来源。 
204   (无内容)  服务器成功处理了请求,但没有返回任何内容。 
205   (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206   (部分内容)  服务器成功处理了部分 GET 请求。

 

  • 3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。

300   (多种选择)  针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。 
301   (永久移动)  请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302   (临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303   (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304   (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。 
305   (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。 
307   (临时重定向)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

  • 4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。

400   (错误请求) 服务器不理解请求的语法。 
401   (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 
403   (禁止) 服务器拒绝请求。
404   (未找到) 服务器找不到请求的网页。
405   (方法禁用) 禁用请求中指定的方法。 
406   (不接受) 无法使用请求的内容特性响应请求的网页。 
407   (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408   (请求超时)  服务器等候请求时发生超时。 
409   (冲突)  服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。 
410   (已删除)  如果请求的资源已永久删除,服务器就会返回此响应。 
411   (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。 
412   (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。 
413   (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。 
414   (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。 
415   (不支持的媒体类型) 请求的格式不受请求页面的支持。 
416   (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。 
417   (未满足期望值) 服务器未满足"期望"请求标头字段的要求。

  • 5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。

500   (服务器内部错误)  服务器遇到错误,无法完成请求。 
501   (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 
502   (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 
503   (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 
504   (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。 
505   (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

  • 浏览器的内核分别是什么

  • Chrome:Blink(基于webkit,Google与Opera Software共同开发)
  • IE: trident内核
  • Firefox:gecko内核
  • Safari:webkit内核
  • Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核
  • 优雅降级和渐进增强

  • 优雅降级:(常用,兼容IE)

一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

  • 渐进增强:

针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

  • 浏览器是如何渲染页面

  1. 解析HTML文件,创建DOM树。自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。
  2. 解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式<HTML中的style样式;
  3. 将CSS与DOM合并,构建渲染树(Render Tree)
  4. 布局和绘制,重绘(repaint)和重排(reflow)
  • 关于事件循环 

node端

Node 的 Event Loop 分为 6 个阶段,它们会按照顺序反复运行。每当进入某一个阶段的时候,都会从对应的回调队列中取出函数去执行。当队列为空或者执行的回调函数数量到达系统设定的阈值,就会进入下一阶段。

Event Loop 6 个阶段:

  1. timers
  2. I/O callbacks
  3. idle, prepare
  4. poll
  5. check
  6. close callbacks

浏览器端

浏览器端 的情况与 node端 的情况相仿,当我们执行 JS 代码的时候其实就是往执行栈中放入函数,当遇到异步的代码时,会被挂起并在需要执行的时候加入到 Task(有多种 Task) 队列中。一旦执行栈为空,Event Loop 就会从 Task 队列中拿出需要执行的代码并放入执行栈中执行。

  • 微任务(microtask)
    • process.nextTick
    • promise
    • Object.observe(曾经是提案,如今已经废除)
    • MutationOberver
  • 宏任务(macrotask)
    • script
    • setTimeout
    • setInterval
    • setImmediate
    • I/O
    • UI渲染

执行顺序如下:

  1. 执行同步代码,这是宏任务
  2. 执行栈为空,查询是否有微任务要执行
  3. 必要时渲染UI
  4. 进行下一轮的 EventLoop ,执行宏任务中的异步代码

参考链接:JS事件循环——宏任务和微任务

setTimeout 误差

上面讲了定时器是属于 宏任务(macrotask) 。如果当前 执行栈 所花费的时间大于 定时器 时间,那么定时器的回调在 宏任务里,来不及去调用,所有这个时间会有误差。

我们看以下代码:

setTimeout(function () {
	console.log('biubiu');
}, 1000);

//某个执行时间很长的函数();

如果定时器下面的函数执行要 5秒钟,那么定时器里的log 则需要 5秒之后再执行,函数占用了当前 执行栈 ,要等执行栈执行完毕后再去读取 微任务(microtask),等 微任务(microtask) 完成,这个时候才会去读取 宏任务 里面的 setTimeout 回调函数执行。setInterval 同理,例如每3秒放入宏任务,也要等到执行栈的完成。

前端进阶之setTimeout 倒计时为什么会出现误差?

  • 垃圾回收机制方式

标记清除(常用)和引用计数。

  • 标记清除:

  定义和用法:当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:"离开环境"。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。

  到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。

  • 引用计数:

  定义和用法:引用计数是跟踪记录每个值被引用的次数。

  基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。

  • Web攻击技术

  • XSS 跨站脚本攻击,是说攻击者通过注入恶意的脚本,在用户浏览网页的时候进行攻击,比如获取cookie,或者其他用户身份信息,可以分为存储型和反射型,存储型是攻击者输入一些数据并且存储到了数据库中,其他浏览者看到的时候进行攻击,反射型的话不存储在数据库中,往往表现为将攻击代码放在url地址的请求参数中。主要是前端层面的,用户在输入层面插入攻击脚本,改变页面的显示,或则窃取网站 cookie,
  • 预防方法:不相信用户的所有操作,对用户输入进行一个转义,不允许 js 对 cookie 的读写,为cookie设置httpOnly属性,对用户的输入进行检查,进行特殊字符过滤
  • CSRF 跨站请求伪造,可以理解为攻击者盗用了用户的身份,以用户的名义发送了恶意请求,比如用户登录了一个网站后,立刻在另一个tab页面访问量攻击者用来制造攻击的网站,这个网站要求访问刚刚登陆的网站,并发送了一个恶意请求,这时候CSRF就产生了,比如这个制造攻击的网站使用一张图片,但是这种图片的链接却是可以修改数据库的,这时候攻击者就可以以用户的名义操作这个数据库。即以你的名义,发送恶意请求。
  • 预防方法:使用验证码,检查https头部的refer,使用token,通过 cookie 加参数等形式过滤

性能优化

1.压缩css,js,图片

2.减少http请求次数,  合并css,js   合并图片(雪碧图)

3.使用CDN

4.减少dom元素数量

5.图片懒加载

6.静态资源另外用无cookie的域名

7.减少dom的访问(缓存dom)

8.巧用事件委托

9.样式表置顶、脚本置低

发布了142 篇原创文章 · 获赞 54 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/CWH0908/article/details/91379357