思维导图
![](https://file.jishuzhan.net/article/1712869306070470658/02eaeeb2b83debad505f68b91bcf7298.webp)
高阶技巧
![](https://file.jishuzhan.net/article/1712869306070470658/ed851c0a15e745170209a3115dbbd979.webp)
1. 深浅拷贝
![](https://file.jishuzhan.net/article/1712869306070470658/2083a3bd59926b6d0ce810247f5ecf9c.webp)
1.1 浅拷贝
![](https://file.jishuzhan.net/article/1712869306070470658/05333afc8fa3f0c2357b679d184ffb60.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/cf265e11e214c920ab60daa62b8df708.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/5ecb03841eca74fcb8d17d8322742994.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/b9b2034f3d59ee32a76d451d7289e75a.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/25a288e82ec874d739ad8065d19c047d.webp)
1.2 深拷贝
![](https://file.jishuzhan.net/article/1712869306070470658/aa7b4ae352ee879adebfe7e7c3f52f57.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/8592c5356db07192f20a504ed077e7eb.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/fefa439a8ecb0d083ab74f9a91cf1de4.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/3d0694d31c986ab1cb8587fc5547d0a6.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/24332961c4c2d6d7b953aa66c36ac69a.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/8adb0667f09b849315a2b971976b0662.webp)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div></div>
<script>
function getTime() {
document.querySelector('div').innerHTML = new Date().toLocaleString()
setTimeout(getTime, 1000)
}
getTime()
</script>
</body>
</html>
递归函数实现深拷贝
![](https://file.jishuzhan.net/article/1712869306070470658/4dacc6bbfca584a1fdb3d17ce4557513.webp)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const obj = {
uname: 'pink',
age: 18,
hobby: ['乒乓球', '足球'],
family: {
baby: '小pink'
}
}
const o = {}
// 拷贝函数
function deepCopy(newObj, oldObj) {
debugger
for (let k in oldObj) {
// 处理数组的问题 一定先写数组 在写 对象 不能颠倒
if (oldObj[k] instanceof Array) {
newObj[k] = []
// newObj[k] 接收 [] hobby
// oldObj[k] ['乒乓球', '足球']
deepCopy(newObj[k], oldObj[k])
} else if (oldObj[k] instanceof Object) {
newObj[k] = {}
deepCopy(newObj[k], oldObj[k])
}
else {
// k 属性名 uname age oldObj[k] 属性值 18
// newObj[k] === o.uname 给新对象添加属性
newObj[k] = oldObj[k]
}
}
}
deepCopy(o, obj) // 函数调用 两个参数 o 新对象 obj 旧对象
console.log(o)
o.age = 20
o.hobby[0] = '篮球'
o.family.baby = '老pink'
console.log(obj)
console.log([1, 23] instanceof Object)
// 复习
// const obj = {
// uname: 'pink',
// age: 18,
// hobby: ['乒乓球', '足球']
// }
// function deepCopy({ }, oldObj) {
// // k 属性名 oldObj[k] 属性值
// for (let k in oldObj) {
// // 处理数组的问题 k 变量
// newObj[k] = oldObj[k]
// // o.uname = 'pink'
// // newObj.k = 'pink'
// }
// }
</script>
</body>
</html>
![](https://file.jishuzhan.net/article/1712869306070470658/8a04482e402c4236515354e44d873cf3.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/09b7c2902c5ee233783afcda9affba73.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/ba12341431d7da9084a8056818d67e4d.webp)
lodash实现深拷贝
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 先引用 -->
<script src="./lodash.min.js"></script>
<script>
const obj = {
uname: 'pink',
age: 18,
hobby: ['乒乓球', '足球'],
family: {
baby: '小pink'
}
}
const o = _.cloneDeep(obj)
console.log(o)
o.family.baby = '老pink'
console.log(obj)
</script>
</body>
</html>
![](https://file.jishuzhan.net/article/1712869306070470658/38ef82220878a3ed39b07a5d08aa1b7c.webp)
利用JSON实现深拷贝
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const obj = {
uname: 'pink',
age: 18,
hobby: ['乒乓球', '足球'],
family: {
baby: '小pink'
}
}
// 把对象转换为 JSON 字符串
// console.log(JSON.stringify(obj))
const o = JSON.parse(JSON.stringify(obj))
console.log(o)
o.family.baby = '123'
console.log(obj)
</script>
</body>
</html>
![](https://file.jishuzhan.net/article/1712869306070470658/e81f93fbea5e97bd851e0bb7bc0f3db8.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/cf042441abe8f8d8d21fe7c2b29b7b0e.webp)
2.异常处理
2.1 throw 抛异常
![](https://file.jishuzhan.net/article/1712869306070470658/f2885de0bf6728d69235e6d316d126b2.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/a16826d39e6ff25ca3b224823ad113a6.webp)
2.2 try/catch 捕获错误信息
![](https://file.jishuzhan.net/article/1712869306070470658/05d92f22adbf6672ec7710ea4074711d.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/fa9a249ce32a2bfada1953ad5404c2b3.webp)
2.3 debugger
![](https://file.jishuzhan.net/article/1712869306070470658/aeae84ef42b2a6e9892957ffc19a32b7.webp)
3.处理this
![](https://file.jishuzhan.net/article/1712869306070470658/16a8d39e6e0286f9385cff9dac9777b7.webp)
3.1 this指向
普通函数
![](https://file.jishuzhan.net/article/1712869306070470658/99db943fffa826fbc7815093330bc65e.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/45212577ca27d25eec3a37e5823a5433.webp)
箭头函数
![](https://file.jishuzhan.net/article/1712869306070470658/dff516ba6cd44442f8f7281b9d78db76.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/7ab74f9dea4690ccd5e8d7f4d820efbf.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/0c3db45f314bba0eadc8f95380e1a6be.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/c8220c84bc72c66a4d75bb1af24261b6.webp)
3.2 改变this
![](https://file.jishuzhan.net/article/1712869306070470658/f9d7300f8b81ebb9bdf9f514380608e9.webp)
call()
![](https://file.jishuzhan.net/article/1712869306070470658/4b50780a594b786c21320bc4ff8d67d0.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/735360a777e8f329ba96ba1f82e41d33.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/87f3a33ce9b7c4138c0505a190311897.webp)
apply()
![](https://file.jishuzhan.net/article/1712869306070470658/ab40cdb7945a31b44db21c1ed4ce6fed.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/b8253e6450f785525f8a5e8445a077bb.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/ca7f6547bd307b97212652cf67162afb.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/a8163c0aa2384fcbfd1175cb082cf7ae.webp)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const obj = {
age: 18
}
function fn(x, y) {
console.log(this) // {age: 18}
console.log(x + y)
}
// 1. 调用函数
// 2. 改变this指向
// fn.apply(this指向谁, 数组参数)
fn.apply(obj, [1, 2])
// 3. 返回值 本身就是在调用函数,所以返回值就是函数的返回值
// 使用场景: 求数组最大值
// const max = Math.max(1, 2, 3)
// console.log(max)
const arr = [100, 44, 77]
const max = Math.max.apply(Math, arr)
const min = Math.min.apply(null, arr)
console.log(max, min)
// 使用场景: 求数组最大值
console.log(Math.max(...arr))
</script>
</body>
</html>
bind()-重点
![](https://file.jishuzhan.net/article/1712869306070470658/e6b35baf88279417c4960cda0c20bd56.webp)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>发送短信</button>
<script>
const obj = {
age: 18
}
function fn() {
console.log(this)
}
// 1. bind 不会调用函数
// 2. 能改变this指向
// 3. 返回值是个函数, 但是这个函数里面的this是更改过的obj
const fun = fn.bind(obj)
// console.log(fun)
fun()
// 需求,有一个按钮,点击里面就禁用,2秒钟之后开启
document.querySelector('button').addEventListener('click', function () {
// 禁用按钮
this.disabled = true
window.setTimeout(function () {
// 在这个普通函数里面,我们要this由原来的window 改为 btn
this.disabled = false
}.bind(this), 2000) // 这里的this 和 btn 一样
})
</script>
</body>
</html>
![](https://file.jishuzhan.net/article/1712869306070470658/71bbbe23bd99e96f37169919baee47c2.webp)
4.性能优化
4.1 防抖
![](https://file.jishuzhan.net/article/1712869306070470658/a226220a6c20e176f513a9584f6fa96d.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/4d0b4b3225de66b8566e14ca81f85458.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/5b6c0436d5b5741d893bd0aec6990c18.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/246203dedc7a0407b15cfe3890a570bb.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/0b6117e7c25d39fd044dbe17cb2162fb.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/b9f0ed2858d7069962ccc9496c5307ac.webp)
lodash提供的防抖处理
_.debounce(mouseMove, 500)
![](https://file.jishuzhan.net/article/1712869306070470658/a80992f5c34be6049a3cddede50fb201.webp)
手写防抖
![](https://file.jishuzhan.net/article/1712869306070470658/e36d1c0b3b79bd139594344ecd628a57.webp)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box {
width: 500px;
height: 500px;
background-color: #ccc;
color: #fff;
text-align: center;
font-size: 100px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
const box = document.querySelector('.box')
let i = 1 // 让这个变量++
// 鼠标移动函数
function mouseMove() {
box.innerHTML = ++i
// 如果里面存在大量操作 dom 的情况,可能会卡顿
}
// 防抖函数
function debounce(fn, t) {
let timeId
return function () {
// 如果有定时器就清除
if (timeId) clearTimeout(timeId)
// 开启定时器 200
timeId = setTimeout(function () {
fn()
}, t)
}
}
// box.addEventListener('mousemove', mouseMove)
box.addEventListener('mousemove', debounce(mouseMove, 200))
</script>
</body>
</html>
4.2 节流
![](https://file.jishuzhan.net/article/1712869306070470658/08c9f3fad6a6f2776b426e5dcc7e3906.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/362dfaf05620e2c27edd862683ac49fb.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/21d645b83f44e115718bd12d0b500faf.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/1a77825115cae7f300ec93e2aeee3266.webp)
lodash实现节流
![](https://file.jishuzhan.net/article/1712869306070470658/8b4c56e22f80dced2fe125ecdacb9cd6.webp)
手动实现节流
![](https://file.jishuzhan.net/article/1712869306070470658/cbb5d7533b8c08515711a0daecef67b6.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/3a75dd86cb958a297807b67360fb0c12.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/efa321a48b40395f4d41625d2e547d50.webp)
所以使用timer = null 清空定时器
![](https://file.jishuzhan.net/article/1712869306070470658/e80e81f5ea573889e65ed1a9b9abf2d1.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/bce29d3c25d7d4ea83448e6d50efc80a.webp)
5.综合案例
![](https://file.jishuzhan.net/article/1712869306070470658/4022b40d3293b964a62b3ab64b031547.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/230fa105e7ec9e86327c72b99920196a.webp)
![](https://file.jishuzhan.net/article/1712869306070470658/08f4c833aa85c4da6344c76375b0b280.webp)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="referrer" content="never" />
<title>综合案例</title>
<style>
* {
padding: 0;
margin: 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="http://pip.itcast.cn">
<img src="https://pip.itcast.cn/img/logo_v3.29b9ba72.png" alt="" />
</a>
</div>
<div class="video">
<video src="https://v.itheima.net/LapADhV6.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.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script>
// 1. 获取元素 要对视频进行操作
const video = document.querySelector('video')
video.ontimeupdate = _.throttle(() => {
// console.log(video.currentTime) 获得当前的视频时间
// 把当前的时间存储到本地存储
localStorage.setItem('currentTime', video.currentTime)
}, 1000)
// 打开页面触发事件,就从本地存储里面取出记录的时间, 赋值给 video.currentTime
video.onloadeddata = () => {
// console.log(111)
video.currentTime = localStorage.getItem('currentTime') || 0
}
</script>
</body>
</html>