高阶技巧
一.深浅拷贝
1.浅拷贝
浅拷贝:把对象拷贝给一个新的对象
存在问题:如果直接赋值,则复制的是地址,修改任何一个对象,另一个对象都会变化
常见方法:
- 拷贝对象:
Object. assign()
展开运算符 {...obj} - 拷贝数组:
Array.prototype.concat()
展开运算符 [...arr]
浅拷贝存在的问题:
如果是基本数据类型则拷贝值 如果是引用数据类型则拷贝的还是地址,还会相互影响
2.深拷贝
深拷贝:拷贝多层,不再拷贝地址 常见方法: 通过 JSON 序列化实现 lodash库 实现 通过递归实现
1. 通过JSON序列化实现(使用较多)
JSON.stringify() 序列化为 JSON 字符串,然后再JSON.parse() 转回对
注意事项:
function 或 undefined等,在序列化过程中会被忽略
2. js库 lodash里面 _.cloneDeep 内部实现了深拷贝
官网地址:www.lodashjs.com/
3.通过递归实现深拷贝
递归: 所谓递归就是一种函数调用自身的操作 简单理解:函数内部自己调用自己, 就是递归,这个函数就是递归函数 递归函数的作用和循环效果类似 由于递归很容易发生“栈溢出”错误(stack overflow),所以记得添加退出条件 return
二.异常处理
1.throw 抛异常
异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行
总结:
- throw 抛出异常信息,程序也会终止执行
- throw 后面跟的是错误提示信息
- Error 对象配合 throw 使用,能够设置更详细的错误信息
2.try /catch 捕获异常
try 试试 catch 拦住 finally 最后
说明:
-
将预估可能发生错误的代码写在 try 代码段中
-
如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息
-
finally 不管是否有错误,都会执行
3.debugger
调用调试功能,例如设置断点
三.处理this
1.改变this
(1).call()
使用 call 方法调用函数,同时指定被调用函数中 this 的指向
语法:
fun.call(thisArg, arg1, arg2, ...)
thisArg:在 fun 函数运行时指定的 this 值 arg1,arg2:传递的其他参数 返回值就是函数的返回值,因为它就是调用函数 使用场景: Object.prototype.toString.call(数据) 检测数据类型
(2)apply()
使用 apply 方法调用函数,同时指定被调用函数中 this 的值
语法:
fun.apply(thisArg, [argsArray])
thisArg:在fun函数运行时指定的 this 值 argsArray:传递的值,必须包含在数组里面 返回值就是函数的返回值,因为它就是调用函数 使用场景: apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值
(3)bind()
bind() 方法不会调用函数。但是能改变函数内部 this 指向
语法:
fun.bind(thisArg, arg1, arg2, ...)
thisArg:在 fun 函数运行时指定的 this 值 arg1,arg2:传递的其他参数 返回由指定的 this 值和初始化参数改造的 原函数拷贝 (新函数) 使用场景: 当我们只是想改变 this 指向,并且不想调用这个函数时,可以使用 bind,比如改变定时器内部的this指向.
2.this指向总结
this的取值 不取决于函数的定义,而是取决于怎么调用的(this指向调用者) 全局内调用: fn() 指向window 对象内的方法调用:obj.fn() 指向调用对象 构造函数调用:new Person() 指向实例对象 事件处理函数中调用:指向当前触发事件的DOM元素 特殊调用 比如 call、apply、bind可以改变this指向,fun.call(obj) 指向 obj
四.性能优化
1.防抖(debounce)
防抖: 单位时间内,频繁触发事件,只执行最后一次 使用场景: 搜索框搜索输入。只需用户最后一次输入完,再发送请求手机号、邮箱验证输入检测
2.节流 ( throttle)
节流:单位时间内,频繁触发事件,只执行一次 使用场景: 高频事件:鼠标移动 mousemove、页面尺寸缩放 resize、滚动条滚动scroll 等等