这里写自定义目录标题
深浅拷贝
深浅拷贝只针对引用类型。
浅拷贝
浅拷贝拷贝的是地址
单层对象的拷贝,多层对象使用这种拷贝方法就会出现问题。
<script>
//对象的浅拷贝
const obj = {
name: 'name',
age: 18
}
// 通过展开运算符{...}拷贝对象
const o = { ...obj }
o.age = 20
console.log(o);
//通过Object.assgin方法拷贝对象
const r = {}
Object.assign(r, obj)
r.age = 19
console.log(r)
// obj中的内容将不会改变
console.log(obj)
// 数组的浅拷贝
const arr = [1, 2, 3]
// 通过展开运算符拷贝数组
const a = [...arr]
a.push(1)
console.log(a)
// 通过concat方法拷贝数组
const b = [].concat(arr)
b.pop(1)
console.log(b)
console.log(arr)
</script>
深拷贝
深拷贝拷贝的是对象,不是地址。
深拷贝怎么实现:深拷贝可以实现拷贝出的新对象不会影响旧对象,实现深拷贝需要用到函数递归,普通拷贝直接赋值即可,如果遇到数组再次调用递归函数,如果遇到对象形式再次调用递归函数,如果有数组又有对象,那么先数组后对象,因为数组也是一种对象。
常见方法:
-
通过递归实现深拷贝
-
lodash/cloneDeep
_.cloneDeep(obj) -
通过JSON.stringify()实现
将对象转换成JSON 字符串,然后再转换成JSON对象。
<script>
const obj = {
name: 'name',
age: 18,
family: {
mother: 'lxy',
}
}
const o = JSON.parse(JSON.stringify(obj))
o.family.mother = 'ren'
console.log(o)
console.log(obj)
</script>
异常处理
预估代码执行过程中可能发生的错误。
throw抛异常
抛出异常信息,程序终止执行,Error对象配合throw使用
<script>
function sum(a, b) {
if (!a || !b) {
throw new Error('没有参数传递过来')
}
return a + b
}
console.log(sum());
</script>
try/catch捕获异常
捕获错误信息(浏览器提供的错误信息),不中断程序,如果需要中断程序,就用return。
将预估可能发生错误的代码写到try中,如果发生了错误catch就会拦截下来,并打印错误信息,finally不管是否有错误都会执行。
<p>123</p>
<script>
function fn() {
try {
document.querySelector('.p').style.color = 'pink'
} catch (err) { //参数err
console.log(err.message); //打印错误信息
throw new Error('选择器错误')
return //中断程序,不会打印11
}
finally { //肯定会执行的代码写在finally中
console.log(22)
}
console.log(11)
}
fn()
</script>
debugger
相当于一个断点。
处理this
this指向
普通函数:谁调用就指向谁。普通函数的严格模式下指向undefined。
箭头函数:箭头函数中没有this,要向外层作用域中一层一层的查找this,直到有this的定义。
构造函数、原型函数(原型对象)、DOM事件函数(点击事件等)最好不要用箭头函数。
改变this
- call()
fun.call(thisArg,arg1,arg2,...)
thisArg:在fun函数运行时指定的this值。
arg:普通的参数
<script>
//call方法改变this的指向
const obj = {
name: 'lxy'
}
function fn(x, y) {
console.log(this); //本来指向window,通过call改变了指向obj
}
fn.call(obj, 1, 2) //fn.call调用函数同时改变this指向
//obj给了this 实参 1传给x,2传给y
</script>
- apply()
fun.apply(thisArg,[argsArray])
thisArg:在fun函数运行时指定的this值。
argsArray:传递的值,必须包含在数组里
返回值就是函数的返回值,因为他就是调用函数
因此apply主要和数组有关系,比如使用Math.max()求数组最大值
- bind()
bind方法不会调用函数(而apply和call都会立即调用函数),但是能改变函数内部的this指向。
fun.bind(thisArg,arg1,arg2,...)
thisArg:在fun函数运行时指定的this值。
arg:传递的其他参数
返回由指定的this值和初始化参数改造的原函数拷贝(新函数)
因此当我们只是想改变this指向,而不想调用这个函数的时候,可以使用bind,比如改变定时器内部的this指向。
const obj = {
name: 'pink'
}
function fn() {
console.log(this); //本来指向window,通过call改变了指向obj
}
const fun = fn.bind(obj) //bind不会调用函数,返回一个新函数,指向obj的新函数
fun() //返回的是函数,所以要调用
改变this指向方法的区别
性能优化
防抖debounce
防抖:单位时间内,频繁触发事件,只执行最后一次。
节流throttle
防抖:单位时间内,频繁触发事件,只执行一次。