答: 常用浏览器有chrome、safari、 IE、火狐(firefox) 、 Opera 、360、搜狗等
浏览器 | 内核 | 备注 |
---|---|---|
IE | Trident | IE、猎豹安全、360极速浏览器、百度浏览器 |
firefox | Gecko | 可惜这几年已经没落了,打开速度慢、升级频繁、猪一样的队友flash、神一样的对手chrome。 |
Safari | webkit | 现在很多人错误地把 webkit 叫做 chrome内核(即使 chrome内核已经是 blink 了)。苹果感觉像被别人抢了媳妇,都哭晕再厕所里面了。 |
chrome | Chromium/Blink | 在 Chromium 项目中研发 Blink 渲染引擎(即浏览器核心),内置于 Chrome 浏览器之中。Blink 其实是 WebKit 的分支。大部分国产浏览器最新版都采用Blink内核。二次开发 |
Opera | blink | Presto(已经废弃) 是挪威产浏览器 opera 的 “前任” 内核,现在跟随chrome用blink内核。 |
1)为了在没有CSS的情况下,页面也能呈现出很好地内容结构、代码结构
2)用户体验:例如title、alt用于解释名词
3)有利于SEO:利于被搜索引擎收录,更便于搜索引擎的爬虫程序来识别
4)方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页
5)便于项目的开发及维护,使HTML代码更具有可读性
1.href:Hypertext Reference的缩写,超文本引用,它指向一些网络资源,建立和当前元素或者说是本文档的链接关系。在加载它的时候,不会停止对当前文档的处理,浏览器会继续往下走。常用在a、link等标签。
2.src:source的所写,表示的是对资源的引用,它指向的内容会嵌入到当前标签所在的位置。由于src的内容是页面必不可少的一部分,因此浏览器在解析src时会停下来对后续文档的处理,直到src的内容加载完毕。常用在script、img、iframe标签中,我们建议js文件放在HTML文档的最后面。如果js文件放在了head标签中,可以使用window.onload实现js的最后加载。
总结:href用于建立当前页面与引用资源之间的关系(链接),而src则会替换当前标签。遇到href,页面会并行加载后续内容;而src则不同,浏览器需要加载完毕src的内容才会继续往下走。
1.从属关系区别
@import是 CSS 提供的语法规则,只有导入样式表的作用;link是HTML提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性等。
2.加载顺序区别
加载页面时,link标签引入的 CSS 被同时加载;@import引入的 CSS 将在页面加载完毕后被加载。
3.兼容性区别
@import是 CSS2.1 才有的语法,故只可在 IE5+ 才能识别;link标签作为 HTML 元素,不存在兼容性问题。
4.DOM可控性区别
可以通过 JS 操作 DOM ,插入link标签来改变样式;由于 DOM 方法是基于文档的,无法使用@import的方式插入样式。
5.权重区别(该项有争议,下文将详解)
link引入的样式权重大于@import引入的样式。
!important > 内联样式 > ID选择器 > 类选择器(属性选择器、伪类选择器)> 元素选择器(伪元素选择器)> 通配符选择器
样式系统从右向左匹配规则。只要当前选择符的左边还有其他选择符,样式系统就会继续向左移动,直到找到和规则匹配的元素,或者因为不匹配而退出。
是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点);而从左向右的匹配规则的性能都浪费在了失败的查找上面。
块元素在垂直方向上的margin是很奇怪的,会有重叠现象。
如果display都是block,有三种情况:
外间距均为正数,竖直方向上会选择最大的外边距作为间隔
一正一负,间距 = 正 - |负|
两个负,间距 = 0 - 绝对值最大的那个
设置display: inline-block的盒子不会有margin重叠,position: absolute的也不会出现。
静态、自适应、流式、响应式四种网页布局;
静态布局:意思就是不管浏览器尺寸具体是多少,网页布局就按照当时写代码的布局来布置;
自适应布局:就是说你看到的页面,里面元素的位置会变化而大小不会变化;
流式布局:你看到的页面,元素的大小会变化而位置不会变化——这就导致如果屏幕太大或者太小都会导致元素无法正常显示。
响应式布局:每个屏幕分辨率下面会有一个布局样式,同时位置会变而且大小也会变。
position 属性规定元素的定位类型。
值 | 描述 |
---|---|
absolute | 生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。 |
fixed | 生成绝对定位的元素,相对于浏览器窗口进行定位。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。 |
relative | 生成相对定位的元素,相对于其正常位置进行定位。因此,“left:20” 会向元素的 LEFT 位置添加 20 像素。 |
sticky | 粘性定位(而sticky相当于加了一个滚动事件的处理,当页面滚动到相对应的元素上,就会变成固定定位的效果。当滚动到父元素不在可视区域范围内时,定位效果就会消失。) |
static | 默认值。没有定位,元素出现在正常的流中 |
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域.
|| : 只要其中有一个为true,整体结果是true;
&& : 只要有一个是false,整体结果是false;
!:取反 (比较:转布尔,在取反)
答案:前者会自动转换类型,再判断是否相等
后者不会自动类型转换,直接去比较
==如何自动转换类型:
如果有一边的操作数是布尔值,则将true转换为1,false转换为0
如果有一边的操作符是字符串,则用Number()方法将字符串转换为数值,再比较
null和undefined是相等的,而且不管是它俩之间相互比较还是它们中任何一个和别的比较,它俩都不会转换为其它任何值
NaN和任何值都不相等,包括它本身
一个操作数是对象,另一个不是对象时:调用对象的valueOf()方法得到对象的基本类型值,再进行比较
方法 | 描述 |
---|---|
charAt() | 返回在指定位置的字符。 |
charCodeAt() | 返回在指定的位置的字符的 Unicode 编码。 |
concat() | 连接两个或更多字符串,并返回新的字符串。 |
fromCharCode() | 将 Unicode 编码转为字符。 |
indexOf() | 返回某个指定的字符串值在字符串中首次出现的位置。 |
includes() | 查找字符串中是否包含指定的子字符串。 |
lastIndexOf() | 从后向前搜索字符串,并从起始位置(0)开始计算返回字符串最后出现的位置。 |
search() | 查找与正则表达式相匹配的值。 |
slice() | 提取字符串的片断,并在新的字符串中返回被提取的部分。不包含结束的索引 |
split() | 把字符串分割为字符串数组。 |
substr() | 从起始索引号提取字符串中指定数目的字符。 |
substring() | 提取字符串中两个指定的索引号之间的字符。 |
toLowerCase() | 把字符串转换为小写。 |
toUpperCase() | 把字符串转换为大写。 |
trim() | 去除字符串两边的空白 |
toString() | 返回一个字符串。 |
在Javscript中,解析器在向执行环境中加载数据时,对函数声明和函数表达式并非是一视同仁的,解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问),至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解析执行。
答案:string,boolean,number,undefined,function,object
作用域是指程序源代码中定义变量的区域,简单来说,一段程序代码中所用到的变量并不总是有效的,而限定这个变量的可用性的代码范围就是这个变量的作用域。
js有三种:
一般情况下,变量取值到创建这个变量的函数的作用域中取值。但是如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
//改变原数组方法:
var arr = []
arr.push() //数组末尾添加
arr.pop() //数组末尾删除
arr.unshift() //数组头部添加
arr.shift() //数组头部删除
arr.splice() //方法向/从数组中添加/删除项目,然后返回被删除的项目。
arr.reverse() //方法用于颠倒数组中元素的顺序。
arr.sort() //方法用于对数组的元素进行排序。
//不改变原数组方法:
var arr = []
arr.includes(); // 方法用于判断字符串是否包含指定的子字符串。如果找到匹配的字符串则返回 true,否则返回 false。
arr.indexOf(); //方法可返回某个指定的字符串值在字符串中首次出现的位置。
arr.lastIndexOf(); //方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。
arr.slice(); //方法可从已有的数组中返回选定的元素。
arr.join(); //方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。
arr.toString();
arr.concat(); //方法用于连接两个或多个数组。
Object 是 JavaScript 中所有对象的父对象
数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp、Error
简单类型(基本数据类型、值类型):在存储时变量中存储的是值本身,包括String ,Number,Boolean,Undefined,Null
复杂数据类型(引用类型):在存储时变量中存储的仅仅是地址(引用),通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等;
1.创建新节点
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
2.添加、移除、替换、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入
remove()//删除所有的子元素
3.查找
getElementsByTagName() //通过标签名称
getElementsByClassName() //通过元素的class属性的值
getElementById() //通过元素Id,唯一性
“DOM事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡。
JS事件流最早要从IE和网景公司的浏览器大战说起,IE提出的是冒泡流,而网景提出的是捕获流,后来在W3C组织的统一之下,JS支持了冒泡流和捕获流,但是目前低版本的IE浏览器还是只能支持冒泡流(IE6,IE7,IE8均只支持冒泡流),所以为了能够兼容更多的浏览器,建议大家使用冒泡流。
事件委托又叫事件代理,利用事件冒泡的原理,原本绑定在子元素身上的事件,现在绑定在父元素身上,由父元素监听事件的行为。
优点:
1.可以减少事件注册,节省大量内存占用
2.可以将事件应用于动态添加的子元素上
缺点:
使用不当会造成事件在不应该触发时触发
this 的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this 的指向不同
BOM全称Browser Object Model,即浏览器对象模型,主要处理浏览器窗口和框架。
DOM全称Document Object Model,即文档对象模型,是 HTML 和XML 的应用程序接口(API),遵循W3C 的标准,所有浏览器公共遵守的标准。
可以说,BOM包含了DOM(对象),浏览器提供出来给予访问的是BOM对象,从BOM对象再访问到DOM对象,从而js可以操作浏览器以及浏览器读取到的文档。
它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
window对象有很多子对象,除了 document以外,还有如下常用子对象:
答:新增加了图像、位置、存储、多任务等功能。
新增元素:
移除的元素:
兼容性问题:
区分:
iframe:是一个内联框架(行内框架),可以包含另外一个文档的内容。
1.iframe能够原封不动的把嵌入的网页展现出来。
2.如果有多个网页引用iframe,那么你只需要修改iframe的内容,就可以实现调用的每一个页面内容的更改,方便快捷。
3.网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用iframe来嵌套,可以增加代码的可重用。
4.如果遇到加载缓慢的第三方内容如图标和广告,这些问题可以由iframe来解决。
1.会产生很多页面,不容易管理。
2.iframe框架结构有时会让人感到迷惑,如果框架个数多的话,可能会出现上下、左右滚动条,会分散访问者的注意力,用户体验度差。
3.代码复杂,无法被一些搜索引擎索引到,这一点很关键,现在的搜索引擎爬虫还不能很好的处理iframe中的内容,所以使用iframe会不利于搜索引擎优化。
4.很多的移动设备(PDA 手机)无法完全显示框架,设备兼容性差。
5.iframe框架页面会增加服务器的http请求,对于大型网站是不可取的。
14.新增选择器:属性选择器、伪类选择器、伪元素选择器。
单冒号(:)用于CSS2的写法,双冒号(::)用于CSS3的写法。
::before就是以一个子元素的存在,定义在元素主体内容之前的一个伪元素。并不存在于dom之中,只存在在
页面之中
:before的兼容性要比::before好
1.display:flex;(定义了一个flex容器)
2.flex-direction(决定主轴的方向)
row(默认值,水平从左到右)colunm(垂直从上到下)row-reverse(水平从右到左)column-reverse(垂直从下到上)
3.flex-wrap(定义如何换行)
nowrap(默认值,不换行)wrap(换行)wrap-reverse(换行,且颠倒行顺序,第一行在下方)
4.flex-flow(属性是 flex-direction 属性和 flex-wrap 属性的简写形式,默认值为row nowrap)
5.justify-content(设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式)
flex-start( 默认值、弹性盒子元素将向行起始位置对齐)
flex-end(弹性盒子元素将向行结束位置对齐)
center(弹性盒子元素将向行中间位置对齐。该行的子元素将相互对齐并在行中居中对齐)
space-between(弹性盒子元素会平均地分布在行里)
space-around(弹性盒子元素会平均地分布在行里,两端保留子元素与子元素之间间距大小的一半)
6.align-items(设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式)
flex-start(弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界)
flex-end(弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界)
center( 弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度))
baseline(如弹性盒子元素的行内轴与侧轴为同一条,则该值与flex-start等效。其它情况下,该值将参与基线对齐。)
stretch(如果指定侧轴大小的属性值为’auto’,则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照’min/max-width/height’属性的限制)
7.align-content(设置或检索弹性盒堆叠伸缩行的对齐方式)
flex-start(各行向弹性盒容器的起始位置堆叠。弹性盒容器中第一行的侧轴起始边界紧靠住该弹性盒容器的侧轴起始边界,之后的每一行都紧靠住前面一行)
flex-end(各行向弹性盒容器的结束位置堆叠。弹性盒容器中最后一行的侧轴起结束界紧靠住该弹性盒容器的侧轴结束边界,之后的每一行都紧靠住前面一行)
center(各行向弹性盒容器的中间位置堆叠。各行两两紧靠住同时在弹性盒容器中居中对齐,保持弹性盒容器的侧轴起始内容边界和第一行之间的距离与该容器的侧轴结束内容边界与第最后一 行之间的距离相等)
space-between(各行在弹性盒容器中平均分布。第一行的侧轴起始边界紧靠住弹性盒容器的侧轴起始内容边界,最后一行的侧轴结束边界紧靠住弹性盒容器的侧轴结束内容边界,剩余的行则 按一定方式在弹性盒窗口中排列,以保持两两之间的空间相等)
space-around( 各行在弹性盒容器中平均分布,两端保留子元素与子元素之间间距大小的一半。各行会按一定方式在弹性盒容器中排列,以保持两两之间的空间相等,同时第一行前面及最后 一行后面的空间是其他空间的一半)
stretch(各行将会伸展以占用剩余的空间。剩余空间被所有行平分,以扩大它们的侧轴尺寸)
1.order(默认情况下flex order会按照书写顺训呈现,可以通过order属性改变,数值小的在前面,还可以是负数)
2.flex-grow(设置或检索弹性盒的扩展比率,根据弹性盒子元素所设置的扩展因子作为比率来分配剩余空间)
3.flex-shrink(设置或检索弹性盒的收缩比率,根据弹性盒子元素所设置的收缩因子作为比率来收缩空间)
4.flex-basis (设置或检索弹性盒伸缩基准值,如果所有子元素的基准值之和大于剩余空间,则会根据每项设置的基准值,按比率伸缩剩余空间)
5.flex (flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选)
//flex属性意义
flex:none; // flex:0,0,auto;
flex:auto; // flex:1,1,auto;
flex:1; // flex:1,1,0%;
6.align-self (设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式,可以覆盖父容器align-items的设置)
响应式网站设计(Responsive Web design)是一个网站能够兼容多个终端,而不是为每一个终端做一个特定的版本。
基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理。
页面头部必须有meta声明的viewport。
绘制出来的每⼀个图形的元素都是独⽴的 DOM 节点,能够⽅便的绑定事件或⽤来修 。
属性
属性 | 描述 |
---|---|
origin | 返回当前网页的域名(比如http://192.168.1.12:8092) |
hostname | 返回URL的主机名 |
port | 返回一个URL服务器使用的端口号 |
pathname | 返回的URL路径名。 |
protocol | 返回一个URL协议 |
hash | 返回从井号 (#) 开始的 URL(锚) |
href | 返回完整的URL |
search | 返回从问号 (?) 开始的 URL(查询部分) |
host | 返回一个URL的主机名和端口 |
方法
属性 | 描述 |
---|---|
replace() | 用新的文档替换当前文档。替换当前页面,不记录历史,不可以后退 |
reload() | 重新加载当前文档。相当于点击刷新按钮刷新F5,如果参数为true,相当于ctrl+F5强制刷新 |
assign() | 加载新的文档。跟href一样,可以跳转页面 |
window.navigator 接口表示用户代理的状态和标识。
navigator 对象包含有关浏览器的信息,它有很多属性,我们最常用的是 userAgent,该属性可以返回由客户机发送服务器的 user-agent 头部的值。
Navigator.onLine网络状态
onLine 属性是一个只读的布尔值,声明了系统是否处于脱机模式,如果系统属于脱机状态,则返回 false,否则返回 true。
HTML5 给我们提供了2个事件 online 和 offline,给window绑定事件–检测网络开始状态
属性
length 返回浏览器历史列表中的 URL 数量。
方法
back() 加载 history 列表中的前一个 URL。
forward() 加载 history 列表中的下一个 URL。
go() 加载 history 列表中的某个具体页面。
被拖动的源对象可以触发的事件:
(1)ondragstart:源对象开始被拖动
(2)ondrag:源对象被拖动过程中(鼠标可能在移动也可能未移动)
(3)ondragend:源对象被拖动结束
拖动源对象可以进入到上方的目标对象可以触发的事件:
(1)ondragenter:目标对象被源对象拖动着进入
(2)ondragover:目标对象被源对象拖动着悬停在上方
(3)ondragleave:源对象拖动着离开了目标对象
(4)ondrop:源对象拖动着在目标对象上方释放/松手
DataTransfer
在进行拖放操作时,DataTransfer
对象用来保存被拖动的数据。它可以保存一项或多项数据、一种或者多种数据类型
除非被清除,否则永久保存 clear()可清除,
sessionStorage 仅在当前会话下有效,关闭页面或浏览器后被清除
常问的点,前者是在一定时间过后将函数添加至执行队列,执行时间=延迟时间+之前函数代码执行时间+执行函数时间。
后者是不管前一次是否执行完毕,每隔一定时间重复执行,用于精准执行互相没有影响的重复操作。
如果需要控制前后执行顺序,最好使用setTimeout模拟setInterval
**原型:**
每一个构造函数,都会带有一个 prototype
属性。该属性指向一个对象,该对象称之为 原型对象
。其所有的属性和方法都能被构造函数的实例对象共享访问,因为实例都包含着一个指向原型对象的内部指针 __proto__
。可以通过内部指针 __proto__
访问到原型对象,
原型对象
上默认有一个 constructor
属性,指向其相关联的构造函数。
**原型链:**
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__
上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__
中查找(即上一层构造函数的prototype),这样一层一层向上查找直到Object的prototype结束,这样就会形成一个链式结构,我们称为原型链。我们可以说:它们是继承关系
**call:**
call(thisObj, obj1, obj2…)
要求传入函数的参数是参数列表
**apply:**
apply(thisObj, [argArray])
要求传入函数的参数必须放入数组中整体传入
**bind:**
.bind(thisObj,arg1,arg2,…),
共同点 : 都可以改变this指向
不同点:
应用场景
相同点
1、都是循环遍历数组中的每一项
2、forEach和map方法里每次执行匿名函数都支持3个参数,参数分别是item(当前每一项)、index(索引值)、arr(原数组)
3、匿名函数中的this都是指向window
4、只能遍历数组
区别
1、forEach()返回值是undefined,不可以链式调用
2、map()返回一个新数组,原数组不会改变;forEach()会修改原来的数组
3、map速度比forEach快
4、map里可以用return ,而foreach里用return不起作用
JavaScript 除了提供正常模式外,还提供了严格模式(strict mode)。ES5 的严格模式是采用具有限制性 JavaScript变体的一种方式,即在严格的条件下运行 JS 代码。
严格模式在 IE10 以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。
设立严格模式的原因:
1、消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
2、消除代码运行的一些不安全之处,保证代码运行的安全;
3、提高编译器效率,增加运行速度;
4、为未来新版本的Javascript做好铺垫。
严格模式下的语法变化:
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
只需满足以下任意一个条件,即是高阶函数:
\1. 接受一个或多个函数作为输入
\2. return 返回另外一个函数
**概念:**内部函数访问其所在的外部函数中声明的参数和变量,形成的词法环境叫闭包.
闭包有三个特性:
使用闭包的好处:
使用闭包的坏处:
深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。
浅拷贝: 只复制指向某个对象的指针****而不复制对象本身,新旧对象还是共享同一块内存。
Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign()进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。
深拷贝:会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
深拷贝的实现方式
1.JSON.parse(JSON.stringify())
原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。
2.手写递归方法
递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝;
参照文档:https://www.cnblogs.com/zhangguicheng/p/12768743.html
构造函数:
class类:
1、typeOf :只能检测基本数据类型
2、instanceOf :检测当前实例是否属于某个类的方法
3、construtor : 检测当前实例的构造函数
4、Object.prototype.toString.call( ) : 最准确的方式;
12.怎么判断一个原型是否是这个对象的原型
使用: Object.prototype.isPrototypeOf()进行比较
var obj1 = {name: “Lilei”};
var obj2 = Object.create(obj1);
obj1.isPrototypeOf(obj2); // true
1、 不要在同一行声明多个变量
2、使用 ===或!==来比较true/false或者数值
3、 switch必须带有default分支
4、 函数应该有返回值
5、 for if else 必须使用大括号
6、 语句结束加分号
7、 命名要有意义,使用驼峰命名法
栈(stack):由编译器自动分配释放,存放函数的参数值,局部变量等;
堆(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统释放。
window对象代表浏览器中打开的一个窗口。
document对象代表整个html文档。
**小谷告诉你:**实际上,document对象是window对象的一个属性。
1、浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
2、解析出 IP 地址后,根据该 IP 地址和默认端口80,和服务器建立TCP连接;
3、浏览器发出读取文件(URL中域名后面部分对应的文件)的HTTP请求,
该请求消息作为 TCP三次握手的第三个报文的数据发送给服务器;
4、服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器
5、释放TCP连接;
6、浏览器加载该 html 文本并显示内容;
在网络数据传输中,传输层协议TCP(传输控制协议)是建立连接的可靠传输,TCP建立连接的过程,我们称为****三次握手。
第一次,客户端向服务器发送SYN同步报文段,请求建立连接
第二次,服务器确认收到客户端的连接请求,并向客户端发送SYN同步报文,表示要向客户端建立连接
第三次,客户端收到服务器端的确认请求后,处于建立连接状态,向服务器发送确认报文
小谷课堂:
客户端是在收到确认请求后,先建立连接
服务器是在收到最后客户端的确认后,建立连接
发起连接请求的一定是客户端
在网络数据传输中,传输层协议断开连接的过程我们称为****四次挥手。
第一次,A端像B端发送FIN结束报文段,准备关闭连接
第二次,B端确认A端的FIN,表示自己已经收到对方关闭连接的请求
(中间这段时间,A端停止向B端发送数据,但是B端可以向A端发送数据,要将自己未处理完任务处理完)
第三次,B端向A端发送FIN结束报文段,准备关闭连接
第四次,A端确认B端的FIN,进入TIME_WAIT状态,此时A端进程已经退出,但是连接还在
小谷课堂:
当B端收到A端的ACK之后,先断开连接
当A端等待2 MSL之后,确认的B端接收到ACK后,再断开连接
发起断开连接请求的一端最后要进入有一个TIME_WAIT状态
发起连接请求的可以是客户端也可以是服务器端
一、传输信息安全性不同
1、http协议:是超文本传输协议,信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。
2、https协议:是具有安全性的ssl加密传输协议,为浏览器和服务器之间的通信加密,确保数据传输的安全。
二、连接方式不同
1、http协议:http的连接很简单,是无状态的。
2、https协议:是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议。
三、端口不同
1、http协议:使用的端口是80。2、https协议:使用的端口是443.
四、证书申请方式不同
1、http协议:免费申请。2、https协议:需要到ca申请证书,一般免费证书很少,需要交费。
小谷来帮你
1XX :信息状态码 2XX :成功状态码 3XX :重定向
4XX :客户端错误 5XX: 服务器错误
100 信息服务器收到请求,需要请求者继续执行操作
200 (成功) 服务器已成功处理了请求。
301 表示永久性重定向。
302 表示临时性重定向。
303 临时性重定向,且总是使⽤ GET 请求新的 URI
304 (未修改) 自从上次请求后,请求的网页未修改过。
400 (错误请求) 服务器不理解请求的语法。
403 (禁止) 服务器拒绝请求。
404 (未找到) 服务器找不到请求的网页。
405 (not allowed)请求不允许
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
503 表示服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
区别:
1、get使用地址栏提交参数 ; 而Post是通过提交请求体提交参数。
2、get传送的数据量较小,不能大于2KB ; post 传送的数据量较大。
3、get是从服务器上获取数据 ; post 是向服务器传送数据,一般用于修改服务器上的资源。
4、POST 效率高于 GET
5、GET默认可以缓存而POST不会
6、GET 参数url可见 POST的不可见
7、GET 通过拼接url进行传递参数 POST 通过body 体传输参数
8、GET只接受ASCll字符,而POST没限制
9、POST 比 GET 安全
以下几种情况用post方法:
1.请求的结果有持续性的作用,例如:数据库内添加新的数据行
2.若使用get方法,则表单上收集的数据可能让URL过长
3.要传送的数据不是采用ASCII编码
AJAX = 异步 JavaScript 和 XML。 AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。
ajax应用程序的优势在于:
Ajax可以实现动态不刷新(局部刷新) 就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变过的信息。
Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。通过XMLHttpRequest对象,Web开发人员可以在页面加载以后进行页面的局部更新。
常用的post,get,delete put
//创建 XMLHttpRequest 对象
var ajax = new XMLHttpRequest();
//规定请求的类型、URL 以及是否异步处理请求。
ajax.open('GET',url,true);
//发送信息至服务器时内容编码类型
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//发送请求
ajax.send(null);
//接受服务器响应数据
ajax.onreadystatechange = function () {
if (obj.readyState == 4 && (obj.status == 200 || obj.status == 304)) {
}
}
要说跨域,首先得说同源策略
**同源策略 :**是浏览器的安全策略,协议名、域名、端口号必须完全一致。
跨域是违背同源策略就会产生跨域。
解决跨域的方法:
vue代理配置 nginx代理配置 后端设置 jsonp(前后端配合)
1、主机到网络层
实际上TCP/IP参考模型没有真正描述这一层的实现,只是要求能够提供给其上层-网络互连层一个访问接口,以便在其上传递IP分组。由于这一层次未被定义,所以其具体的实现方法将随着网络类型的不同而不同。
2、网络互连层
网络互连层是整个TCP/IP协议栈的核心。它的功能是把分组发往目标网络或主机。同时,为了尽快地发送分组,可能需要沿不同的路径同时进行分组传递。因此,分组到达的顺序和发送的顺序可能不同,这就需要上层必须对分组进行排序。
网络互连层定义了分组格式和协议,即IP协议(Internet Protocol)。
网络互连层除了需要完成路由的功能外,也可以完成将不同类型的网络(异构网)互连的任务。除此之外,网络互连层还需要完成拥塞控制的功能。
3、传输层
在TCP/IP模型中,传输层的功能是使源端主机和目标端主机上的对等实体可以进行会话。在传输层定义了两种服务质量不同的协议。即:传输控制协议TCP(transmission control protocol)和用户数据报协议UDP(user datagram protocol)。
TCP协议是一个面向连接的、可靠的协议。它将一台主机发出的字节流无差错地发往互联网上的其他主机。在发送端,它负责把上层传送下来的字节流分成报文段并传递给下层。在接收端,它负责把收到的报文进行重组后递交给上层。TCP协议还要处理端到端的流量控制,以避免缓慢接收的接收方没有足够的缓冲区接收发送方发送的大量数据。
UDP协议是一个不可靠的、无连接协议,主要适用于不需要对报文进行排序和流量控制的场合。
4、应用层
TCP/IP模型将OSI参考模型中的会话层和表示层的功能合并到应用层实现。
应用层面向不同的网络应用引入了不同的应用层协议。其中,有基于TCP协议的,如文件传输协议(File Transfer Protocol,FTP)、虚拟终端协议(TELNET)、超文本传输协议(Hyper Text Transfer Protocol,HTTP),也有基于UDP协议的。
JSONP(JSON with Padding) ,利用script标签本来就具备的跨域请求功能,请求后台接口地址,来完成数据请求的,这种跨域的通讯方式称为JSONP。
JSONP的原理 : 利用script标签可以获取不同源资源的特点,来达到跨域访问某个资源的目的。
缺点:
1、JSONP只支持GET请求,不支持POST等其它类型的HTTP请求
2、JSONP只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
3、JSONP在调用失败的时候不会返回各种HTTP状态码。
4、JSONP缺点是安全性。
数据体积方面。JSON相对于XML来讲,数据的体积小,传递的速度更快些。
数据交互方面。JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。
数据描述方面。JSON对数据的描述性比XML较差。
传输速度方面。JSON的速度要远远快于XML。
1、JSON是JavaScript Object Notation;XML是可扩展标记语言。
2、JSON是基于JavaScript语言;XML源自SGML。
3、JSON是一种表示对象的方式;XML是一种标记语言,使用标记结构来表示数据项。
4、JSON仅支持UTF-8编码;XML支持各种编码。
5、JSON支持数组;XML不支持数组。
6、XML用来传输和存储数据,HTML用来显示数据。
7、JSON不使用结束标记;XML有开始和结束标签。
8、JSON的安全性较低;XML比JSON更安全。
9、JSON不支持注释;XML支持注释。
ID 选择器使用 ID 来选择元素,比如 #element1,而 class 选择器使用 CSS class 来选择元素。
当你只需要选择一个元素时,使用 ID 选择器,而如果你想要选择一组具有相同 CSS class 的元素,就要用 class 选择器。
ready() 函数用于在文档进入ready状态时执行代码。当DOM 完全加载(例如HTML被完全解析DOM树构建完成时),jQuery允许你执行代码。使用$(document).ready()的最大好处在于它适用于所有浏览器,jQuery帮你解决了跨浏览器的难题。
JavaScript window.onload 事件除了要等待 DOM 被创建还要等到包括大型图片、音频、视频在内的所有外部资源都完全加载。如果加载图片和媒体内容花费了大量时间,用户就会感受到定义在 window.onload 事件上的代码在执行时有明显的延迟。
jQuery ready() 函数只需对 DOM 树的等待,而无需对图像或外部资源加载的等待,从而执行起来更快。使用 jQuery $(document).ready() 的另一个优势是你可以在网页里多次使用它,浏览器会按它们在 HTML 页面里出现的顺序执行它们,相反对于 onload 技术而言,只能在单一函数里使用。
**总结:**用 jQuery ready() 函数比用 JavaScript window.onload 事件要更好些。
$(this) 返回一个 jQuery 对象,你可以对它调用多个 jQuery 方法,比如用 text() 获取文本等。而 this 代表当前元素,它是 JavaScript 关键词中的一个,表示上下文中的当前 DOM 元素。你不能对它调用 jQuery 方法,直到它被 $() 函数包裹,例如 $(this)。
通过利用 addClass() 和 removeClass() 这两个 jQuery 方法。
动态的改变元素的class属性可以很简单例如. 使用类“.active"来标记它们的未激活和激活状态,等等
.addClass(“类名”)添加元素 .remove() 删除样式类
ajax() 方法更强大,更具可配置性, 让你可以指定等待多久,以及如何处理错误。
get() 方法是一个只获取一些数据的专门化方法。
方法链是对一个方法返回的结果调用另一个方法,这使得代码简洁明了,同时由于只对 DOM 进行了一轮查找,性能方面更加出色。
$.get()
提交和$.post()
提交有区别吗?$.get()
方法使用GET方法来进行异步请求的。$.post()
方法使用POST方法来进行异步请求的。$.ajax()
的请求方式?$.ajax({
url:'http://www.baidu.com',
type:'POST',
data:data,
cache:true,
headers:{},
beforeSend:function(){},
success:function(){},
error:function(){},
complete:function(){}
});
选择器大致分为:基本选择器,层次选择器,过滤选择器,表单选择器
答:append(),appendTo(),prepend(),prependTo(),after(),insertAfter() before(),insertBefore()
内添加
1.append在文档内添加元素
2.appendTo()把匹配的元素添加到对象里
3.prepend()在元素前添加
4.prependTo()把匹配的元素添加到对象前
外添加
1.after()在元素之后添加
2.before()在元素之前添加
3.insertAfter()把匹配元素在对象后添加
4.insertBefore()把匹配元素在对象前添加
children() 取得匹配元素的子元素集合,只考虑子元素不考虑后代元素
next() 取得匹配元素后面紧邻的同辈元素
prev() 取得匹配元素前面紧邻的同辈元素
siblings() 取得匹配元素前后的所有同辈元素
closest() 取得最近的匹配元素
find() 取得匹配元素中的元素集合,包括子代和后代
each() 函数就像是 Java 里的一个 Iterator,它允许你遍历一个元素集合。你可以传一个函数给 each() 方法,被调用的 jQuery 对象会在其每个元素上执行传入的函数。
初始化git仓库 :git init
新增文件的命令:git add file或者git add .
提交文件的命令:git commit –m或者git commit –a(直接提交)
查看工作区状况:git status –s(简洁形式查看)
拉取合并远程分支的操作:git fetch/git merge或者git pull
查看提交记录命令:git log
将 git 仓库中指定的更新记录恢复出来,并且覆盖暂存区和工作目录:git reset --hard commitID
开发过程中,我们都有自己的特性分支,所以冲突发生的并不多,但也碰到过。诸如公共类的公共方法,我和别人同时修改同一个文件,他提交后我再提交就会报冲突的错误。
发生冲突,在IDE里面一般都是对比本地文件和远程分支的文件,然后把远程分支上文件的内容手工修改到本地文件,然后再提交冲突的文件使其保证与远程分支的文件一致,这样才会消除冲突,然后再提交自己修改的部分。特别要注意下,修改本地冲突文件使其与远程仓库的文件保持一致后,需要提交后才能消除冲突,否则无法继续提交。必要时可与同事交流,消除冲突。
发生冲突,也可以使用命令。
通过git stash命令,把工作区的修改提交到栈区,目的是保存工作区的修改;
通过git pull命令,拉取远程分支上的代码并合并到本地分支,目的是消除冲突;
通过git stash pop命令,把保存在栈区的修改部分合并到最新的工作空间中;
命令git stash是把工作区修改的内容存储在栈区。
小谷提醒你:
1、解决冲突文件时,会先执行git stash,然后解决冲突;
2、遇到紧急开发任务但目前任务不能提交时,会先执行git stash,然后进行紧急任务的开发,然后通过git stash pop取出栈区的内容继续开发;
3、切换分支时,当前工作空间内容不能提交时,会先执行git stash再进行分支切换;
git fetch branch是把名为branch的远程分支拉取到本地。
git pull branch是在fetch的基础上,把branch分支与当前分支进行merge;因此pull = fetch + merge。
git merge 合并分支
git rebase 合并多个commit为一个完整commit进行合并提交记录
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
具体自己举例说明
\1. let和const
2.解构赋值,数组和对象的解构
3.剩余及扩展运算符…
4.Symbol基本数据类型
5.Map和Set对象
6.proxy代理和reflect映射
\7. 模板字符串
\8. 箭头函数
9.迭代器iterator
10.Promise async await
11.ES6模块化-export-import
1.Map是键值对,Set是值的集合,当然键和值可以是任何的值;
2.Map可以通过get方法获取值,而set不能因为它只有值;
3.Set的值是唯一的可以做数组去重,Map由于没有格式限制,可以做数据存储
4.map和set都是stl中的关联容器,map以键值对的形式存储,key=value组成pair,是一组映射关系。set只有值,可以认为只有一个数据,并且set中元素不可以重复且自动排序。
第一种数组去重方法(使用Array.from):
let arr = [12,43,23,43,68,12];
let item = new Set(arr);
console.log(item);//结果输出的是一个对象
//使用Array.from转成数组
let arr = [12,43,23,43,68,12];
let item = Array.from(new Set(arr));
console.log(item);// [12, 43, 23, 68]
第二种数组去重方法(使用…扩展运算符):
let arr = [12,43,23,43,68,12];
let item = […new Set(arr)];
console.log(item);//[12, 43, 23, 68]
1、箭头函数本身没有this,它的this指向上下文
2、箭头函数内部没有arguments对象,可以使用rest参数代替
3、不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误
4、没有 propotype原型属性
async await 是用来解决异步的,async函数是Generator函数的语法糖
使用关键字async来表示,在函数内部使用 await 来表示异步
async函数返回一个 Promise 对象,可以使用then方法添加回调函数
当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句
async较Generator的优势:
(1)内置执行器。Generator 函数的执行必须依靠执行器,而 Aysnc 函数自带执行器,调用方式跟普通函数的调用一样
(2)更好的语义。async 和 await 相较于 * 和 yield 更加语义化
(3)更广的适用性。yield命令后面只能是 Thunk 函数或 Promise对象,async函数的await后面可以是Promise也可以是原始类型的值
(4)返回值是 Promise。async 函数返回的是 Promise 对象,比Generator函数返回的Iterator对象方便,可以直接使用 then() 方法进行调用
1.JS 异步编程进化史:callback -> promise -> generator -> async + await
2.async/await 函数的实现,就是将 Generator 函数和自动执行器,包装在一个函数里。
3.async/await可以说是异步终极解决方案了。
(1) async/await函数相对于Promise,优势体现在:
处理 then 的调用链,能够更清晰准确的写出代码
并且也能优雅地解决回调地狱问题。
当然async/await函数也存在一些缺点,因为 await 将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低,代码没有依赖性的话,完全可以使用 Promise.all 的方式。
(2) async/await函数对 Generator 函数的改进,
Generator 函数的执行必须靠执行器,而 async 函数自带执行器。也就是说,async 函数的执行,与普通函数一模一样,只要一行。
1、减少http请求,合理浏览器缓存
2、启用压缩:HTML、CSS、javascript文件启用GZip压缩可达到较好的效果
3、CSS Sprites:合并 CSS图片,减少请求数的又一个好办法。
4、LazyLoad Images:在页面刚加载的时候可以只加载第一屏,当用户继续往后滚屏的时候才加载后续的图片
5、CSS放在页面最上部,javascript放在页面最下面:让浏览器尽快下载CSS渲染页面
6、异步请求Callback(就是将一些行为样式提取出来,慢慢的加载信息的内容)
7、Javascript代码优化
**优雅降级:**Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于IE独特的盒模型布局问题,针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效.
**渐进增强:**从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增加无害于基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。
**重绘与回流是由于浏览器的再次渲染所引起的,所以我们需要先了解浏览器的渲染过程;**一个前端页面无非就是有html、css、JavaScript组成的。
通常来说,渲染引擎会解析HTML文档来构建DOM树,与此同时,渲染引擎也会用CSS解析器解析CSS文档构建CSSOM树。接下来,DOM树和CSSOM树关联起来构成渲染树(RenderTree),这一过程称为Attachment。然后浏览器按照渲染树进行布局(Layout),最后一步通过绘制显示出整个页面。
注意:回流必将引起重绘,而重绘不一定会引起回流。回流会导致渲染树需要重新计算,开销比重绘大,所以我们要尽量避免回流的产生。
回流的产生:
1.页面第一次渲染 在页面发生首次渲染的时候,所有组件都要进行首次布局,这是开销最大的一次回流。
2.浏览器窗口尺寸改变
3.元素位置和尺寸发生改变的时候
4.新增和删除可见元素
5.内容发生改变(文字数量或图片大小等等)
6.元素字体大小变化。
7.激活CSS伪类(例如::hover)。
8.设置style属性
9.查询某些属性或调用某些方法。比如说:
offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight
除此之外,当我们调用getComputedStyle方法,或者IE里的currentStyle时,也会触发回流,原理是一样的,都为求一个“即时性”和“准确性”。
重绘的产生:
当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如
visibility、outline、背景色等属性的改变。
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
**所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。**节流会稀释函数的执行频率。
vue是一个用于创建用户界面的开源JavaScript框架,也是一个创建单页应用的Web应用框架;Vue所关注的核心是MVC模式中的视图层,同时,它也能方便地获取数据更新,并通过组件内部特定的方法实现视图与模型的交互。
Vue.js 是一个优秀的前端界面开发 JavaScript 库,它之所以非常火,是因为有众多突出的特点,其中主要的特点有以下几个。
1) 轻量级的框架
Vue.js 能够自动追踪依赖的模板表达式和计算属性,提供 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API,使读者更加容易理解,能够更快上手。(理解)
2) 双向数据绑定
声明式渲染是数据双向绑定的主要体现,同样也是 Vue.js 的核心,它允许采用简洁的模板语法将数据声明式渲染整合进 DOM。(理解)
3) 指令
Vue.js 与页面进行交互,主要就是通过内置指令来完成的,指令的作用是当其表达式的值改变时相应地将某些行为应用到 DOM 上。(理解)
4) 组件化
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。
在 Vue 中,父子组件通过 props 传递通信,从父向子单向传递。子组件与父组件通信,通过触发事件通知父组件改变数据。这样就形成了一个基本的父子通信模式。
在开发中组件和 HTML、JavaScript 等有非常紧密的关系时,可以根据实际的需要自定义组件,使开发变得更加便利,可大量减少代码编写量。
组件还支持热重载(hotreload)。当我们做了修改时,不会刷新页面,只是对组件本身进行立刻重载,不会影响整个应用当前的状态。CSS 也支持热重载。(理解)
5) 客户端路由
Vue-router 是 Vue.js 官方的路由插件,与 Vue.js 深度集成,用于构建单页面应用。Vue 单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来,传统的页面是通过超链接实现页面的切换和跳转的。(理解)
6) 状态管理
状态管理实际就是一个单向的数据流,State 驱动 View 的渲染,而用户对 View 进行操作产生 Action,使 State 产生变化,从而使 View 重新渲染,形成一个单独的组件。(理解)
组件化
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。
在 Vue 中,父子组件通过 props 传递通信,从父向子单向传递。子组件与父组件通信,通过触发事件通知父组件改变数据。这样就形成了一个基本的父子通信模式。
1)能够把页面抽象成多个相对独立的模块;
2)实现代码重用,提高开发效率和代码质量,便于代码维护
数据驱动
声明式渲染是数据双向绑定的主要体现,同样也是 Vue.js 的核心,它允许采用简洁的模板语法将数据声明式渲染整合进 DOM。(理解)
数据发生变化后,会重新对页面渲染,这就是Vue响应式,那么这一切是怎么做到的呢?
想完成这个过程,我们需要:
侦测数据的变化
收集视图依赖了哪些数据
数据变化时,自动“通知”需要更新的视图部分,并进行更新
也可以说:
数据劫持 / 数据代理
依赖收集
发布订阅模式
MVC:Model View Controller 模型层 视图层 控制器,一种软件设计典范。
MVVM:Model-View-ViewModel 模型-视图-视图模型,是一种设计思想。
优点:分离视图和模型。低耦合,可重用性,独立开发,可测试,双向数据绑定
答:需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。
作用主要是为了高效的更新虚拟DOM。
v-show指令是通过修改元素的displayCSS属性让其显示或者隐藏
v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果
**事件修饰符**
表单修饰符:
v-model.lazy - 取代 input 监听 change 事件
v-model.number - 输入字符串转为有效的数字
v-model.trim - 输入首尾空格过滤
computed计算属性是用来声明式的描述一个值依赖了其它的值。当你在模板里把数据绑定到一个计算属性上时,Vue 会在其依赖的任何值导致该计算属性改变时更新 DOM。它可以让你的代码更加声明式、数据驱动并且易于维护。
watch监听的是你定义的变量,当你定义的变量的值发生变化时,调用对应的方法。就好在div写一个表达式name,data里写入num和lastname,firstname,在watch里当num的值发生变化时,就会调用num的方法,方法里面的形参对应的是num的新值和旧值,而计算属性computed,计算的是Name依赖的值,它不能计算在data中已经定义过的变量。
vue生命周期共分为四个阶段
一:实例创建
二:DOM渲染
三:数据更新
四:销毁实例
共有八个基本钩子函数
1.beforeCreate --创建前
触发的行为:vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。
在此阶段可以做的事情:加loading事件
2.created --创建后
触发的行为:vue实例的数据对象data有了,$el还没有
在此阶段可以做的事情:解决loading,请求ajax数据为mounted渲染做准备
3.beforeMount --渲染前
触发的行为:vue实例的$el和data都初始化了,但还是虚拟的dom节点,具体的data.filter还未替换
在此阶段可以做的事情:。。。
4.mounted --渲染后
触发的行为:vue实例挂载完成,data.filter成功渲染
在此阶段可以做的事情:配合路由钩子使用
5.beforeUpdate --更新前
触发的行为:data更新时触发
在此阶段可以做的事情:。。。
6.updated —更新后
触发的行为:data更新时触发
在此阶段可以做的事情:数据更新时,做一些处理(此处也可以用watch进行观测)
7.beforeDestroy —销毁前
触发的行为:组件销毁时触发
在此阶段可以做的事情:可向用户询问是否销毁
8.destroyed —销毁后
触发的行为:组件销毁时触发,vue实例解除了事件监听以及和dom的绑定(无响应了),但DOM节点依旧存在
在此阶段可以做的事情:组件销毁时进行提示
1、父传子:父组件中通过v-bind绑定一个属性,子组件中通过props接收父组件中的绑定的属性
2、子传父:子组件通过广播的方式$emit将值传递给父组件,父组件中通过一个函数去接收子组件中传递过来的值
3、兄弟间传值:可以通过中间媒介父组件进行传递值得中转
4、使用vuex状态管理,可以实现数据的随意存储和获取
axios 的是一种异步请求,用法和ajax类似,安装npm install axios --save 即可使用,请求中包括get,post,put, patch ,delete等请求方式,
解决跨域可以在请求头中添加Access-Control-Allow-Origin,
也可以在vue.config.js文件中更改proxy配置等解决跨域问题
方法一、使用cancelToken.sourse工厂方法创建cancel token
方法二、通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token
详细信息:https://segmentfault.com/a/1190000040953340?utm_source=sf-similar-article
1.vue-resources不再更新了,vue作者尤大推荐axios。
2.axios就是一个基于ES6的Promise的网络请求库,其实说干净了就是一个打包好的XMLHttpRequests,也就是说,这个也是一个ajax库。
3.axios
在浏览器里建立XHR
通过nodejs进行http请求
转换或者拦截请求数据或响应数据
支持Promise的API
可以取消请求
自动转换JSON
可以防御XSRF攻击!
5.vue-resources
只提供了浏览器版本
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。
详细信息:https://www.jianshu.com/p/b49987c6afcc
this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
答:首先,组件可以提升整个项目的开发效率能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低,难维护,复用性等问题。
然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在道具中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用发射方法
vue-router 有 3 种路由模式:hash、history、
其中,3 种路由模式的说明如下:
答:在router目录下的index.js文件中,对path属性加上/:id。 使用router对象的params.id
一种是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。
第二种:组件内的钩子;
第三种:单独路由独享组件
答:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。简单来说就是:应用遇到多个组件共享状态时,使用vuex。
vuex的流程
页面通过mapAction异步提交事件到action。action通过commit把对应参数同步提交到mutation,mutation会修改state中对应的值。最后通过getter把对应值跑出去,在页面的计算属性中,通过,mapGetter来动态获取state中的值
场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
有五种,分别是State , Getter , Mutation , Action , Module
\1. state:vuex的基本数据,用来存储变量
\2. getter:从基本数据(state)派生的数据,相当于state的计算属性
\3. mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
\4. action:1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
\5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
一、如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
二、如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便
答:vue.js是采用数据劫持结合发布者 - 订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
Proxy 的优势如下:
Object.defineProperty 的优势如下:
兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。
常用对象解析:
(1) scripts:npm run xxx 命令调用node执行的 .js 文件
(2) dependencies:生产环境依赖包的名称和版本号,即这些 依赖包 都会打包进 生产环境的JS文件里面
(3) devDependencies:开发环境依赖包的名称和版本号,即这些 依赖包 只用于 代码开发 的时候,不会打包进 生产环境js文件 里面。
1)代码层面的优化
2)Webpack 层面的优化
3)基础的 Web 技术的优化
Vue 3.0 正走在发布的路上,Vue 3.0 的目标是让 Vue 核心变得更小、更快、更强大,因此 Vue 3.0 增加以下这些新特性:
(1)监测机制的改变
3.0 将带来基于代理 Proxy 的 observer 实现,提供全语言覆盖的反应性跟踪。这消除了 Vue 2 当中基于 Object.defineProperty 的实现所存在的很多限制:
新的 observer 还提供了以下特性:
(2)模板
模板方面没有大的变更,只改了作用域插槽,2.x 的机制导致作用域插槽变了,父组件会重新渲染,而 3.0 把作用域插槽改成了函数的方式,这样只会影响子组件的重新渲染,提升了渲染的性能。
同时,对于 render 函数的方面,vue3.0 也会进行一系列更改来方便习惯直接使用 api 来生成 vdom 。
(3)对象式的组件声明方式
vue2.x 中的组件是通过声明的方式传入一系列 option,和 TypeScript 的结合需要通过一些装饰器的方式来做,虽然能实现功能,但是比较麻烦。
3.0 修改了组件的声明方式,改成了类式的写法,这样使得和 TypeScript 的结合变得很容易。
此外,vue 的源码也改用了 TypeScript 来写。其实当代码的功能复杂之后,必须有一个静态类型系统来做一些辅助管理。
现在 vue3.0 也全面改用 TypeScript 来重写了,更是使得对外暴露的 api 更容易结合 TypeScript。静态类型系统对于复杂代码的维护确实很有必要。
(4)其它方面的更改
vue3.0 的改变是全面的,上面只涉及到主要的 3 个方面,还有一些其他的更改:
应用场景 跨多层父子组件通信 兄弟组件通信
Vue 通过事件发射器接口执行实例,实际上你可以使用一个空的 Vue 实例,原理其实就是发布订阅。
可以通过单独的事件中心管理组件间的通信:
// 将在各处使用该事件中心 // 组件通过它来通信 var eventHub = new Vue()
然后在组件中,可以使用 $emit, $on, $off 分别来分发、监听、取消监听事件。
1、WXML (WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。内部主要是微信自己定义的一套组件。与html差不多。
2、WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式,与css差不多
3、js 逻辑处理,网络请求
4、json 小程序设置,如页面注册,页面标题及tabBar。
1、给HTML元素添加data-*属性来传递我们需要的值,然后通过e.currentTarget.dataset或onload的param参数获取。但data-名称不能有大写字母和不可以存放对象
2、设置id 的方法标识来传值通过e.currentTarget.id获取设置的id的值,然后通过设置全局对象的方式来传递数值
3、在navigator中添加参数传值(?传的值的名称=所传的值在onLoad(option)用option来接收并获取)
1、提高页面加载速度
2、用户行为预测
3、减少默认data的大小
都各有各的好处,都有又缺点。
小程序的优点:
基于微信平台开发,享受微信本身自带的流量,这个是最大的优势
无需安装,只要打开微信就能用,不占用用户手机内存,体验好
开发周期短,一般最多一个月可以上线完成
开发所需的资金少,所需资金是开发原生APP一半不到
小程序名称是唯一性的,在微信的搜索里权重很高
容易上手,只要之前有HTML+CSS+JS基础知识,写小程序基本上没有大问题;当然如果了解ES6+CSS3则完全可以编写出即精简又动感的小程序;
基本上不需要考虑兼容性问题,只要微信可以正常运行的机器,就可以运行小程序;
发布、审核高效,基本上上午发布审核,下午就审核通过,升级简单,而且支持灰度发布;
开发文档比较完善,开发社区比较活跃;
最近刚开放的牛x功能,新增webview组件,可以展示网页啦,这个比较爽;
支持插件式开发,一些基本功能可以开发成插件,供多个小程序调用;
缺点:
1.局限性很强,(比如页面大小不能超过1M。不能打开超过5个层级的页面。样式单一。小程序的部分组件已经是成型的了,样式不可以修改。例如:幻灯片、导航。)只能依赖于微信依托于微信,无法开发后台管理功能。
2.不利于推广推广面窄,不能分享朋友圈,只能通过分享给朋友,附近小程序推广。其中附近小程序也受到微信的限制
3.后台调试麻烦,因为API接口必须https请求,且公网地址,也就是说后台代码必须发布到远程服务器上;当然我们可以修改host进行dns映射把远程服务器转到本地,或者开启tomcat远程调试;不管怎么说终归调试比较麻烦。
4.前台测试有诸多坑,最头疼莫过于模拟器与真机显示不一致
5.js引用只能使用绝对路径,很蛋疼;基于安全性及MINA框架实现原理,小程序中对js使用做了很多限制,不能使用:new Function,eval,Generator,不能操作cookie,不能操作DOM;
原生App优点:
1、原生的响应速度快
2、对于有无网络操作时,譬如离线操作基本选用原生开发
3、需要调用系统硬件的功能(摄像头、方向传感器、重力传感器、拨号、GPS、语音、短信、蓝牙等功能)
4、在无网络或者若网的情况下体验好。
缺点:
开发周期长,开发成本高
需要下载
(授权,微信登录获取code,微信登录,获取 iv , encryptedData 传到服务器后台,如果没有注册,需要注册。)
小程序支付如何实现?
我们做要简单,其实我更认为是小程序只有1M,更多的东西给后台吧
1、小程序注册,要以公司的以身份去注册一个小程序,才有微信支付权限;
2、绑定商户号。
3、在小程序填写合法域
4.调用wx.login()获取appid
5.调用
wx.requestPayment(
{
'timeStamp': '',//时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间
'nonceStr': '',//随机字符串,长度为32个字符以下。
'package': '',//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
'signType': 'MD5',//签名类型,默认为MD5,支持HMAC-SHA256和MD5。注意此处需与统一下单的签名类型一致
'paySign': '',//签名,具体签名方案参见微信公众号支付帮助文档;
'success':function(res){},//成功回调
'fail':function(res){},//失败
'complete':function(res){}//接口调用结束的回调函数(调用成功、失败都会执行)
})
客服功能,录音,视频,音频,地图,定位,拍照,动画,canvas
小程序的优点
小程序的缺点
①运行环境不同(小程序在微信运行,h5在浏览器运行);
②开发成本不同(h5需要兼容不同的浏览器);
③获取系统权限不同(系统级权限可以和小程序无缝衔接);
④应用在生产环境的运行流畅度(h5需不断对项目优化来提高用户体验);
首先,我们先看一下在vue-router和react-router中的用法本质
Vue-Router
React-Router
vue适合webapp,适合做用户交互多,各种动态效果变化丰富的应用。特别是PC、手机的网页版,商城等页面。
原因:vue实现逻辑复杂的功能比较简单。
react适合oa系统,适合大批量的数据展示、适合做大型应用。特别适合公司的后台管理系统。
原因:react对那种比较复杂的交互,实现起来比较麻烦,没有vue方便。同时react的渲染原理是渲染整个组件树,所以,一方面是费性能,而且代码写起来逻辑复杂。但是react对批量数据操作很厉害。
总而言之,项目要求比较高的适合使用react,因为react的社区更活跃一些,尤其是各种UI框架比较稳定、系统,可以信赖。Vue的社区也很活跃,但相对而言各种组件五花八门,大多数不够完善,缺乏系统性和迭代性,对于项目的后期维护和新手入手都不太友好。
从应用上来看,react打出来的包会大一些,相对来说,vue的包小一些,如果项目场景对加载速度由要求,建议使用vue。
挂载
constructor():组件的初始化
componentWillMount:组件将要挂载时促发
render()渲染
componentDidMount:组件第一次挂载完成时触发
更新
shouldComponentDidMount:是否需要更新数据,返回false则不更新
componentWillUpdate:将要更新数据触发
componentDidUpdate:组件更新完成触发
卸载
componentWillUnmount:组件销毁的时候触发
16.3版本后新增:getDerivedStateFrinOrios前面要加上static保留字,声明为静态方法,不然会被react忽略掉,不常用,componentWillMount,componentWillUpdate弃用
区别:
React基于Virtual DOM实现了一个SyntheticEvent层(合成事件层),定义的事件处理器会接收到一个合成事件对象的实例,它符合W3C标准,且与原生的浏览器事件拥有同样的接口,支持冒泡机制,所有的事件都自动绑定在最外层上。
在React底层,主要对合成事件做了两件事:
高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。
(1)哪些方法会触发 react 重新渲染?
setState 是 React 中最常用的命令,通常情况下,执行 setState 会触发 render。但是这里有个点值得关注,执行 setState 的时候不一定会重新渲染。当 setState 传入 null 时,并不会触发 render。
(2)重新渲染 render 会做些什么?
组件状态的改变可以因为props的改变,或者直接通过setState方法改变。组件获得新的状态,然后React决定是否应该重新渲染组件。只要组件的state发生变化,React就会对组件进行重新渲染。这是因为React中的shouldComponentUpdate方法默认返回true,这就是导致每次更新都重新渲染的原因。
(1)React中setState后发生了什么
在代码中调用setState函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个UI界面。
(2)setState 是同步还是异步的
假如所有setState是同步的,意味着每执行一次setState时(有可能一个同步代码中,多次setState),都重新vnode diff + dom修改,这对性能来说是极为不好的。如果是异步,则可以把一个同步代码中的多个setState合并成一次组件更新。所以默认是异步的,但是在一些情况下是同步的。
setState 的第二个参数是一个可选的回调函数。这个回调函数将在组件重新渲染后执行。等价于在 componentDidUpdate 生命周期内执行。通常建议使用 componentDidUpdate 来代替此方式。
this.state通常是用来初始化state的,this.setState是用来修改state值的。如果初始化了state之后再使用this.state,之前的state会被覆盖掉,如果使用this.setState,只会替换掉相应的state值。所以,如果想要修改state的值,就需要使用setState,而不能直接修改state,直接修改state之后页面是不会更新的。
React 通常将组件生命周期分为三个阶段:
挂载阶段组件被创建,然后组件实例插入到 DOM 中,完成组件的第一次渲染,该过程只会发生一次,在此阶段会依次调用以下这些方法:
当组件的 props 改变了,或组件内部调用了 setState/forceUpdate,会触发更新重新渲染,这个过程可能会发生多次。这个阶段会依次调用下面这些方法:
卸载阶段只有一个生命周期函数,componentWillUnmount() 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作:
这个生命周期在一个组件被卸载和销毁之前被调用,因此你不应该再这个方法中使用 setState,因为组件一旦被卸载,就不会再装载,也就不会重新渲染。
componentDidCatch(error, info),此生命周期在后代组件抛出错误后被调用。 它接收两个参数∶
react的父级组件的render函数重新渲染会引起子组件的render方法的重新渲染。但是,有的时候子组件的接受父组件的数据没有变动。子组件render的执行会影响性能,这时就可以使用shouldComponentUpdate来解决这个问题。
客户端路由实现的思想:
基于 hash 的路由:通过监听hashchange事件,感知 hash 的变化
基于 H5 history 路由:
react-router 实现的思想:
(1)React中setState后发生了什么
在代码中调用setState函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个UI界面。
(2)setState 是同步还是异步的
假如所有setState是同步的,意味着每执行一次setState时(有可能一个同步代码中,多次setState),都重新vnode diff + dom修改,这对性能来说是极为不好的。如果是异步,则可以把一个同步代码中的多个setState合并成一次组件更新。所以默认是异步的,但是在一些情况下是同步的。
setState 的第二个参数是一个可选的回调函数。这个回调函数将在组件重新渲染后执行。等价于在 componentDidUpdate 生命周期内执行。通常建议使用 componentDidUpdate 来代替此方式。
this.state通常是用来初始化state的,this.setState是用来修改state值的。如果初始化了state之后再使用this.state,之前的state会被覆盖掉,如果使用this.setState,只会替换掉相应的state值。所以,如果想要修改state的值,就需要使用setState,而不能直接修改state,直接修改state之后页面是不会更新的。
React 通常将组件生命周期分为三个阶段:
挂载阶段组件被创建,然后组件实例插入到 DOM 中,完成组件的第一次渲染,该过程只会发生一次,在此阶段会依次调用以下这些方法:
当组件的 props 改变了,或组件内部调用了 setState/forceUpdate,会触发更新重新渲染,这个过程可能会发生多次。这个阶段会依次调用下面这些方法:
卸载阶段只有一个生命周期函数,componentWillUnmount() 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作:
这个生命周期在一个组件被卸载和销毁之前被调用,因此你不应该再这个方法中使用 setState,因为组件一旦被卸载,就不会再装载,也就不会重新渲染。
componentDidCatch(error, info),此生命周期在后代组件抛出错误后被调用。 它接收两个参数∶
react的父级组件的render函数重新渲染会引起子组件的render方法的重新渲染。但是,有的时候子组件的接受父组件的数据没有变动。子组件render的执行会影响性能,这时就可以使用shouldComponentUpdate来解决这个问题。
客户端路由实现的思想:
基于 hash 的路由:通过监听hashchange事件,感知 hash 的变化
基于 H5 history 路由:
react-router 实现的思想: