深浅拷贝:
浅拷贝:
拷贝对象后,如果里面的属性值是简单数据类型直接拷贝值.
如果属性值是引用数据类型则拷贝的是地址.
语法:
const obj = {
uname : 'ly',
age : 18
}
//浅拷贝
const o = { ...obj }
o.age = 20
//其中obj中age为18, o中age为20
const o1 = {}
Object.assign(o1, obj)//obj赋值给o1
o.age = 20
//其中obj中age为18, o1中age为20
深拷贝:
拷贝的是对象,不是地址
常见方法:
1. 通过递归实现深拷贝
const obj = {
uname : 'ly',
age : 18,
hobby : ['ll', 'yy'],
family : {xixi: 'hhh'}
}
const o = {}
//拷贝函数
function deepCopy(newObj, oldObj) {
for (let k in oldObj) {
//处理数组问题
if(oldObj[k] instanceof Array)
{
newObj[k] = []
//newObj[k] 接收[]
//oldObj[k] ['ll', 'yy']
deepCopy(newObj[k], oldObj[k])
}else if(oldObj[k] instanceof Object)
{
newObj[k] = {}
//newObj[k] 接收{}
deepCopy(newObj[k], oldObj[k])
}else{
//k 属性名 uname, oldObj[k] 属性值
// newObj[k] === o.uname
newObj[k] = oldObj[k]
}
}
}
deepCopy(o, obj)
//这样就不会互相影响了
注意:
递归容易发生 " 栈溢出 ", 所以必须要加推出条件 return
先数组再对象,因为数组也是属于对象
2. lodash / cloneDeep
<script src = './lodash.min.js'></script>
const obj = {
uname : 'ly',
age : 18,
hobby : ['ll', 'yy'],
family : {xixi: 'hhh'}
}
const o = _.cloneDeep(obj)
先通过利用第三方库来使用.
先引用,再使用
3. 通过JSON.stringify()实现
const obj = {
uname : 'ly',
age : 18,
hobby : ['ll', 'yy'],
family : {xixi: 'hhh'}
}
const o = JSON.parse(JSON.stringify(obj))
注意:
JSON.parse()是将JSON字符串转化为对象
JSON.stringify()将对象转化为JSON字符串
---
异常处理 : 预估代码执行过程中可能发生的错误.
throw抛异常:
throw抛出异常信息, 程序会终止执行.
Error配合使用
try/catch捕获错误信息:
<p> 123</p>
function fn(){
try {
//可能发送错误的代码
const p = document.querySelector('.p')
p.style.color = 'red'
}catch(err){
console.log(err.message)
throw new Error('出现错误')
//需要return中断程序
//return
}
finally{
//不管程序对不对,一定会执行的代码
alert('hhh')
}
}
fn()
预估发生错误的代码放入try中,
如果try代码中出现错误后,会执行catch代码段,并截获到错误信息.
debugger
---
普通函数this指向 : 谁调用this就指向谁.
箭头函数this指向 : 箭头函数不存在this, 但是默认绑定外层this的值.
改变this: 3个方法可以动态指定普通函数中this指向
1. call()
fn.call(指定this的指向, 参数1, 参数2...)
2. apply()
fn.apply(指定this的指向, [传递的值,必须包含在数组里面])
3. bind() : 不会调用函数, 但是能改变this指向.
返回值是个函数, 但是这个函数里面的this指向是更改过的.
fn.bind(指定this的指向, 参数1, 参数2...)
const obj = {
uname = 'll'
}
function fn(){
console.log('hh')
}
const fun = fn.bind(obj)
//调用函数
fun()
---
防抖: 单位时间内, 频繁触发事件,只执行最后一次.
手写防抖函数 : 鼠标在盒子上移动,鼠标停止500ms之后,里面数字才会变化+1
function debounce(fn, t){
let timer;
// return 返回一个匿名函数
return function(){
if(timer) clearTimeout(timer)
timer = setTimeout(function(){
fn()
}, t)
}
}
box.addEventListener('mousemove', debounce(mouseMove, 500))
节流: 单位时间内, 频繁触发事件, 只执行一次.
function throttle(fn, t){
let timer = null;
// return 返回一个匿名函数
return function(){
if(!timer)
{
timer = setTimeout(function(){
fn()
// 在setTimeout中是无法删除定时器(clearTimeout), 所以只能用timer= null
timer = null
}, t)
}
}
}
box.addEventListener('mousemove', throttle(mouseMove, 500))