节流和防抖
节流:短时间内频繁触发事件时,第一次事件会执行,执行完毕有一个冷却时间,过了这个时间才可以再次触发,适用于监听窗口滚动事件,即使用户不断拖动滚动条,也能在某个时间间隔之后给出反馈。
防抖:短时间内频繁触发事件时,只有最后一次触发的事件会执行,适用于内容搜索,一定时间后才去匹配搜索结果
undefined和null的区别
undefined表示“缺少值”,转为数值时为NaN
null表示"没有对象",即该处不应该有值,转为数值时为0,典型用法是:(1) 作为函数的参数,表示该函数的参数不是对象。(2) 作为对象原型链的终点。
ajax原理
1、实例化一个XHR对象,它是一种支持异步请求的技术,是ajax的核心
2、创建请求(open),参数一:请求方式,二:url,三:同步异步
3、设置响应请求状态变化的函数(onreadystatechange)然后在函数中判断,如果xhr.readyState等于4,表示请求成功已经接收到响应内容,并解析完成了;
然后继续判断如果xhr.status等于200,表示成功处理请求。然后就可以获取返回的数据了xhr.responseText
4、发送请求,send()如果是post请求,可以跟参数,不跟的话填null;如果是get请求,参数写在创建请求时的url中
ajax请求方式get和post的区别
1、GET请求会被浏览器主动缓存,而POST不会,除非手动设置
2、GET请求参数会被完整的保留在浏览器历史记录里,而POST中的参数不会被保留,并且GET的参数会暴露在url上
3、get传递的数据是有限制的
4、get传递数据是在url中,post是在send中
ajax状态码
一、readyState【4最常用】
●0 - (未初始化) 还没有调用send()方法
●1 - (载入) 已调用send(方法,正在发送请求
●2 - (载入完成) send()方法执行完成,已经接收到全部响应内容
●3 - (交互) 正在解析响应内容
●4 - (完成) 响应内容解析完成,可以在客户端调用了
二、status【200最常用】
●2xx - 表示成功处理请求。如200
●3xx - 需要重定向,浏览器直接跳转,如304:服务器已经执行了GET请求,但文件未变化,和上次的一样,就会返回304
●4xx - 客户端请求错误,如404
●5xx - 服务器端错误
如何判断数据类型?
值类型用typeof,引用类型用instanceof
回流及重绘
回流:就是对整个或者部分页面重新构建渲染
触发因素一般有:
1、页面首次渲染的时候
2、浏览器窗口大小发生改变的时候
3、元素尺寸或位置发生改变的时候
4、元素字体大小变化的时候
5、激活css伪类的时候(如:hover)
重绘:就是对元素重新绘制
触发因素:
1、修改字体颜色,背景颜色
2、修改outline、visibility
回流一定伴随着重绘,而重绘不一定伴随回流
bind、apply和call
都是用于改变函数体内this的指向,但是bind与apply和call的最大的区别是:bind不会立即调用,而是返回一个新函数,称为绑定函数,其内的this指向为创建它时传入bind的第一个参数,而传入bind的第二个及以后的参数作为原函数的参数来调用原函数。
BFC
就是一块独立渲染的区域,不会影响外界元素,形成BFC的条件是这块区域脱离文档流,比如绝对定位固定定位,浮动、display的值是inline-block,可以避免margin重叠、清除浮动
阻止冒泡:e.stopPropagation()
取消默认事件:e.prev entDefault()
js实现继承
1、原型和原型链
2、es6新增的class类的继承,通过extends(is thens)
ES6
新增了一种基础数据类型 Symbol (先bou)。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。
let与const
1、有块级作用域的概念,是在花括号中的{},比如if,for,但对象{}不是块级作用域
2、不会预解析提升
3、都是不能重复声明的,let可以重新赋值,const不行
4、const常量声明时必须赋值
5、const是引用类型的时候,里面的数据是可以修改的,通过Object.freeze( )可以冻结数据
解构赋值
数组是有序的,根据位置取想要获取的元素,不获取的空着
对象是无序的,根据属性名获取
字符串也是有序的,空格也算
字符串新增方法
1、模板字符串: 使用 ` ` 包起来的字符串,绑定数据用${ }
2、 .includes(x) 判断 某字符串是否存在
3、for-of循环字符串
正则新增修饰符U、Y
1、u指Unicode的意思
console.log( /^\ud83d/u.test('\ud83d\udc36'))
加了u修饰符,\ud83d\udc36会被当做1个字符,所以返回的是false
2、y指粘连修饰符
符合条件会一直匹配,有一处匹配不上就会终止
函数新增
1、默认值:函数的形参可以设置默认值,并且默认值可以与前一个参数进行运算,但不能和自身或后一个参数进行运算
2、箭头函数
数值新增
Number.isNaN()--判断是不是非数值 不是数值返回true 是数值返回false
对象新增
1、当属性名与属性值相同时,可省略属性值
2、可以将变量用中括号[ ]包裹,作为对象的属性名,也可以是模版字符串。
3、修改对象的原型对象 :Object.setPrototypeOf( 要修改的对象,想作为原型的对象)
数组新增
1、es6新增的Set:new Set(arr)会自动检测去重
2、splice:双重for循环,第二次的循环j= i+1,然后判断i == j 的时候,删除重复的元素 splic(j,1)
3、sort(傻特):数组排序,arr.sort ( ( a , b ) => { return a - b } ) 升序 {return b - a } 降序
4、Array.form(object,回调函数) 将类数组对象转换为数组
5、Array.of ( ) 将传入的参数数据合并为一个数组
Sass
1、声明变量以$开头,并有局部变量的概念
2、@import 引入sass文件
3、插值:#{变量名}
4、sass的数组是用括号包含,索引从1开始
调用数组的方式:nth(变量名,索引)
取对应数据索引:index(变量名,数据值)
5、加减乘除
加减法直接相加减
乘除法需要用()包住,只需一个带单位就行,如果是用变量进行乘除不需要加()
6、mixin混合宏
声明:@mixin 名称 {xxxx}
引用:@include 名称
mixin 名称(){}还可以带参数,形参前要加$,不会和变量名冲突
7、继承
@extend 被继承的名字,直接写在需要继承的{}中
还可以链式继承,一层套一层,上面有的样式都会有
8、嵌套
和vue案例中学的Styles一样,按元素结构顺序写样式,低级的往后空一格
9、还有@if、@for、@while、@each条件控制
10、还有很多内置函数(数值、数组、字符串、map)
访问网站的过程
(1)输入网站域名;
(2)通过DNS解析找到目标服务器的IP地址;
(3)然后浏览器和服务器通过TCP三次握手建立通信,浏览器向服务器发送请求
(4)服务器将响应数据发送到用户的浏览器, 进行四次挥手,确认没有数据需要发送后结束通信
(5) 浏览器处理响应数据,完成网页的渲染呈现
浏览器渲染过程
1、浏览器将HTML文档解析成DOM树。
2、解析CSS文件,形成cssom树形的数据结构
3、将DOM和CSSOM合并为渲染树(Rendering tree),代表一系列将被渲染的对象。
4、布局渲染树,计算渲染树中的元素的尺寸、位置,然后绘制页面的像素信息
5、将渲染树的各个节点绘制到屏幕上(painting)
cors原理
cors一般后端设置,允许访问的域名、允许的行为、允许的头部字段、有效期
jsonp原理
src实际上是get请求,没有同源策略的限制,可以通过script的src请求到文件;然后定义callback回调函数,请求数据成功后执行
HTTP
HTTP是从万维网传送超文本到本地浏览器的传送协议,是基于TCP连接基础上的,TCP就是单纯建立连接,不涉及我们需要请求的实际数据,http是用来收发数据的经过TCP三次握手建立连接后,浏览器向服务器发送一个请求,服务器响应请求返回数据,浏览器拿到数据,TCP四次挥手确认没有数据需要发送了,断开连接
HTTP报文
它是HTTP应用程序之间发送的数据块。
报文结构分为请求头、请求行、空行、请求实体
HTTP和HTTPS区别
HTTP协议以明文方式发送内容,不提供任何方式的数据加密,所以HTTP协议不适合传输一些敏感信息,比如:银行卡号、密码等支付信息。
HTTPS在HTTP的基础上加入了SSL/TLS协议,SSL/TLS依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
HTTP各版本区别
HTTP 1.0需要使用keep-alive参数来告知服务器端要建立一个长连接
HTTP1.1默认支持长连接。
HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求
三次握手
作用是提供可靠的字节流服务,为了准确无误地将数据送达目的地
通俗的说法
1)张三 :嘿,李四,是我,听到了吗?
2)李四 :我听到了,你能听到我的吗?
3)张三 :好的,我们互相都能听到对方的话,我们的通信可以开始了。
四次挥手
确认已经没有数据需要发送了
通俗的说法
1)张三 :我所有东西都说完了
2)李四:我已经全部听到了,但是等等我,我还没说完
3)李四 :好了,我已经说完了
4)张三 :好的,那我们的通信结束
闭包主要作用
一、保存for循环每次的i值。
二、可以在一个函数中,用自己另外定义的一个函数(具体操作)作为返回值return出去,相当于一个外部接口,然后外部根据这个接口进行操作。这样也是一个闭包,外部没办法直接操作这个函数;;比如函数中有个变量a=1,然后作为返回值的函数进行的操作是a++,外部调用这个函数就是返回a++ a = 2,而不能进行其他的操作了,私有变量。
cookies
Cookie是保存在客户端的纯文本文件,当我们使用自己的电脑通过浏览器进行访问网页的时候,服务器就会生成一个证书并返回给我的浏览器并写入我们的本地电脑。这个证书就是cookie。
在seesion出现之前,一般网站都是通过cookie保存请求的内容,服务器根据用户进行特定的内容展示。也就是说如果不使用cookie,我们将不能在浏览器中看到购物车的东西这就类似于浏览器的收藏夹,如果我们收藏了,下次我们再打开浏览器窗口就会看到我们收藏的东西。也就是说cookie保存了一个前后的状态
WebSocket
是 H5 开始提供的一种在单个 TCP (传输控制协议, 就是要对数据的传输进行一定的控制)连接上进行全双工通讯的协议。
应用于直播、聊天室
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,形成了一条快速通道。两者之间就直接可以数据互相传送。
Web Worker
就是为 JavaScript 创造多线程环境,将一些计算密集或高延迟的任务,分配给分线程运行。分线程是在后台运行的,和主线程互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,主线程(就会很流畅,不会被阻塞或拖慢。
Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。
Vue
非父子组件间传值
bus总线机制:
(1)给Vue的原型绑定bus属性,Vue.prototype.bus = new Vue()
(2)要传数据的组件上调用bus,this.bus.$emit()
(3)要接数据的组件上监听,this.bus.$on()
Vuex状态管理模式
(1)安装好vuex后,创建一个仓库,Vuex.Store({ })
(2)里面有三块:state存放公用数据,actions放异步操作或批量同步操作,mutations放一个个对state的同步修改
(3)往state里面填充数据,调用里面的数据是this.$store.XX,需要修改数据的话是以下步骤:
a、通过dispatch方法向actions传递事件和数据
b、actions通过commit方法调用mutations,mutations里面放的是对state的同步修改
计算属性、计算方法、watch
计算属性computed:{ 属性名 :依赖的数据 },有缓存,当依赖的数据发生改变时才会执行
计算方法:方法定义在methods中,方法绑定在标签中{{方法名()}}无论依赖的数据是否改变都会执行一次
watch监听器:定义在watch中,监听数据的改变
如果一个数据需要经过复杂计算就用 computed
如果一个数据需要被监听并且对数据做一些操作就用 watch
computed:
当一个属性受多个属性影响的时候就需要用到computed
最典型的栗子: 购物车商品结算的时候
watch:
当一条数据影响多条数据的时候就需要用watch
栗子:搜索数据
MVC与MVVM
MVC即模型-视图-控制器。M和V指的意思和MVVM中的M和V意思一样。C即Controller指的是页面业务逻辑。使用MVC的目的就是将M和V的代码分离。MVC是单向通信。也就是View跟Model,必须通过Controller来承上启下。MVC和MVVM的区别并不是VM完全取代了C,只,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。也就是说MVVM实现的是业务逻辑组件的重用,
Vue中双向数据绑定是如何实现的?
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。
单页面应用和多页面应用区别及优缺点
单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。
多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新
单页面的优点:
用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小;前后端分离;页面效果会比较炫酷(比如切换页面内容时的专场动画)。
单页面缺点:
首屏加载慢:解决方法1、require组件实现路由懒加载;2、cdn;3、异步组件
不利于seo,由于浏览器爬取不会执行js,所以隐藏在js中的跳转也不会获取到,就搜索不到相关的子页面的内容
导航不可用,需要引入vue-router解决;初次加载时耗时多;
VUE的路由
根目录下router文件夹里的index.js文件就是路由的配置文件
<router-view></router-view>显示的是当前路由所对应的内容(一般只用写在根组件中就可以了,因为最终显示的只有这个根组件,单组件页面),如果没有这个标签,就不会显示对应组件的内容了
vue会从router下的js文件找到对应路径的对应组件,拿到组件让router-view标签显示出来,如果用keep-alive包裹可以缓存组件
跳转页面
编程式导航:每一个组件都有router实例属性,this.$router.push(路由)就能跳转页面
标签跳转:router-link,相当于a标签
keep-alive
是vue自带的属性,路由加载一次后 把路由的内容放到内存中 下一次再进这个路由的时候 不需要重新加载 把之前的拿出来显示就可以了
为什么使用key
需要使用key来给每个节点做一个唯一标识,可以正确的识别此节点,主要是为了高效的更新虚拟DOM。
生命周期函数
beforecreate(组件创建前) : 举个栗子:可以在这加个loading事件
created(组件创建完成,但DOM还未渲染) :在这结束loading,还做一些初始化,实现函数自执行
mounted (模板渲染完成挂载后): 在这发起后端请求,拿回数据,配合路由钩子做一些事情
updated(数据更新完成后)
项目中遇到的难点
1、组件 + v-show:
当一个页面内有多个地方使用同一个组件,并通过v-show控制组件的显示隐藏时会有异常,例如我通过eventbus触发了一个事件,这个组件进行了监听,触发一次事件,会监听执行了多次,因为v-show即使为false时,也是存在于DOM中,只是隐藏了起来,所以就会有多次触发事件的性能问题,所以需要通过v-if来控制组件的使用与否
2、聊天记录上下文分页功能
模拟了聊天软件,进入聊天窗口时,默认定位在底部,越往上,数据越旧,当滑动到顶部时,请求下一页数据,当前位置保持不变,难点在于如何请求到新数据,数据增加了之后滚到位置不变,可以通过添加了新数据后的元素高度,减去添加新数据前的位置,得出本次新添加数据的高度,然后把滚动位置设置到这个高度就可以了