一省:HTML
19. 强制缓存和协商缓存?
HTTP缓存可以分为强制缓存和协商缓存两种。
1. 强制缓存: 当客户端第一次请求服务器资源时,服务器会在响应头中加入 Cache-Control 或 Expires 字段,告诉客户端在规定时间内直接使用本地缓存而不需要再次请求服务器。如果在规定时间内客户端再次请求该资源,浏览器会直接从本地缓存中获取资源并返回给客户端。常见的强制缓存指令包括:
Cache-Control
: max-age=xxx:规定资源被缓存的时间(单位秒)。Expires
: xxx:规定缓存的过期时间,必须是一个 GMT 格式的时间。
2. 协商缓存: 当客户端第一次请求服务器资源时,服务器返回的响应头中不包含强制缓存指令,此时客户端必须将该资源缓存起来。当客户端再次请求该资源时,客户端会先向服务器发送一个请求,由服务器判断该资源是否更新,如果没有更新则返回 304 Not Modified
状态码,告诉客户端可以使用本地缓存,否则返回更新后的资源。常见的协商缓存指令包括:
Last-Modified/If-Modified-Since
:服务器响应头中包含Last-Modified
字段,表示该资源最后一次修改的时间,客户端再次请求该资源时,会在请求头中加入If-Modified-Since
字段,表示上一次请求该资源时的最后修改时间,服务器通过比较两个时间判断资源是否更新。ETag/If-None-Match
:服务器响应头中包含ETag
字段,表示该资源的唯一标识,客户端再次请求该资源时,会在请求头中加入If-None-Match
字段,表示上一次请求该资源时的唯一标识,服务器通过比较两个标识判断资源是否更新。
使用缓存可以减少网络传输和服务器负载,提高网页的响应速度和用户体验。但需要注意,强制缓存会导致客户端无法及时获取最新的资源,协商缓存需要服务器和客户端配合,否则会导致客户端缓存失效。因此在开发过程中需要根据具体情况综合使用强制缓存和协商缓存。
二省: CSS
19. 如何垂直水平居中一个元素?
<style>
.out_box {
width: 600px;
height: 600px;
background: tomato;
}
.inner_box {
width: 200px;
height: 200px;
background: yellowgreen;
}
</style>
<body>
<div class="out_box">
<div class="inner_box"></div>
</div>
</body>
- 弹性盒子,flex布局
.out_box { display: flex; align-items: center; justify-content: center; }
- Gird布局
.out_box { display: grid; align-items: center; justify-content: center; }
- table布局
.out_box { display: table-cell; vertical-align: middle; text-align: center; } .inner_box { display: inline-block; }
- 绝对定位 + margin:auto;
.out_box { position: relative; } .inner_box { position: absolute; top: 0; left: 0; bottom: 0; right: 0; margin: auto; }
- 绝对定位 + transform
.out_box { position: relative; } .inner_box { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
- 绝对定位 + margin负值(适用于子元素高度确定)
.out_box { position: relative; } .inner_box { position: absolute; top: 50%; left: 50%; margin-top: -100px; margin-left: -100px; }
三省:JavaScript
19. 数组的方法(二)
7. 操作方法
- concat() 拼接数组并返回一个新数组
let arr = [1, 2, 3] console.log(arr.concat(4, 5));//[1, 2, 3, 4, 5] let newArr = [6, 7, 8] console.log(arr.concat(4, 5, newArr));//[1, 2, 3, 4, 5, 6, 7, 8]
- slice() 截取数组中一段并返回一个新数组
// slice() 接收两个参数,开始索引和结束索引,若没有结束索引,则截取从开始索引到数组末尾的元素 let arr = [1,2,3,4,5,6] console.log(arr.slice(2, 5));// [3, 4, 5] console.log(arr.slice(-3, -1));//[4, 5] console.log(arr.slice(2));//[3, 4, 5, 6]
splice() 可以执行删除、插入和替换操作
// splice() 删除 传两个参数,第一个是开始的下标,第二个是删除的数量 let arr = ["old1","old2","old3"] console.log(arr.splice(0, 1));//删除的元素['old1'] console.log(arr);//['old2', 'old3'] // splice() 插入 传三个或更多参数,第一个是开始的下标,第二个要是删除的数量(插入的话是0,因为不需要删除),后边是要插入的元素 let arr = ["old1","old2","old3"] console.log(arr.splice(1, 0, "new1", "new2"));//删除的元素[] console.log(arr);//['old1', 'new1', 'new2', 'old2', 'old3'] // splice() 替换 传三个或更多参数,第一个是开始的下标,第二个要是删除的数量,后边是要插入的元素 let arr = ["old1","old2","old3"] console.log(arr.splice(1, 2, "new1", "new2"));//删除的元素['old2', 'old3'] console.log(arr);//['old1', 'new1', 'new2']
8. 查找和位置方法
- 严格相等搜索
let arr = [1,2,3,4,5,6,5,4,3,2,1]
- indexof() 从头开始查找,找到就返回下标,否则返回-1
console.log(arr.indexOf(5));//4 console.log(arr.indexOf(15));//-1
- lastIndexOf() 从末尾开始查找,找到就返回下标,否则返回-1
console.log(arr.lastIndexOf(5));//6 console.log(arr.lastIndexOf(15));//-1
- includes() 从头开始查找,找到就返回true,否则返回false
console.log(arr.includes(5));//true console.log(arr.includes(15));//false
- indexof() 从头开始查找,找到就返回下标,否则返回-1
- 断言函数搜索
//断言函数接收三个参数 元素、索引和数组本身 let friends = [ { name: "Jack", age: 10 }, { name: "James", age: 20 } ]
- find(断言函数) 返回第一个匹配的元素
console.log(friends.find((el, index, arr) => { return el.age > 18 }));//{name: 'James', age: 20} console.log(friends.find((el, index, arr) => el.name === "Jac k"));//{name: 'Jack', age: 10}
- findIndex(断言函数) 返回第一个匹配元素的下标
console.log(friends.find((el, index, arr) => { return el.age > 18 }));//1 console.log(friends.find((el, index, arr) => el.name === "Jac k"));//0
- find(断言函数) 返回第一个匹配的元素
9. 迭代方法
ECMAScript为数组定义了5个迭代方法,分别是every()
、some()
、filter()
、map()
、forEach()
- every()\
every()
检查数组中的所有元素是否都满足指定条件,返回布尔值。该方法接收一个函数作为参数,该函数接收三个参数:当前元素、当前索引和原数组let arr = [2,3,4,5,6] console.log(arr.every((item) => item > 1));//true console.log(arr.every((item) => item % 2 === 0));//false
- some()\
some()
检查数组中是否有至少一个元素满足指定条件,返回布尔值。该方法接收一个函数作为参数,该函数接收三个参数:当前元素、当前索引和原数组let arr = [2,3,4,5,6] console.log(arr.some((item) => item % 2 !== 0));//true console.log(arr.some((item) => item > 6));//false
- filter()\
filter()
创建一个新数组,其中包含原始数组中满足指定条件的所有元素。该方法接收一个函数作为参数,该函数接收三个参数:当前元素、当前索引和原数组let arr = [2,3,4,5,6] console.log(arr.filter((item) => item % 2 === 0));//[2, 4, 6] console.log(arr.filter((item) => item <5 ));//[2, 3, 4]
- map()\
map()
创建一个新数组,其中包含原始数组的每个元素调用回调函数的结果。该方法接收一个函数作为参数,该函数接收三个参数:当前元素、当前索引和原数组let arr = [2,3,4,5,6] console.log(arr.map((item) => item % 2));//[0, 1, 0, 1, 0] console.log(arr.map((item) => item * 2 ));//[4, 6, 8, 10, 12]
- forEach()\
forEach()
对数组中的每个元素执行指定的操作,没有返回值。该方法接受一个回调函数,该函数接受三个参数:当前元素、当前索引和原数组。let arr = [2,3,4,5,6] arr.forEach((item) => console.log(item));//2 3 4 5 6
10. 归并方法
JavaScript数组的归并方法可以将数组中的元素按照指定规则进行归并计算,返回一个最终结果。ECMAScript为数组提供了2个归并方法:reduce()和reduceRight().
- reduce() \
reduce()
对数组中的所有元素执行指定的操作,并返回最终结果。该方法接受一个回调函数和一个可选的初始值。该回调函数接受四个参数:累积值、当前元素、当前索引和原数组。// reduce() 实现累加 let arr = [1, 2, 3, 4, 5] console.log(arr.reduce((prev, cur, index, arr) => prev + cur));//15
- reduceRight()\
reduceRight()
与reduce()
方法类似,但是从数组的末尾开始遍历数组。let arr = ["?", "you", "are", "who"] console.log(arr.reduceRight((prev, cur, index, arr) => prev + ' ' + cur));//who are you ?