异常处理
抛异常
-
异常处理指"预估代码执行过程中可能发生的错误",最大程度的避免错误的发生导致整个程序无法继续运行
-
throw 抛出异常信息,程序也会终止执行
-
throw 后面跟的是"错误提示信息"
-
Error 对象配合 throw 使用,能够设置更详细的错误信息
<script>
function add(x, y) {
if (!x || !y) {
// throw '参数不能为空'
throw new Error('没有参数传递进来')
}
return x + y
}
console.log(add());
</script>
捕获异常
<body>
<p>123</p>
<script>
try {
const p = document.querySelector()
p.style.color = 'red'
} catch (err) {
console.log(err.message);
}
finally {
console.log('一定会执行这里')
alert('OVER')
}
</script>
</body>
debugger
<script>
function cloneDeep(arr) {
debugger // 如果写上这一行代码,就意味着程序将在这里暂停,等待你的调试
for(let i = 0; i < arr.length; i++) {
console.log(i);
}
}
</script>
性能优化
防抖
基本概念
单位时间内,频繁触发事件,先取消前面的,只执行最后一次
具体演示
- 要求:鼠标在盒子上移动,鼠标停止500ms之后(即半秒),里面的数字才会累加+1
- 实现方式:利用 lodash 工具库提供的防抖来实现
<body>
<div class="box" style="width: 200px; height: 200px; background-color: pink;"></div>
<!-- 引入lodash库 -->
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
<script>
const box = document.querySelector('.box')
let i = 1
function add() {
box.innerHTML = i++
}
// 利用lodash库实现防抖---500毫秒之后进行+1操作
box.addEventListener('mousemove', _.debounce(add, 500))
</script>
</body>
拓展部分:手写防抖函数,模拟debounce的防抖功能
<body>
<div class="box" style="width: 200px; height: 200px; background-color: pink;"></div>
<script>
const box = document.querySelector('.box')
// 模拟debounce防抖
function debounce(func, time) {
let timer
return function () {
if (timer) clearTimeout(timer)
timer = setTimeout(func, time)
}
}
// 我的功能
let i = 1
function add() {
box.innerHTML = i++
}
box.addEventListener('mousemove', debounce(add, 500))
</script>
</body>
节流
基本概念
单位时间内,频繁触发事件,只执行最开始的一次
具体演示
<body>
<div class="box" style="width: 200px; height: 200px; background-color: pink;"></div>
<!-- 引入lodash库 -->
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
<script>
const box = document.querySelector('.box')
let i = 1
function add() {
box.innerHTML = i++
}
// 利用lodash库实现节流---3000毫秒之后进行+1操作
box.addEventListener('mousemove', _.throttle(add, 3000))
</script>
</body>
拓展部分:手写节流函数,模拟throttle的节流功能
<body>
<div class="box" style="width: 200px; height: 200px; background-color: pink;"></div>
<script>
const box = document.querySelector('.box')
// 模拟throttle节流
function throttle(func, time) {
let timer
return function () {
if (timer) return
timer = setTimeout(() => {
func()
timer = null // 清除定时器
// 注意:在setTimeout中是无法删除定时器的(即:clearTimeout()不起作用),因为定时器还在运作,所以使用timer = null的形式
}, time)
}
}
// 我的功能
let i = 1
function add() {
box.innerHTML = i++
}
box.addEventListener('mousemove', throttle(add, 500))
</script>
</body>
总结对比
性能优化 | 说明 | 使用场景 |
---|---|---|
防抖 | 单位时间内,频繁触发事件,只执行最后一次 | 搜索框搜索输入、手机号、邮箱验证输入监测 |
节流 | 单位时间内,频繁触发事件,只执行最初一次 | 高频事件:鼠标移动mousemove、页面尺寸缩放resize、滚动条滚动scroll等 |
案例演示
前置知识
- ontimeupdate 事件:在视频/音频(video/audio)当前的播放位置发生改变时触发
- onloadeddata 事件:在当前帧的数据加载完成,而且还没有足够的数据播放视频/音频(video/audio)的下一帧时触发
- video.currentTime:获取视频当前播放的时间
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 1200px;
margin: 0 auto;
}
.video video {
width: 100%;
padding: 20px 0;
}
.elevator {
position: fixed;
top: 280px;
right: 20px;
z-index: 999;
background: #fff;
border: 1px solid #e4e4e4;
width: 60px;
}
.elevator a {
display: block;
padding: 10px;
text-decoration: none;
text-align: center;
color: #999;
}
.elevator a.active {
color: #1286ff;
}
.outline {
padding-bottom: 300px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<a href="#">
<img src="#" alt="">
</a>
</div>
<div class="video">
<video src="https://stream7.iqilu.com/10339/upload_transcode/202002/18/20200218114723HDu3hhxqIT.mp4"
controls></video>
</div>
<div class="elevator">
<a href="javascript:" data-ref="video">视频介绍</a>
<a href="javascript:" data-ref="intro">内容简介</a>
<a href="javascript:" data-ref="outline">评论列表</a>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
<script>
// 1. 获取视频对象
const video = document.querySelector('video')
// 2. 操作视频对象
// ontimeupdate触发的频率太高,我们可以进行节流,设定1秒种触发一次
video.ontimeupdate = _.throttle(() => {
// 把当前的视频播放时间存储到本地
localStorage.setItem('currentTime', video.currentTime)
}, 1000)
// 3. 打开页面触发事件————从本地存储中取出记录的时间,并进行跳转
video.onloadeddata = () => {
video.currentTime = localStorage.getItem('currentTime') || 0
}
</script>
</body>
</html>