目录
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,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请求的实现
浏览器的同源策略
常用的跨域方案
在地址栏里输入一个URL,到这个页面呈现出来,中间会发生什么?
call、bind、apply区别
get、post的区别
“ ===”、“ ==”的区别
同步和异步的区别
Vue面试题
v-for中:key的作用
组件中的data为什么是个函数
虚拟DOM节点
Webpack面试题
什么是Webpack
webpack与grunt、gulp的不同?
分别介绍bundle,chunk,module是什么
分别介绍什么是loader?什么是plugin?
什么 是模块热更新?
如何可以自动生成webpack配置?
webpack-dev-server和http服务器如nginx有什么区别?
Git面试题
git和svn的优缺点。
Git 里面的 origin
fetch和merge和pull的区别
常用命令
浏览器和网络协议
http 和 https 有何区别
TCP传输的三次握手
从输入URL到页面加载成功显示经历了什么
常见的HTTP状态码
浏览器的内核分别是什么
优雅降级和渐进增强
浏览器是如何渲染页面
关于事件循环
垃圾回收机制方式
Web攻击技术
性能优化
- 用正确的标签做正确的事情。
- html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;即使在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的;
- 搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO;
- 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。
- 不是一个HTML标签,是一个用于告诉浏览器当前HTML版本的指令
- 告知浏览器按照何种规范解析页面
- 添加了,就等同于开启了标准模式
在SEO中,所谓的TDK其实就是title、description、keywords这三个标签,这三个标签在网站的优化过程中,title标题标 签,description描述标签,keywords关键词标签。
SEO中TDK详细介绍
新增语义化标签
常用的块级元素:
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属性区别
alt是给搜索引擎识别,在图像无法显示时的替代文本;
title是关于元素的注释信息,主要是给用户解读。当鼠标放到文字或是图片上时有title文字显示。
(因为IE不标准)在IE浏览器中alt起到了title的作用,变成文字提示。在定义img对象时,将alt和title属性写全,可以保证在各种浏览器中都能正常使用。
- title属性没有明确意义只表示是个标题,H1则表示层次明确的标题,对页面信息的抓取也有很大的影响;
- strong是标明重点内容,有语气加强的含义,使用阅读设备阅读网络时:会重读,而是展示强调内容。
- i内容展示为斜体,em表示强调的文本;
提供有关页面的元信息,比如针对搜索引擎和更新频度的描述和关键词。
label标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。
- 会阻塞主页面的Onload事件;
- 搜索引擎的检索程序无法解读这种页面,不利于SEO;
- iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。
使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript。动态给iframe添加src属性值,这样可以绕开以上两个问题。
- XHTML 元素必须被正确地嵌套。
错误:
this is example.
正确:
this is example.
- XHTML 元素必须被关闭。
错误:
this is example.
正确:
this is example.
- 标签名必须用小写字母。
错误:
this is example.
正确:
this is example.
- 空标签也必须被关闭
错误:
正确:
- XHTML 文档必须拥有根元素。
所有的 XHTML 元素必须被嵌套于 根元素中。
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边写出来的文件小。
- table必须在页面完全加载后才显示,div则是逐行显示。
- table的嵌套性太多,没有div简洁
- 原因
因为浏览器的兼容的问题,不同浏览器有些标签的默认值是不同的,如果没有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%; }
- 内联元素:
内联元素(inline)不会独占一行,相邻的内联元素会排在同一行。其宽度随内容的变化而变化。
内联元素不可以设置宽高
内联元素可以设置margin,padding,但只在水平方向有效。
- 块状元素:
- 块级元素会独占一行,默认情况下宽度自动填满其父元素宽度
- 块级元素可以设置宽高
- 块级元素可以设置margin,padding
- 内联块状元素 inline-block:
表现为同行显示并可修改宽高内外边距等属性。简单来说就是将对象呈现为inline对象,但是对象的内容作为block对象呈现(可以设置宽高和margin值)。之后的内联对象会被排列在同一内联。比如我们可以给一个span标签设置inline-block属性值,使其既具有block的宽度高度特性又具有inline的同行特性。
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
在元素内容的最后面添加新内容。
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;,它会固定在目标位置。
- 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属性和上述替换元素表现为inline-block
- none
inline和inline-block出现的问题
水平呈现的元素间,换行显示或空格分隔的情况下会有间距
解决方法
- 相邻inline-block元素不分行写,写在同一行并且中间无空格
- select父元素使用font-size:0
float(对块级、行内、内联块元素的影响)
- display:none是彻底消失,不在文档流中占位,浏览器也不会解析该元素;
- visibility:hidden是视觉上消失了,可以理解为透明度为0的效果,在文档流中占位,浏览器会解析该元素;
- 使用visibility:hidden比display:none性能上要好,display:none切换显示时,页面产生回流(当页面中的一部分元素需要改变规模尺寸、布局、显示隐藏等,页面重新构建,此时就是回流。所有页面第一次加载时需要产生一次回流),而visibility切换是否显示时则不会引起回流。
一、无继承性的属性
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
满足下列css声明之一的元素便会生成BFC
- 根元素
- float的值不为none
- overflow的值不为visible(常用 overflow:hidden创建BFC区域)
- display的值为inline-block、table-cell、table-caption
- position的值不为static或relative
BFC(块级格式上下文)
由于不同厂商的流览器或某浏览器的不同版本(如IE6-IE11,Firefox/Safari/Opera/Chrome等),对CSS的支持、解析不一样,导致在不同浏览器的环境中呈现出不一致的页面展现效果。这时,我们为了获得统一的页面效果,就需要针对不同的浏览器或不同版本写特定的CSS样式,我们把这个针对不同的浏览器/不同版本写相应的CSS code的过程,叫做CSS hack
CSS hack
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)
优先级:
important的权值为最高 1,0,0,0
ID的权值为 0,1,0,0
类的权值为 0,0,1,0
标签的权值为 0,0,0,1
伪类选择的权值为 0,0,1,0
通配选择符的权值 0,0,0,0
比较同一级别的个数,数量多的优先级高,如果相同即比较下一级别的个数:
important > 内联 > ID > 类 > 标签 | 伪类 >通配符 > 继承
这也就解释了为什么11个标签的定义会比不上1个类的定义,1个类加11个标签会比不上2个类的权重高。
CSS选择器、优先级与匹配原理
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配合使用,因为超出的尺寸的会被隐藏。
属性和区别
- transition是过渡,animation是动画。transition只能从一种状态过渡到另外一种状态,animation可以定制复杂动画,可以定义动画的区间等。
- transition必须通过一些行为才能触发(js或者伪类来触发),animation的话直接就可以触发。
菜鸟教程——@media
利用CSS中的@media实现响应式布局
- 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属性可以指定盒子模型种类
content-box指定盒子模型为W3C的标准盒子模型
border-box指定盒子模型为IE盒子模型(width包含border和padding)
干货!各种常见布局实现
CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,以供项目使用。CSS预处理器为CSS增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在CSS中使用变量、简单的逻辑程序、函数等等在编程语言中的一些基本特性,可以让你的CSS更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。
详说css与预处理器
原理:
将许多的小图片整合到一张大图片中,利用css中的background-image属性,background-position属性定位某个图片位置,来达到在大图片中引用某个部位的小图片的效果。
优点:
- 减少网页的http请求,提升网页加载速度。
- 合并多张小图片成大图,能减少字节总数(大图大小<=多张小图大小).
缺点:
- 前期需要处理图片将小图合并,多些许工程量。
- 对于需要经常改变的图片维护起来麻烦。
z-index失效的原因
- href表示超文本引用,用在link和a等元素上,href是引用和页面关联,是在当前元素和引用资源之间建立联系。
- src表示引用资源,表示替换当前元素,用在img,script,iframe上,src是页面内容不可缺少的一部分。
- src是source的缩写,是指向外部资源的位置,指向的内部会迁入到文档中当前标签所在的位置;在请求src资源时会将其指向的资源下载并应用到当前文档中,例如js脚本,img图片和frame等元素。当浏览器解析到这一句的时候会暂停其他资源的下载和处理,直至将该资源加载,编译,执行完毕,图片和框架等元素也是如此,类似于该元素所指向的资源嵌套如当前标签内,这也是为什么要把js饭再底部而不是头部。
- 当浏览器解析到这一句的时候会识别该文档为css文件,会下载并且不会停止对当前文档的处理,这也是为什么建议使用link方式来加载css而不是使用@import。
Flex 布局语法教程
- undefined
- null
- string
- boolean
- number
- symbol(ES6)
一种引用类型
- Object
- null: 代表“空值”,代表一个空对象指针,使用typeof运算得到 “object”,所以可以认为它是一个特殊的对象值。
- undefined: Undefined类型,当一个声明了一个变量未初始化时,得到的就是undefined。
null是javascript的关键字,可以认为是对象类型,它是一个空对象指针,和其它语言一样都是代表“空值”,
不过 undefined 却是javascript才有的。
undefined是在ECMAScript第三版引入的,为了区分空指针对象和未初始化的变量,它是一个预定义的全局变量。
没有返回值的函数返回为undefined,没有实参的形参也是undefined。
相同点:
- 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命令创建
简述一下原型链:
所有函数都有一个prototype属性,所有引用类型(对象)都有__proto__属性,当对象调用当前实例不存在的属性和函数的时候就会沿着__proto__属性向上查找prototype原型对象中的属性和函数,直到Object原型对象为止,由此形成原型链。
javascript深入学习原型到原型链
prototype和__proto__的区别
- 作用域是针对变量的
- 原型链是针对构造函数的
javascript中作用域链和原型链的区别
- 工厂模式
- 构造函数模式
- 原型模式
- 组合模式
- 寄生构造函数模式
- 稳妥构造函数模式
javascript创建对象的方式
- 原型链继承
- 借用构造函数继承
- 组合继承
- 原型式继承
- 寄生式继承
- 寄生组合式继承
javascript继承的方式
什么是闭包:
由于作用域的关系,我们在函数外部是无法直接访问到函数内部的变量的,但是函数内部可以把这个变量传给全局变量或者返回出来,这样外部作用域就可以访问函数内部作用域的变量了;
简单的说,闭包就是有权限访问另一个函数内部作用域的变量的函数;
优点:
主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染
缺点:
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
this 永远指向最后调用它的那个对象
- 在调用函数时使用
new
关键字,函数内的this
是一个全新的对象。- 如果
apply
、call
或bind
方法用于调用、创建一个函数,函数内的 this 就是作为参数传入这些方法的对象。- 当函数作为对象里的方法被调用时,函数内的
this
是调用该函数的对象。比如当obj.method()
被调用时,函数内的 this 将绑定到obj
对象。- 如果调用函数不符合上述规则,那么
this
的值指向全局对象(global object)。浏览器环境下this
的值指向window
对象,但是在严格模式下('use strict'
),this
的值为undefined
。- 如果符合上述多个规则,则较高的规则(1 号最高,4 号最低)将决定
this
的值(根据当前的词法作用域来决定this)。- ES6的箭头函数,将忽略上面的所有规则,
this
被设置为它被创建时的上下文。
改变 this 指向的方法:
- 使用 ES6 的箭头函数
- 在函数内部使用
_this = this
- 使用
apply
、call
、bind
- new 实例化一个对象
javascript深入学习this指向问题
简述JavaScript中的this
通过new创建对象经历4个步骤
- 创建一个新Object对象;[var o = {};]
- 将构造函数的作用域赋给新对象(因此this指向了这个新对象)执行构造函数中的代码(为这个新对象添加属性); [Person.apply(o)] [Person原来的this指向的是window]
- 为其绑定原型对象;
- 返回新生成的对象。
防抖:在高频发的事件调用时,每次将定义好的定时器清除掉,只有当高频发事件调用最后一次的时候,由于没有再调用该事件函数,没有清除定义的定时器,那么定时器将正常工作,即定时器等待时间内连续调用10次后显示1,连续调用20次后显示的还是1。
通俗来讲就是,你要我在30s内搬100块砖,我偷懒,我结束时才搬一块。
javascript的防抖和节流
节流:在高频发的事件调用时,不会清除定义好的定时器。假设你的定时器为1s,加入if判断语句,如果你高频发事件的调用间隔小于1s,那么你在这1s的定时器等待时间内调用的次数都当成一次,即连续调用10次后如果花了三秒钟则显示3,连续调用20次后如果花了三秒钟那么也显示3,就是看你的调用时间。注意,将若干函数调用合成为一次(稀释函数的执行频率),并在给定时间过去之后,调用一次(仅仅只会调用一次)。
通俗来讲就是,你要我在30s内搬100块砖,我搬,不过我每1s(定时器范围)才搬一块,多了我不干,所以我最后才搬了30块砖。
javascript的防抖和节流
原生JS中DOM节点相关API合集
DOM0级
分为2个:一是在标签内写onclick事件
二是在JS写onlicke=function(){}函
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 事件冒泡及其阻止方法
在JavaScript中,DOM0级、DOM2级与旧版本IE(8-)为对象添加事件的方法不同
为了以跨浏览器的方式处理事件,需要编写一段“通用代码”,即跨浏览器的事件处理程序
习惯上,这个方法属于一个名为EventUtil的对象
编写并使用该对象后,可保证处理事件的代码能在大多数浏览器下一致的运行
EventUtil对象的封装及其使用
把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。
优点:
- 减少内存消耗
- 动态绑定事件(因为事件是绑定在父层的,和目标元素的增减是没有关系的)
局限性:
- focus、blur 之类的事件本身没有事件冒泡机制,所以无法委托
- mousemove、mouseout 这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也不适合事件委托
JavaScript 事件委托 (事件代理) 详解
JSON对象的两个很重要的方法
JSON.parse() //JSON字符串转换为JSON对象 JSON.stringify() //JSON对象转化为字符串
- JSON相对于XML来讲,数据的体积小,传递的速度更快些
- JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互
- XML对数据描述性比较好;
- JSON的速度要远远快于XML
JSON用法
原生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数据大小不能超过4k。
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
生命周期:
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage 数据在当前浏览器窗口关闭后自动删除。
注意:
通过点击链接(或者用了 window.open)打开的新标签页之间是属于同一个 session 的,但新开一个标签页总是会初始化一个新的 session,即使网站是一样的,它们也不属于同一个 session。
cookies,sessionStorage 和 localStorage 的区别
- 输入url后,首先需要找到这个url域名的服务器ip,为了寻找这个ip,浏览器首先会寻找缓存,查看缓存中是否有记录,缓存的查找记录为:浏览器缓存-》系统缓存-》路由器缓存,缓存中没有则查找系统的hosts文件中是否有记录,如果没有则查询DNS服务器。
- 得到服务器的ip地址后,浏览器根据这个ip以及相应的端口号,构造一个http请求,这个请求报文会包括这次请求的信息,主要是请求方法,请求说明和请求附带的数据,并将这个http请求封装在一个tcp包中,这个tcp包会依次经过传输层,网络层,数据链路层,物理层到达服务器,服务器解析这个请求来作出响应,返回相应的html给浏览器。
- 因为html是一个树形结构,浏览器根据这个html来构建DOM树,在dom树的构建过程中如果遇到JS脚本和外部JS连接,则会停止构建DOM树来执行和下载相应的代码,这会造成阻塞,这就是为什么推荐JS代码应该放在html代码的后面,之后根据外部央视,内部央视,内联样式构建一个CSS对象模型树CSSOM树,构建完成后和DOM树合并为渲染树,这里主要做的是排除非视觉节点,比如script,meta标签和排除display为none的节点,之后进行布局,布局主要是确定各个元素的位置和尺寸。
- 之后是渲染页面,因为html文件中会含有图片,视频,音频等资源,在解析DOM的过程中,遇到这些都会进行并行下载,浏览器对每个域的并行下载数量有一定的限制,一般是4-6个,当然在这些所有的请求中我们还需要关注的就是缓存,缓存一般通过Cache-Control、Last-Modify、Expires等首部字段控制。
call与apply都属于Function.prototype的一个方法,所以每个function实例都有call、apply属性;
作用
call()方法和apply()方法的作用相同:改变this指向。
区别(接收参数的方式不同)
- call():第一个参数是对象,其余参数都直接传递给函数(参数必须逐个列举出来)。
- apply():第一个参数是对象,传递给函数的是参数数组或者arguments类数组对象。
传递参数并非call()和apply()真正的作用,真正强大的地方是能修改函数运行的作用域(改变this指向)
javascript中的call()与apply()
- Get 请求能缓存,Post 不能
- Post 相对 Get 安全,因为Get 请求都包含在 URL 里,且会被浏览器保存历史纪录,Post 不会,但在抓包的情况下都是一样的。
- Post 可以通过 request body来传输比 Get 更多的数据,Get 没有这个技术
- URL有长度限制,会影响 Get 请求,但是这个长度限制是浏览器规定的,不是 RFC 规定的
- Post 支持更多的编码类型且不对数据类型限制
- ==,当且仅当两个运算数相等时,它返回 true,即不检查数据类型
- ===,只有在无需类型转换运算数就相等的情况下,才返回 true,需要检查数据类型
同步是阻塞模式,异步是非阻塞模式。
- 同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
- 异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
使用变量 a 拷贝对象 b,改变 a 中的值 b 中的值也会跟着改变,这叫做浅拷贝。要想让 a 独立于 b 就需要深拷贝。(非基本类型)
简易处理
function deepClone() { return JSON.parse(JSON.stringify(obj)) }复制代码
既然是简易处理就有他的不足,上面主要是用了 JSON 的序列化和反序列化。而 JSON 是不支持函数和 undefined 的因此碰到这些情况会缺失,但是已经能够满足大部分情况了
复杂处理
复杂处理就需要采用递归的方式了
function deepClone(obj) { function isClass(o) { if (o === null) return "Null"; if (o === undefined) return "Undefined"; return Object.prototype.toString.call(o).slice(8, -1); } var result; var oClass = isClass(obj); if (oClass === "Object") { result = {}; } else if (oClass === "Array") { result = []; } else { return obj; } for (var key in obj) { var copy = obj[key]; if (isClass(copy) == "Object") { result[key] = arguments.callee(copy);//递归调用 } else if (isClass(copy) == "Array") { result[key] = arguments.callee(copy); } else { result[key] = obj[key]; } } return result; }
Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
每一个组件或者实例都会经历一个完整的生命周期,总共分为三个阶段:初始化、运行中、销毁。
- 实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作
- 挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
- 接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
- 接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情...
- 当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿
- 当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom
- 当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等
- 组件的数据绑定、监听...去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以
需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。key的作用主要是为了高效的更新虚拟DOM
Vue2.0 v-for 中 :key 到底有什么用?
组件是可复用的
vue
实例,一个组件被创建好之后,就可能被用在各个地方,而组件不管被复用了多少次,组件中的data
数据都应该是相互隔离,互不影响的,基于这一理念,组件每复用一次,data
数据就应该被复制一次,之后,当某一处复用的地方组件内data
数据被改变时,其他复用地方组件的data
数据不受影响。每个组件实例可以维护一份被返回对象的独立拷贝。
优点:
- 保证性能下限: 虚拟DOM可以经过diff找出最小差异,然后批量进行patch,这种操作虽然比不上手动优化,但是比起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限
- 无需手动操作DOM: 虚拟DOM的diff和patch都是在一次更新中自动进行的,我们无需手动操作DOM,极大提高开发效率
- 跨平台: 虚拟DOM本质上是JavaScript对象,而DOM与平台强相关,相比之下虚拟DOM可以进行更方便地跨平台操作,例如服务器渲染、移动端开发等等
缺点:
- 无法进行极致优化: 在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化,比如VScode采用直接手动操作DOM的方式进行极端的性能优化
虚拟DOM实现原理?
- 虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象
- 状态变更时,记录新树和旧树的差异
- 最后把差异更新到真正的dom中
虚拟DOM详细实现见虚拟DOM原理
- Model 层: 对应数据层的域模型,它主要做域模型的同步。通过 Ajax/fetch 等 API 完成客户端和服务端业务 Model 的同步。在层间关系里,它主要用于抽象出 ViewModel 中视图的 Model。
- View 层:作为视图模板存在,在 MVVM 里,整个 View 是一个动态模板。除了定义结构、布局外,它展示的是 ViewModel 层的数据和状态。View 层不负责处理状态,View 层做的是 数据绑定的声明、 指令的声明、 事件绑定的声明。
- ViewModel 层:把 View 需要的层数据暴露,并对 View 层的 数据绑定声明、 指令声明、 事件绑定声明 负责,也就是处理 View 层的具体业务逻辑。ViewModel 底层会做好绑定属性的监听。当 ViewModel 中数据变化,View 层会得到更新;而当 View 中声明了数据的双向绑定(通常是表单元素),框架也会监听 View 层(表单)值的变化。一旦值变化,View 层绑定的 ViewModel 中的数据也会得到自动更新。
优点:
- 分离视图(View)和模型(Model),降低代码耦合,提高视图或者逻辑的重用性: 比如视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定不同的"View"上,当View变化的时候Model不可以不变,当Model变化的时候View也可以不变。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑
- 提高可测试性: ViewModel的存在可以帮助开发者更好地编写测试代码
- 自动更新dom: 利用双向绑定,数据更新后视图自动更新,让开发者从繁琐的手动dom中解放
缺点:
- Bug很难被调试: 因为使用双向绑定的模式,当你看到界面异常了,有可能是你View的代码有Bug,也可能是Model的代码有问题。数据绑定使得一个位置的Bug被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。另外,数据绑定的声明是指令式地写在View的模版当中的,这些内容是没办法去打断点debug的
- 一个大的模块中model也会很大,虽然使用方便了也很容易保证了数据的一致性,当时长期持有,不释放内存就造成了花费更多的内存
- 对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高
computed:
computed
是计算属性,也就是计算值,它更多用于计算值的场景computed
具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时才会重新调用对应的getter来计算computed
适用于计算比较消耗性能的计算场景watch:
- 更多的是「观察」的作用,类似于某些数据的监听回调,用于观察
props
$emit
或者本组件的值,当数据变化时来执行回调进行后续操作- 无缓存性,页面重新渲染时值不变化也会执行
WebPack可以看做是模块打包机,在webpack里一切文件皆模块。它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
- 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打包过后的代码已经不是你写的代码了,或许你再去看,已经看不懂啦
- bundle:是由webpack打包出来的文件,
- chunk:代码块,一个chunk由多个模块组合而成,用于代码的合并和分割。
- module:是开发中的单个模块,在webpack的世界,一切皆模块,一个模块对应一个文件,webpack会从配置的entry中递归开始找出所有依赖的模块。
- loader:模块转换器,用于将模块的原内容按照需要转成你想要的内容
- plugin:在webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果,是用来自定义webpack打包过程的方式,一个插件是含有apply方法的一个对象,通过这个方法可以参与到整个webpack打包的各个流程(生命周期)。
模块热更新是webpack的一个功能,他可以使得代码修改过后不用刷新浏览器就可以更新,是高级版的自动刷新浏览器。
好处:保持应用的数据状态,节省调试时间,样式调试更快
webpack-cli /vue-cli /etc ...脚手架工具
webpack-dev-server使用内存来存储webpack开发环境下的打包文件,并且可以使用模块热更新,他比传统的http服务对开发更加简单高效。
gulp强调的是前端开发的工作流程,我们可以通过配置一系列的task,定义task处理的事务(例如文件压缩合并、雪碧图、启动server、版本控制等),然后定义执行顺序,来让gulp执行这些task,从而构建项目的整个前端开发流程。
webpack是一个前端模块化方案,更侧重模块打包,我们可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源。
Git是分布式版本控制系统,SVN是集中式版本控制系统
SVN优缺点
- 优点:
- 管理方便,逻辑明确,符合一般人思维习惯。
- 易于管理,集中式服务器更能保证安全性。
- 代码一致性非常高。
- 适合开发人数不多的项目开发。
- 缺点:
- 服务器压力太大,数据库容量暴增。
- 如果不能连接到服务器上,基本上不可以工作,看上面第二步,如果服务器不能连接上,就不能提交,还原,对比等等。
- 不适合开源开发(开发人数非常非常多,但是Google app engine就是用svn的)。但是一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理,从而很好的解决开发人数众多的问题。
Git优缺点
- 优点:
- 适合分布式开发,强调个体。
- 公共服务器压力和数据量都不会太大。
- 速度快、灵活。
- 任意两个开发者之间可以很容易的解决冲突。
- 离线工作。
- 缺点:
- 学习周期相对而言比较长。
- 不符合常规思维。
- 代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息。
origin 是默认的远程版本库名称,你可以在 .git/config 之中进行修改,事实上 git push origin master 的意思是 git push origin master:master (将本地的 master 分支推送至远端的 master 分支,如果没有就新建一个)
pull相当于git fetch 和 git merge,即更新远程仓库的代码到本地仓库,然后将内容合并到当前分支。
- git fetch:相当于是从远程获取最新版本到本地,不会自动merge
- git merge : 将内容合并到当前分支
- git pull:相当于是从远程获取最新版本并merge到本地
- git show # 显示某次提交的内容 git show $id
- git add
# 将工作文件修改提交到本地暂存区 - git rm
# 从版本库中删除文件 - git reset
# 从暂存区恢复到工作文件 - git reset HEAD^ # 恢复最近一次提交过的状态,即放弃上次提交后的所有本次修改
- git diff
# 比较当前文件和暂存区文件差异 git diff - git log -p
# 查看每次详细修改内容的diff - git branch -r # 查看远程分支
- git merge
# 将branch分支合并到当前分支 - git stash # 暂存
- git stash pop #恢复最近一次的暂存
- git pull # 抓取远程仓库所有分支更新并合并到本地
- git push origin master # 将本地主分支推到远程主分支
- http是HTTP协议运行在TCP之上。所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。
- https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。此外客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份
为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。用TCP协议把数据包送出去后,TCP不会对传送 后的情况置之不理,它一定会向对方确认是否成功送达。握手过程中使用了TCP的标志:SYN和ACK。
发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。
最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。
若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。
- 当发送一个URL请求时,不管这个URL是Web页面的URL还是Web页面上每个资源的URL,浏览器都会开启一个线程来处理这个请求,同时在远程DNS服务器上启动一个DNS查询。这能使浏览器获得请求对应的IP地址。
- 浏览器与远程`Web`服务器通过`TCP`三次握手协商来建立一个`TCP/IP`连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。
- 一旦`TCP/IP`连接建立,浏览器会通过该连接向远程服务器发送`HTTP`的`GET`请求。远程服务器找到资源并使用HTTP响应返回该资源,值为200的HTTP响应状态表示一个正确的响应。
- 此时,`Web`服务器提供资源服务,客户端开始下载资源。请求返回后,便进入了我们关注的前端模块简单来说,浏览器会解析`HTML`生成`DOM Tree`,其次会根据CSS生成CSS Rule Tree,而`javascript`又可以根据`DOM API`操作`DOM`
总结:
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回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)
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
- 渐进增强:
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
- 解析HTML文件,创建DOM树。自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。
- 解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式
- 将CSS与DOM合并,构建渲染树(Render Tree)
- 布局和绘制,重绘(repaint)和重排(reflow)
node端
Node 的 Event Loop 分为 6 个阶段,它们会按照顺序反复运行。每当进入某一个阶段的时候,都会从对应的回调队列中取出函数去执行。当队列为空或者执行的回调函数数量到达系统设定的阈值,就会进入下一阶段。
Event Loop 6 个阶段:
- timers
- I/O callbacks
- idle, prepare
- poll
- check
- close callbacks
浏览器端
浏览器端 的情况与 node端 的情况相仿,当我们执行 JS 代码的时候其实就是往执行栈中放入函数,当遇到异步的代码时,会被挂起并在需要执行的时候加入到 Task(有多种 Task) 队列中。一旦执行栈为空,Event Loop 就会从 Task 队列中拿出需要执行的代码并放入执行栈中执行。
- 微任务(microtask)
- process.nextTick
- promise
- Object.observe(曾经是提案,如今已经废除)
- MutationOberver
- 宏任务(macrotask)
- script
- setTimeout
- setInterval
- setImmediate
- I/O
- UI渲染
执行顺序如下:
- 执行同步代码,这是宏任务
- 执行栈为空,查询是否有微任务要执行
- 必要时渲染UI
- 进行下一轮的 EventLoop ,执行宏任务中的异步代码
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时,被视为准备回收的对象。
- 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.样式表置顶、脚本置低