浅拷贝和深拷贝只针对引用类型
如果是简单数据类型拷贝值,引用数据类型拷贝的是地址(简单理解:如果单层对象,没问题,如果有多层就有问题)
拷贝对象:
①Object.assgin(新对象,拷贝对象)
②const 新对象={...拷贝对象}
拷贝数组:
①Array.prototype.concat(新数组,拷贝数组)
②const 新数组={...拷贝数组}
拷贝的是对象,不是地址
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数
const div = document.querySelector('div')
function time() {
div.innerHTML = Date().toLocaleString()
setTimeout(time, 1000)
}
time()
// 定义两个对象
let a = {
name: '小明',
age: 18,
hobby: ['唱歌', '玩游戏'],
brother: {
name: '小黑',
age: 19
}
}
let b = {}
// 定义深拷贝函数
function deepCopy(newObject, oldObject) {
// 1.遍历旧对象
// key是对象里面的属性名
for (let key in oldObject) {
// 如果对象里面包含数组,则对数组进行循环(递归)
if (oldObject[key] instanceof Array) {
newObject[key] = []
deepCopy(newObject[key], oldObject[key])
} // 如果对象里面包含对象,则对对象进行循环(递归)
else if (oldObject[key] instanceof Object) {
newObject[key] = {}
deepCopy(newObject[key], oldObject[key])
} else {
newObject[key] = oldObject[key]
}
}
}
deepCopy(b, a)
了解JavaScript中程序异常处理的方法,提升代码运行的健壮性
语法:throw new Error("提示信息")
总结:
①throw抛出异常信息,程序也会终止执行
②throw后面跟的是错误提示信息
③Error对象配合throw使用,能够设置更详细的错误信息
总结:
①try...catch用于捕获错误信息
②将预估可能发生错误的代码写在try代码段中
③如果try代码段中出现错误后,会执行catch代码段,并截获到错误信息
④finally不管是否有错误,都会执行
call和apply的区别
单位时间内,频繁触发事件,只执行最后一次
实现方式:
<script src="./js/lodash.min.js"></script>
<script>
// 鼠标在盒子上移动,里面的数字就会变化加1
// 1.获取元素
const div = document.querySelector('div')
const h2 = document.querySelector('h2')
// 2.绑定鼠标移动事件
let i = 1
div.addEventListener(
'mousemove',
_.debounce(function () {
h2.innerHTML = i++
}, 500)
)
</script>
<script src="./js/lodash.min.js"></script>
<script>
// 鼠标在盒子上移动,里面的数字就会变化加1
// 1.获取元素
const div = document.querySelector('div')
const h2 = document.querySelector('h2')
// 2.定义鼠标移动函数
let i = 1
function mousemove() {
h2.innerHTML = i++
}
// 手写防抖函数,核心是利用setTimeout定时器来实现
// 1.声明一个定时器变量
// 2.每次鼠标移动(事件触发)的时候都要先判断是否有定时器,如果有的话先清除之前的定时器
// 3.如果没有定时器,则开启定时器,存入到定时器变量里面
// 4.定时器里面写函数调用
div.addEventListener('mousemove', debounce(mousemove, 500))
function debounce(fn, t) {
let timeId
// return 返回一个匿名函数
return function () {
//2.3.4
if (timeId) clearTimeout(timeId)
timeId = setTimeout(function () {
fn()
}, t)
}
}
单位时间内,频繁触发事件,只执行一次
实现方式:
<script src="./js/lodash.min.js"></script>
<script>
// 鼠标在盒子上移动,里面的数字就会变化加1
// 1.获取元素
const div = document.querySelector('div')
const h2 = document.querySelector('h2')
// 2.绑定鼠标移动事件
let i = 1
div.addEventListener(
'mousemove',
_.throttle(function () {
h2.innerHTML = i++
}, 3000)
)
</script>
<script src="./js/lodash.min.js"></script>
<script>
// 鼠标在盒子上移动,里面的数字就会变化加1
// 1.获取元素
const div = document.querySelector('div')
const h2 = document.querySelector('h2')
let i = 1
function mouseMove() {
h2.innerHTML = i++
}
div.addEventListener('mousemove', throttle(mouseMove, 500))
// 核心思路
// 1.声明一个定时器变量
// 2.当鼠标滑过都先判断有没有定时器,如果有定时器则不开启新的定时器
// 3.如果没有定时器则开启定时器,并存在定时器变量里面
// 4.定时器里面要调用执行的函数,定时器里面要把定时器清空
// 绑定鼠标移动事件
function throttle(fn, time) {
let timeId = null
return function () {
if (!timeId) {
timeId = setTimeout(function () {
fn()
timeId = null
}, time)
}
}
}
</script>
// 获取元素
const video = document.querySelector('video')
// let time = 0
// 给video绑定timeupdate事件,该事件会在视频/音频当前位置发生改变时触发
// 因为事件执行频率太快,需要进行节流
video.addEventListener(
'timeupdate',
_.throttle(function () {
// 把当前视频播放的位置存储到浏览器中
localStorage.setItem('videoTime', video.currentTime)
}, 1000)
)
// 给video绑定loadeddata事件,该事件会在页面加载时触发
video.addEventListener('loadeddata', function () {
// 将本地存储的时间赋值给视频现在播放的时间,实现视频从上一次的视频播放位置开始播放
video.currentTime = localStorage.getItem('videoTime') || 0
})