01.Cookie,SessionStorage,LocalStorage
生命周期:Cookie的生命周期默认关闭浏览器后失效;SessionStorage仅在当前窗口下有效,关闭窗口或浏览器将被清除;LocalStorage除非被清除,否则永久保存。
容量:Cookie 4KB 20~50;SessionSorage 5MB;LocalStorage 5MB
网络请求:Cookie每次都会携带在HTTP头中,如果使用Cookie保存过多数据会带来性能问题;SessionStorage、LocalStorage 仅在浏览器中保存,不参与和服务器的通信,不会像Cookie那样保存在请求头中发送给服务器。
使用场景:Cookie 判断用户是否登录;SessionSorage 表单数据;LocalStorage 购物车. Cookie在本地验证完登录,发送到服务器后还可以再验证一次,双重验证更保险。SessionSorage,注册时需要填表单,数据较多,如果没有关闭窗口返回上一页时还可以存在。LocalStorage容量比较大,除非手动清除否则永远存在,上一次添加的购物车商品还可以存在。
// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');
// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');
// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');
// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();
02.同源策略
同源策略(same origin policy)是一种约定,是浏览器最核心也最基本的安全功能。协议、域名、端口都相同就是同源,否则为跨域。
协议+一级域名+二级域名+端口号 相同 才叫同源,否则为跨域。
http://www.it666.com:80/index.html
协议:http://
一级域名 :it666.com
二级域名:www
端口号:80
资源路径:index.html
同源策略带来的影响:一般情况下,浏览器只允许Ajax请求同源的数据,不同源的数据是拿不到的。但一般情况下为了提升网页的性能,网页和数据都是单独存储在不同服务器上的,这时通过Ajax请求数据就会拿不到跨域数据。
跨域解决方法:JSONP让网页从别的地址(跨域的地址)那里获取资料,即跨域读取数据。
JSONP实现跨域访问的原理:
- 在同一界面中可以定义多个script标签
- 同一个界面中多个script标签中的数据可以互相访问
- 可以通过script标签的src属性导入其他资源
- 通过src属性导入其他资源的本质就是将资源拷贝到script标签中
- script的src属性不仅能导入本地资源,还能导入远程资源
- 由于script的src属性没有同源限制,所以可以通过script的src属性来请求跨域数据
JSONP实现跨域访问优化
优化1:企业开发中通过JSONP来获取跨域的数据,一般情况下服务器返回的不是一个变量,而是一个函数的调用。
优化2:自己先定义一个函数,然后将函数名以参数的方式传递给src。就是我定义什么函数,那边就调用什么函数。
优化3:由于script标签默认是同步的,前面的script标签没有加载完数据,后面的script标签不会被执行。所以请求数据的script标签必须放在定义函数的后面。为了打破这种顺序关系限制,我们可以采取异步的script标签。通过js代码创建一个script标签,把oScript动态加载到document中。通过js代码创建一个script标签是异步的,不用等待src这个资源加载完毕就会继续往后执行,往后执行遇到test函数时已经读取了,这时资源加载完毕就会识别到已经有了一个test函数,所以不会报错。
let oScript = document.createElement("script")
oScript.src = "http://127.0.0.1:80/jQuery/Ajax/20-jsonp.php?cb=test";
document.body.appendChild(oScript)
// src在test函数前面,但不会报错,就是说这样也会找到test函数
function test(data){
console.log(data);
}
jQuery 中的JSONP封装
$.ajax({
url: "http://127.0.0.1:80...",
data: { // 发送获取跨域数据的请求时同时把数据传递过去
"teacher": "lnj",
"age": 34
}
dataType: "jsonp", // 告诉jQuery需要请求跨域的数据
jsonp: "cb", // 告诉jQuery服务器在获取回调函数名称的时候需要什么key来获取
jsonpCallback: "lnj", // 告诉jQuery服务器在获取回调函数名称的时候,回调函数的名称是什么
success: function (msg) {
console.log(msg);
}
})
03.应用程序、进程、线程,串行、并行
应用程序:应用程序是.exe后缀,一个应用程序通过多次打开,可以开启多个对应的进程。程序是通过编译器编写好的存储在硬盘上的一个二进制文件,会占用磁盘空间但不会占用系统资源。
进程:进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。一个进程中至少有一个线程,这个线程叫做主线程。进程和线程是一对多关系。
线程:线程是进程中的一个执行实例,是程序执行的最小单元。比如启动迅雷这个程序,系统会创建一个迅雷进程,并且默认会有一个主线程,用于执行迅雷默认的业务逻辑。当我们利用迅雷下载多个任务时,就会发现多个任务都在同时下载,此时为了能够同时执行下载的操作,迅雷会创建多个线程,并将不同的下载任务放到不同的线程中执行。

串行:计算机中,一个线程要执行多个指令,只能一个一个排队执行。同一时刻只能有一条指令在一个CPU上执行,后面的指令必须等待前面的指令执行完才能执行。

并行:同一时刻有多条指令可以在多个CPU上同时执行。

04.JS串行和事件循环
JS是单线程的,前面代码没有执行完后面的代码是不会输出的。
同步代码和异步代码:除了事件绑定的函数和回调函数以外的都是同步代码。事件绑定的函数和回调函数是异步代码,不会立即执行。事件绑定的函数直到事件触发了才会执行,回调函数直到条件满足了才会执行。
事件循环:js会自动将异步代码添加到数组里,这个数组放在所有代码的末尾。当执行完所有同步代码后,js会遍历这个数组里的所有异步代码,看看哪个满足条件,依次执行。
1.程序运行会从上至下依次执行所有的同步代码
2.在执行的过程中如果遇到异步代码会将异步代码放到事件循环中
3.当所有的同步代码执行完后,JS会不断检测 事件循环中的异步代码是否满足条件,一旦满足条件就会执行满足条件的异步代码
05.Promise基本概念
-
promise是ES6中新增的异步编程解决方案,在代码中的表现是一个对象.
企业开发中为了保存异步代码的执行顺序,就会出现回调函数层次嵌套,如果回调函数太多,代码的可读性和维护性会大大降低
promise对象可以将异步操作以同步流程来表示,避免了回调函数的层层嵌套
-
如何创建promise对象:
promise 对象不是异步的,只要创建promise对象就会立即执行promise里面存放的代码
let p = new Promise(function(resolve, reject){
console.log("2")
resolve();
})
-
Promise对象的三种状态
pending: 默认状态,只要没告诉promise任务是成功还是失败就是pending状态
fulfilled(resolved): 一旦调用了resolve函数就是resolved
rejected: 一旦调用了reject函数,状态就会变为rejected
注意: 状态一旦发生改变就不可逆转
-
promise如何实现通过同步的流程来表示异步的操作的?
如果状态改变成功就会自动执行状态所对应的回调函数
resolved -> then()
rejected -> catch()
-
then方法
then接受两个参数,一个参数是状态成功时执行的回调函数,另一个参数是状态为失败时的回调函数;
在修改promise状态时,可以传递参数给then方法中的回调函数;
当状态为成功时,所有的then方法都会被触发;
then方法每次执行完毕时都会返回一个新的promise对象;
可以通过上一个promise对象的then方法给下一个promise的then方法传递参数。注意:无论是在上一个promise对象成功的回调函数中还是失败的回调函数中传递参数,都会传递给下一个promise对象成功的回调中;
上一个promise对象的then方法给下一个promise的then方法传递参数时,除了传递基本数据之外,还可以传递promise对象。
-
catch方法
- 不使用链式编程的原因是,如果promise的状态是失败但没有对应失败的监听就会报错
- then方法每次执行完毕都会返回一个新的promise对象,新的promise对象会继承原有的promise状态
- 如果新的promise状态是失败,没有对应失败的监听也会报错
Promise特点
- 创建时必须传入一个函数,否则会报错
- 会给传入的函数设置两个回调函数
- 刚创建的Promise对象状态是pending
- 状态一旦发生改变就不可再次改变
- 可以通过then来监听状态的改变
- 如果添加监听时状态已经改变,立即执行监听的回调
- 如果添加监听时状态还未改变,那么状态改变时再执行监听回调
- 同一个promise对象可以添加多个then监听,状态改变时所有的监听按照添加顺序执行
06.异常处理机制
JS中的异常,简单来讲就是有错误出现,由于JS是单线程的因此前面的代码一旦出现错误,程序就会被中断,后面的代码就不会被执行。
使用try{}catch{}来处理异常可以保证程序不被中断,后续代码还可以继续执行并拿到发生错误代码的原因。
try{
可能遇到的意外代码
}catch(e){
捕获错误的代码块
}
07.fetch
-
什么是fetch?
和Ajax一样都是用于请求网络数据的
fetch是ES6中新增的基于Promise的网络请求方法
-
fetch的基本使用
fetch(url, {options}) .then() .catch()
08.axios
// 超过2秒的请求时间服务器没返回,就报错。全局的
axios.defaults.timeout = 2000
企业开发中项目分为:开发阶段和部署阶段 ,这两个阶段项目存储的位置是不同的。项目上线前存储在企业的内部测试服务器上,项目上线后存储在企业的正式服务器上。两台服务器不同则IP地址也不同,如果axios发送请求的url写死了的话,那么后期更改将会是巨大的麻烦。
为了解决这个问题,我们可以配置一个全局URL根地址,项目上线时只需修改根地址即可。前部分不用改,只用改后面部分
axios.defaults.baseURL = "http://127.0.0.1";
09.Symbol
什么是Symbol?
Symbol是ES6中新增的一种数据类型,被划分到了基本数据类型中。
基本数据类型:字符串string,数值Number,布尔boolean,undefined,null,Symbol
引用数据类型:ObjectSymbol的作用
用来表示一个独一无二的值为什么需要Symbol?
在企业开发中如果需要对一些第三方的插件、框架进行自定义的时候,可能会因为添加了同名的属性或方法将框架中原有的属性或方法覆盖掉。为了避免这种情况发生,我们就可以使用Symbol作为属性或者方法的名称。如何区分Symbol?
通过Symbol生成独一无二的值时可以设置一个标记,这个标记仅仅用于区分,没有其他任何含义-
Symbol注意点:
-
通过Symbol生成独一无二值时需要在后面加上(),但是前面不能加new,因为他不是引用类型
let x = Symbol(); -
通过Symbol生成独一无二的值时传入的字符串仅仅是一个标记,方便阅读代码,没有其他任何意义
let x = Symbol("name"); 做类型转换时不能转换成数值
不能做任何运算
-
Symbol生成的值作为属性或方法时,一定要保存下来,否则后续无法使用。因为Symbol在两个地方都创建了一个独一无二的值。
image-20230320213446059.png for循环无法遍历Symbol的属性和方法
-
10.Iterator
迭代器
- 只要一个数据自带了Iterator接口,那么这个数据就有一个叫做[Symbol.iterator]的属性
- [Symbol.iterator]的属性会返回一个函数
- [Symbol.iterator]的属性返回的函数执行之后会返回一个对象
- [Symbol.iterator]函数返回的对象中又有一个名称叫做next的方法
- next方法每次执行都会返回一个对象{value:1, done:false} value表示迭代的值,done表示是否已经迭代完成
注意:
-
解构赋值也用到了iterator接口
let arr = new MyArray(1, 3) // 1. 解构赋值 中也用到了iterator接口 let [x, y ,z] = arr; console.log(x, y, z); -
扩展运算符也用到了iterator接口
let arr1 = new MyArray(1, 3) let arr2 = new MyArray(2, 4) // 扩展运算符将两个数组合并成一个数组 let arr3 = [...arr1, ...arr2] console.log(arr3);
11.Generator函数
-
是啥?
Generator函数 是ES6提供的一种异步编程解决方案,Generator函数内部可以封装多个状态,因此可以理解成是一个状态机。
-
如何定义
只需在普通函数的function后面加上*
-
Generator函数和普通函数的区别
- 调用Generator函数后,无论函数有没有返回值,都会返回一个可迭代对象
- 调用Generator函数后,函数中封装的代码不会立即被执行
-
真正让Generator函数有价值的是yield关键字
- 在Generator函数内部使用yield关键字定义状态
- yield关键字可以让Generator函数内部的逻辑被切割成多个部分
- 通过调用迭代器对象next方法执行一个部分代码,执行哪个部分就会返回哪个部分定义的状态
在调用next方法时候可以传递一个参数,这个参数会传递给上一个yield
12.async函数
await等待promise执行完毕,才将promise里面的东西放到res1里
13.异步请求
在获取轮播图数据之前就设置loop:true的话,会导致loop失效,原因是从服务器那边请求数据是个异步操作。
解决方法:等到获取数据之后再设置loop
