JavaScript共有八种数据类型,分别是 Number、Boolean、String、Undefined、Null、Object、Symbol、BigInt。
NaN是非数字,但是用 typeof
检测是number类型。
typeof
判断是否是number类型并且判断是否满足isNaNNaN
是唯一一个不等于任何自身的特点 n !== nObject.is()
方法(判断两个值是否相等)null
和 undefined
的区别相同点:隐式类型转换都是false 不同点:number(null) 是0,number(undefined)是NaN
null表示值被定义了,但是是空值 undefined表示未被定义
闭包可以简单被理解成:定义在一个函数内部的函数。其中一个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
特点:
优点:
缺点:
事件委托就是利用事件冒泡,只定制一个事件处理程序,就可以管理某一类型的所有事件。
事件委托,称为事件代理,是JS中很常用的绑定事件的方法。事件委托就是把原本需要绑定在子元素上面的事件委托给父元素,让父元素担当事件监听的职务,原理是DOM元素的事件冒泡。
一个事件触发后,会在子元素和父元素之间传播,这种传播分为三个阶段:
相同点:
都是在浏览器(客户端)内存储,存储方式为字符串
不同点:
1、生命周期:
1)cookie如果不设置有效期,就是临时存储(存储在内存中),如果设置了有效期,到期之后会消失(存储在硬盘里)
2)localStorage是永久存储,关闭浏览器数据也不会消失,除非手动删除
3)sessionStorage是临时存储,仅在当前回话下有效。引入了一个窗口的概念,数据仅在当前窗口下生效,关闭当前窗口的话数据会被删除
2、cookie数据在每次网络请求的时候都会被发送给服务端,localStorage和sessionStorage则不会
3、cookie大小限制为4kb,storage则为5M
4、storage比cookie的安全性更高一些
什么是原型:
任何对象实例都有一个原型,也叫原型对象。这个原型对象由对象的内置属性_proto_指向它的构造函数的prototype指向的对象,即任何对象都是由一个构造函数创建的,但是不是每一个对象都有prototype,只有方法才有prototype。
什么是原型链
原型链基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法,我们知道,每个构造函数都有一个原型对象,每个原型对象都有一个指向构造函数的指针,而实例又包涵一个指向原型对象的内部指针。
原型链的核心就是依赖对象的_proto_的指向,当自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至到Object时,就没有_proto_指向了。
因为_proto_实质找的是prototype,所以我们只要找这个链条上的构造函数的prototype,其中Object.prototype是没有_proto_属性的,它==null
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含指向原型对象内部的指针。
原型继承是 js 的一种继承方式,原型链作为实现继承的主要方法,其基本思路是利用原型让一个引用类型继承另一个引用类型的属性和方法,
原型继承:利用原型中的成员可以被和其相关的对象共享这一特性,可以实现继承,这种实现继承的方式,就叫做原型继承.
什么是Promise?
我们都知道,Promise是承诺的意思,承诺它过一段时间会给你一个结果
Promise是一种解决异步编程的方案,相比回调函数和事件更合理、更强大
从语法上讲,Promise是一个对象,从它可以获取异步操作的消息
Promise的状态
状态一旦改变,就不会再变
Promise的特点
Promise的缺点
async就是Generation和Promise的语法糖,async就是将Generator的*转换成async,将yield转换成await
函数前必须加一个async,异步操作方法前加一个await关键字,意思就是等一下,执行完了再继续走。注意:await 只能在 async 函数中运行,否则会报错
Promise 如果返回的是一个错误的结果,如果没有做异常处理,就会报错,所以用 try..catch 捕获一下异常就可以了
当发送一个URL请求时,不管这个URL是web页面URl还是Web页面上每个资源的URL,浏览器都会开启一个线程来处理这个请求,同时在远程DNS服务器上启动一个DNS查询。这能使得浏览器得到请求对应的IP地址。
浏览器与远程web服务器通过TCP三次握手协商来建立一个TCP/IP连接,该握手包括一个同步报文,一个同步-应答报文和一个应答报文。这三个报文在浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,然后服务器相应并接受客户端的请求,最后由客户端发出该请求已被接受的报文。
一旦TCP/IP连接建立,浏览器会通过该连接向远程服务器发送HTTP的GET请求。远程服务器找到资源并使用HTTP相应返回该资源
我们常说GET请求参数的大小存在限制,而POST请求的参数大小是无限制的。
实际上HTTP协议从未规定GET/POST的请求长度是多少,对GET请求参数的限制是来源与浏览器或WEB服务器,浏览器或WEB服务器限制了url的长度。为了明确这个概念,我们必须强调下面几点。
HTML
与 JS
交互是通过事件驱动来实现的,例如鼠标点击事件 onclick
、页面滚动事件 onscroll
等等。可以向文档或者文档中的元素添加事件监听来订阅事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下 ”事件流“ 的概念。
什么是事件流
事件流描述的是从页面中接收事件的顺序,DOM2
级事件流包括下面几个阶段:
事件捕获阶段处于目标阶段事件冒泡阶段
addEventListener:addEventListener
是 DOM2
级事件新增的指定事件处理程序的操作,这个方法接收 3
个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是 true
,表示在捕获阶段调用事件处理程序;如果是 false
,表示在冒泡阶段调用事件处理程序。IE只支持事件冒泡。
事件委托是指,不在事件的发生地(直接DOM)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素DOM的类型,来做出不同的相应。
举例:最经典的就是ul和li标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在li标签上直接添加,而是在父元素ul上面添加
好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。
new操作符新建了一个空对象,这个对象原型指向构造函数的prototype,执行构造函数后返回这个对象。
this
指针的函数(bind、apply、call的区别)通过 apply
和 call
改变this指向,他们两个函数的第一个参数都是一样的表示要改变指向的那个对象,第二个参数:apply
是数组,而call
则是arg1,arg2...这种形式。通过bind改变this作用域会返回一个新的函数,这个函数不会马上执行。
必要性: 由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JS程序每次创建字符串、数组或者对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则JS的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。JS的解释器可以检测到何时程序不再使用一个对象了,当它确定了一个对象是无用的时候,它就知道不再需要这个对象,可以把它所占用的内存释放掉了。
例如:
var a = "hello word";
var b = "hello wrod";
var a = b;
复制代码
这时,会释放掉"hello word",释放内存以便再引用垃圾回收的方法:标记清除、计数引用。
标记清除:
这时最常见的垃圾回收方式,当变量进入环境时,就标记这个变量为”进入环境“,从逻辑上讲,永远不能释放进入环境的变量所占用的内存,只要执行流程进入相应的环境,就可能用到他们。当离开环境时,就标记为离开环境。垃圾回收器在运行的时候会给存储在内存中的变量都加上标记,然后去掉环境变量中的变量,以及被环境变量中的变量所引用的变量(条件性去除标记),删除所有被标记的变量,删除的变量无法在环境变量中被访问所以会被删除,最后垃圾回收器完成了内存的清除工作,并回收他们所占用的内存。
引用计数法:
另一种不太常见的方法就是引用计数法,引用计数法的意思就是每个值被引用的次数,当声明了一个变量,并用一个引用类型的值赋值给变量,则这个值的引用次数为 1
,相反的,如果包含了对这个值引用的变量又取得了另外一个值,则原先的引用值引用次数就减 1
,当这个值的引用次数为 0
时,说明没有办法再访问这个值了,因此就把所占的内存给回收进来,这样垃圾收集器再次运行的时候,就会释放引用次数为 0
的这些值。
用引用计数法会存在内存泄漏:
function problem {
var objA = new Object();
var objB = new Object();
objA.a = objB;
objB.b = objA;
}
复制代码
在这个栗子里面,objA和objB通过各自的属性互相引用,这样的话,两个对象的引用次数都为 2
,在采用引用计数的策略中,由于函数执行之后,这两个对象都离开了作用域,函数执行完成后,因为计数不为 0
,这样的相互引用如果大量存在就会导致内存泄漏。
特别是在DOM对象中,也容易存在这种问题,
var element = document.getElementById('');
var myObj = new Object();
myObj.element = element;
element.a = myObj;
复制代码
这样就不会有垃圾回收的过程。
在ES5里面可以通过Object.defineProperty来实现已有属性的监听
Object.defineProperty(user, 'name', {
set: function(key, value) {
}
})
复制代码
缺点:如果id不在user对象中,则不能监听id的变化。
在ES6中可以通过Proxy来实现
var user = new Proxy({}, {
set: function(target, key, value, receiver) {
}
});
复制代码
这样即使有属性在Proxy中不存在,通过user.id来定义也同样可以这样监听这个属性的变化
原理:通过apply或者call方法来实现
(1) 初始版本
Function.prototype.bind = function(obj, arg) {
var arg = Array.prototype.slice.call(arguments, 1);
var context = this;
return function(newArg) {
arg = arg.concat(Array.prototype.slice.call(newArg));
return context.apply(obj, arg);
}
}
复制代码
(2) 考虑到原型链(因为在new一个bind生成的新函数的时候,必须的条件是要继承原函数的原型)
Function.prototype.bind = function(obj, arg) {
var arg = Array.prototype.slice.call(arguments, 1);
var content = this;
var bound = function(newArg) {
arg = arg.concat(Array.prototype.slice.call(newArg));
return context.apply(obj, arg);
}
var F = function() {}
F.prototype = context.prototype;
bound.prototype = new F();
return bound;
}
前端部分知识:
网页生成的过程:
重排:当DOM的变化影响了元素的几何信息(DOM对象的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。
触发条件:
2. 元素尺寸改变——边距、填充、边框、宽度和高度
重绘:当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。
触发条件:改变元素的color、background、box-shadow等属性
header nav main article section aside footer
语义化的优点如下:
多个带async属性的标签,不能保证加载的顺序;多个带defer属性的标签,按照加载顺序执行;
async属性,表示后续文档的加载和执行与js脚本的加载和执行是并行进行的,即异步执行;defer属性,加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),js脚本需要等到文档所有元素解析完成之后才执行,DOMContentLoaded事件触发执行之前。
盒模型都是由四个部分组成的,分别是margin、border、padding和content。
1.flex-direction属性决定主轴的方向(即项目的排列方向)。
2. flex-wrap属性定义,如果一条轴线排不下,如何换行。
3.flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
4.justify-content属性定义了项目在主轴上的对齐方式。
5.align-items属性定义项目在交叉轴上如何对齐。
6.align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
transition是过度属性,强调过度,它的实现需要触发一个事件(比如鼠标移动上去,焦点,点击等)才执行动画。它类似于flash的补间动画,设置一个开始关键帧,一个结束关键帧。
animation是动画属性,它的实现不需要触发事件,设定好时间之后可以自己执行,且可以循环一个动画。它也类似于flash的补间动画,但是它可以设置多个关键帧(用@keyframe定义)完成动画。
新增各种CSS选择器 (: not(.input):所有 class 不是“input”的节点)
1.圆角 (border-radius:8px)
2.多列布局 (multi-column layout)
3.阴影和反射 (Shadoweflect)
4.文字特效 (text-shadow)
5.文字渲染 (Text-decoration)
6.线性渐变 (gradient)
7.旋转 (transform) 增加了旋转,缩放,定位,倾斜,动画,多背景
1.使用display: none; 隐藏dom;
2.使用visibility: hidden; 隐藏dom;
3.使用z-index: -888; 把元素的层级调为负数,然后其他元素覆盖即可;
4.使用opacity: 0; 把元素的透明度调为0,也可以达到隐藏;
5.使用固定定位position: absolute; 把元素定位到看不见的区域;
6.使用transform: scale(0, 0); 把元素缩放为0,也可以实现元素隐藏。
1.利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过translate来调整元素的中心点到页面的中心
2.利用绝对定位,设置四个方向的值都为0,并将margin设置为auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中。该方法适用于盒子有宽高的情况
3.利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过margin负值来调整元素的中心点到页面的中心。该方法适用于盒子宽高已知的情况
4.使用flex布局,通过align-items:center和justify-content:center设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中
基本类型:
Number、String、Boolean、Null、undefined、Symbol
复杂类型:
Object、Array、Function
typeof
instanceof
Object.prototype.toString.call()
作用域负责收集和维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。(全局作用域、函数作用域、块级作用域)。 作用域链就是从当前作用域开始一层一层向上寻找某个变量,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是作用域链。
原型:
原型链: 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念
特点: JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。
闭包是指有权访问另一个函数作用域中的变量的函数 ——《JavaScript高级程序设计》
当函数可以记住并访问所在的词法作用域时,就产生了闭包,
即使函数是在当前词法作用域之外执行 ——《你不知道的JavaScript》
闭包形成的条件:
闭包用途:
闭包缺点:会导致函数的变量一直保存在内存中,过多的闭包可能会导致内存泄漏
JS是单线程的,为了防止一个函数执行时间过长阻塞后面的代码,所以会先将同步代码压入执行栈中,依次执行,将异步代码推入异步队列,异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。微任务队列的代表就是,Promise.then,MutationObserver,宏任务的话就是setImmediate setTimeout setInterval
prototype
对象。this
指向这个对象,执行构造函数的代码(为这个新对象添加属性)https://es6.ruanyifeng.com/#docs/letes6.ruanyifeng.com/#docs/let
var tmp = 123;
if (true) {
// 存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,
所以在let声明变量前,对tmp赋值会报错
tmp = 'abc'; // ReferenceError
let tmp;
}
map有返回值 forEach 没有返回值
豆豆:JS常用数组方法7 赞同 · 0 评论文章
1.新增symbol类型 表示独一无二的值,用来定义独一无二的对象属性名;
2.const/let 都是用来声明变量,不可重复声明,具有块级作用域。存在暂时性死区,也就是不存在变量提升。(const一般用于声明常量);
3.变量的解构赋值(包含数组、对象、字符串、数字及布尔值,函数参数),剩余运算符(...rest);
4.模板字符串(${data});
5.扩展运算符(数组、对象);
6.箭头函数;
7.Set和Map数据结构;
8.Proxy/Reflect;
9.Promise;
10.async函数;
create阶段:vue实例被创建 beforeCreate: 创建前,此时data和methods中的数据都还没有初始化 created: 创建完毕,data中有值,未挂载
mount阶段: vue实例被挂载到真实DOM节点 beforeMount:可以发起服务端请求,去数据 mounted: 此时可以操作Dom
update阶段:当vue实例里面的data数据变化时,触发组件的重新渲染 beforeUpdateupdated
destroy阶段:vue实例被销毁 beforeDestroy:实例被销毁前,此时可以手动销毁一些方法 destroyed
父子组件通讯 props $emit parent、children Ref
兄弟之间通讯 event bus
跨组件通讯 $attrs、$listeners Provide、inject
vuex
watch 属性监听 是一个对象,键是需要观察的属性,值是对应回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,监听属性的变化,需要在数据变化时执行异步或开销较大的操作时使用
computed 计算属性 属性的结果会被缓存,当computed中的函数所依赖的属性没有发生改变的时候,那么调用当前函数的时候结果会从缓存中读取。除非依赖的响应式属性变化时才会重新计算,主要当做属性来使用 computed中的函数必须用return返回最终的结果 computed更高效,优先使用。data 不改变,computed 不更新。
使用场景computed:当一个属性受多个属性影响的时候使用,例:购物车商品结算功能 watch:当一条数据影响多条数据的时候使用,例:搜索数据
v-for的优先级是高于v-if的,如果两者同时出现的话,那每次循环都会执行v-if,会很浪费性能,我们正确的做法应该是再v-for的外面新增一个模板标签template
,在template上使用v-if
2. Vue在更新DOM时是异步执行的。只要侦听到数据变化,Vue将开启1个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个watcher被多次触发,只会被推入到队列中-次。这种在缓冲时去除重复数据对于避免不必要的计算和DOM操作是非常重要的。nextTick方法会在队列中加入一个回调函数,确保该函数在前面的dom操作完成后才调用;
3. 比如,我在干什么的时候就会使用nextTick,传一个回调函数进去,在里面执行dom操作即可;
4. 我也有简单了解nextTick实现,它会在callbacks里面加入我们传入的函数,然后用timerFunc异步方式调用它们,首选的异步方式会是Promise。这让我明白了为什么可以在nextTick中看到dom操作结果。
作用:实现组件缓存
钩子函数: ”activated “组件渲染后调用 ”deactivated“组件销毁后调用
原理:Vue.js内部将DOM节点抽象成了一个个的VNode节点,keep-alive组件的缓存也是基于VNode节点的而不是直接存储DOM结构。它将满足条件(pruneCache与pruneCache)的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象中取出并渲染。
配置属性: include 字符串或正则表达式。只有名称匹配的组件会被缓存 exclude 字符串或正则表达式。任何名称匹配的组件都不会被缓存 max 数字、最多可以缓存多少组件实例
Vuex 是一个专为 Vue 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。
2. 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation, 这样使得我们可以方便地跟踪每一个状态的变化 Vuex主要包括以下几个核心模块:
3. Mutation:是唯一更改 store 中状态的方法,且必须是同步函数
4. Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作
5. Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中
1.id传参
//路由配置
{
path: '/orderDetail/:id',
name: 'orderdetail',
component: () => import('../components/orderDetail.vue'),
meta: { showTabbar: false}
}
this.$router.push({path:`/orderDetail/${this.id}`})
2.query传参
this.$router.push({path:`/orderDetail`,query:{id:this.id}})
3.pramas传参
this.$router.push({name:`orderdetail`,params:{id:this.id}})
1.普通插槽
2.具名插槽
3.作用域插槽
当一个Vue实例创建时,Vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher重新计算,从而致使它关联的组件得以更新。
属性监听:
defineProperty: 遍历对象,劫持对象的每一个属性; Proxy: 劫持整个对象,并返回一个代理对象;
对数组方法的支持:
defineProperty: push...等不能监听;Proxy: 可以监听;
兼容:
defineProperty(ES5)兼容性比Proxy(ES6)好。
2. 声明普通类型 ref
3. 声明复杂类型 reactive
4.watch 的用法
5. v-model 的用法
6. Vue3双向绑定原理
7. Vue3的生命周期
8. Vue3通讯
9. Vue3.2 setup 语法糖等
raw-loader:加载文件原始内容(utf-8)
file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件 (处理图片和字体)
source-map-loader:加载额外的 Source Map 文件,以方便断点调试
svg-inline-loader:将压缩后的 SVG 内容注入代码中
image-loader:加载并且压缩图片文件
json-loader 加载 JSON 文件(默认包含)
babel-loader:把 ES6 转换成 ES5
ts-loader: 将 TypeScript 转换成 JavaScript
awesome-typescript-loader:将 TypeScript 转换成 JavaScript,性能优于 ts-loader
sass-loader:将SCSS/SASS代码转换成CSS
css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS
postcss-loader:扩展 CSS 语法,使用下一代 CSS,可以配合 autoprefixer 插件自动补齐 CSS3 前缀
vue-loader:加载 Vue.js 单文件组件
define-plugin:定义环境变量 (Webpack4 之后指定 mode 会自动配置)
ignore-plugin:忽略部分文件
html-webpack-plugin:简化 HTML 文件创建 (依赖于 html-loader)
web-webpack-plugin:可方便地为单页应用输出 HTML,比 html-webpack-plugin 好用
uglifyjs-webpack-plugin:不支持 ES6 压缩 (Webpack4 以前)
terser-webpack-plugin: 支持压缩 ES6 (Webpack4)
webpack-parallel-uglify-plugin: 多进程执行代码压缩,提升构建速度
mini-css-extract-plugin: 分离样式文件,CSS 提取为独立文件,支持按需加载 (替代extract-text-webpack-plugin)
serviceworker-webpack-plugin:为网页应用增加离线缓存功能
clean-webpack-plugin: 目录清理
Loader 本质就是一个函数,在该函数中对接收到的内容进行转换,返回转换后的结果。 因为 Webpack 只认识 JavaScript,所以 Loader 就成了翻译官,对其他类型的资源进行转译的预处理工作。
Plugin 就是插件,基于事件流框架 Tapable,插件可以扩展 Webpack 的功能,在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
Loader 在 module.rules 中配置,作为模块的解析规则,类型为数组。每一项都是一个 Object,内部包含了 test(类型文件)、loader、options (参数)等属性。
Plugin 在 plugins 中单独配置,类型为数组,每一项是一个 Plugin 的实例,参数都通过构造函数传入
2. git add .
3. git commit -m
4. git push
5. git pull
6. git branch 查看本地分支
7. git branch -a 查看远程分支
8. git branch -d xxx 删除分支
9. git checkout xxx 切换分支
10. git checkout -b xxx 新建分支并且切换到改分支
11. git branch -m 旧分支名 新分支名 分支重命名
12. git status 查看修改的文件
13. git merge 合并分支
14. git checkout -b xxx origin/xxx 拉去远程分支
15. git log 查看提交记录
1.GET在浏览器回退不会再次请求,POST会再次提交请求
2.GET请求会被浏览器主动缓存,POST不会,要手动设置
3.GET请求参数会被完整保留在浏览器历史记录里,POST中的参数不会
4.GET请求在URL中传送的参数是有长度限制的,而POST没有限制
5.GET参数通过URL传递,POST放在Request body中
6.GET参数暴露在地址栏不安全,POST放在报文内部更安全
7.GET一般用于查询信息,POST一般用于提交某种信息进行某些修改操作
8.GET产生一个TCP数据包;POST产生两个TCP数据包
http: 是一个客户端和服务器端请求和应答的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的超文本传输协议。 https:是以安全为目标的 HTTP 通道,即 HTTP 下 加入 SSL 层进行加密。其作用是:建立一个信息安全通道,来确保数据的传输,确保网站的真实性。
1.`HTTP` 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
2.`HTTP` 是不安全的,而 HTTPS 是安全的
3.`HTTP` 标准端口是80 ,而 HTTPS 的标准端口是443
4.`在OSI` 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
5.`HTTP` 无法加密,而HTTPS 对传输的数据进行加密
6.`HTTP`无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书
2. 301永久重定向
3. 302临时重定向
4. 304资源缓存
5. 403服务器禁止访问
6. 404服务器资源未找到
7. 500 502服务器内部错误 504 服务器繁忙
浏览器的本地存储主要分为Cookie、localStorage和sessionStorage。
共同点: 都是保存在浏览器端、且同源的
不同点:
3.作用域不同
多次触发事件,事件处理函数只能执行一次,并且是在触发操作结束时执行。也就是说,当一个事件被触发准备执行事件函数前,会等待一定的时间(这时间是码农自己去定义的,比如 1 秒),如果没有再次被触发,那么就执行,如果被触发了,那就本次作废,重新从新触发的时间开始计算,并再次等待 1 秒,直到能最终执行!
const debounce = (fn, time) => {
let timer = null
return function () {
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this)
}, time)
}
}
事件触发后,规定时间内,事件处理函数不能再次被调用。也就是说在规定的时间内,函数只能被调用一次,且是最先被触发调用的那次。
const throttle = (fn, time) => {
let flag = true
return function () {
if (!flag) return
flag = false
setTimeout(() => {
fn.apply(this)
flag = true
}, time)
}
}