day25--JS进阶(递归函数,深浅拷贝,异常处理,改变this指向,防抖及节流)

目录

浅拷贝

[1.拷贝对象①Object.assgin() ②展开运算符newObj = {...obj}拷贝对象](#1.拷贝对象①Object.assgin() ②展开运算符newObj = {...obj}拷贝对象)

[2.拷贝数组 ①Array.prototype.concat() ② newArr = [...arr]](#2.拷贝数组 ①Array.prototype.concat() ② newArr = [...arr])

深拷贝

1.通过递归实现深拷贝

2.lodash/cloneDeep实现

3.通过JSON.stringify()实现

异常处理

throw抛异常

try/catch捕获异常

debugger

处理this

this指向

普通函数this指向

箭头函数this指向

改变this

call()

apply()

bind()

性能优化

防抖

[1. lodash提供的防抖函数来处理](#1. lodash提供的防抖函数来处理)

[2. 手写一个防抖函数来处理](#2. 手写一个防抖函数来处理)

节流

[1. lodash提供的节流函数来处理](#1. lodash提供的节流函数来处理)

[2. 手写一个节流函数来处理](#2. 手写一个节流函数来处理)


浅拷贝

关于对象/数组等引用数据类型直接复制出现的问题:

因为复制完后的是地址,因此修改复制后的会影响到原来的对象

需要深浅拷贝来解决。

1.拷贝对象①Object.assgin() ②展开运算符newObj = {...obj}拷贝对象

2.拷贝数组 ①Array.prototype.concat() ② newArr = [...arr]

Array.prototype.concat()

concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

因此用于拷贝,则先声明一个空数组再对其进行拷贝。

利用浅拷贝,遇到简单的引用数据类型可以,只是拷贝最外边一层,但是里层的仍然是拷贝地址!

因此,对于浅拷贝,对于多层会出现原本出现的问题,对于多层对象/数组,需要深拷贝。

深拷贝

1.通过递归实现深拷贝

深拷贝需要用到函数递归;如果遇到数组,利用递归处理;如果遇到对象,利用递归处理,二者顺序不可调换

javascript 复制代码
// 深拷贝函数
    function deepCopy(newObj, oldObj) {
      // 遍历旧对象
      for (let k in oldObj) {
        // 遇到值为数组的处理
        if (oldObj[k] instanceof Array) {
          // 如果值为数组,则要对该属性遍历,先要有一个空数组
          newObj[k] = []
          deepCopy(newObj[k], oldObj[k])
        } else if (oldObj[k] instanceof Object) {
          // 如果值为对象,则要对该属性遍历,先要有一个空对象
          newObj[k] = {}
          deepCopy(newObj[k], oldObj[k])
        } else {
          newObj[k] = oldObj[k]
        }

      }
    }

    deepCopy(o, obj)

2.lodash/cloneDeep实现

要先引入库

<script src="./lodash.min.js"></script>

3.通过JSON.stringify()实现

转为JSON字符串再进行拷贝

异常处理

throw抛异常

主观上在适当的地方抛出想设置的异常提示语

try/catch捕获异常

语法:try{} catch(err){} [finally{}]

[]表示可选

catch(err){} 是获取到错误信息对象,上述是将错误信息打印出来。catch(){}不会终止函数,需要手动进行return

debugger

debugger 代码中打断点,效果与在浏览器中同,只是有时更方便。

处理this

this指向

普通函数this指向

普通函数的this指向调用者

箭头函数this指向

逐层往外层函数一层层找,直至有this的定义

改变this

后两者更重要

call()

调用函数,同时改变函数中的this指向

apply()

与call()的不同点在于传递的函数形参要用数组包裹着

bind()

与前两者不同的是

其能改变this指向但!!不会调用函数

因为不调用函数,因此返回值并不是函数返回值,而是拷贝出来的原函数(新函数)

因此只是想改变this指向而不想立马调用函数时要首先想到bind()!!!

性能优化

一般对于触发频次比较高的时间,就需要用防抖或者节流函数来控制触发。

防抖

1. lodash提供的防抖函数来处理

(其是个函数!)

2. 手写一个防抖函数来处理
javascript 复制代码
    function debounce(fn, t) {
      let Time
      console.log(Time)
      return function () {
        if (Time) clearTimeout(Time)
        Time = setTimeout(fn, t)
      }
    }

节流

1. lodash提供的节流函数来处理

这个节流函数是指单位时间内只触发一次,如果单位时间内被触发了多次,在第一次触发结束时会被触发第二次,但不会有第三次,第四次....尽管前面触发了多次。

与手写的节流有不同,手写的节流是单位时间在最后一刻触发,且单位时间内触发了多次,仍然是最后一刻触发。

用法与上同

2. 手写一个节流函数来处理
javascript 复制代码
    function throttle(fn, t) {
      let timer
      return function () {
        // 如果没有定时器运行,则开启,开启后清空,
        // 如果有,则不开启
        console.log(timer)
        if (!timer) {
          timer = setTimeout(function () {
            fn()
            //  开启后执行完后清掉定时器(将定时器置为空),确保下一次正常执行
            // 置空一定要放在定时器内部
            timer = null
          }, t)
        }
      }
    }
相关推荐
Yhame.28 分钟前
深入理解 Java 中的 ArrayList 和 List:泛型与动态数组
java·开发语言
mazo_command2 小时前
【MATLAB课设五子棋教程】(附源码)
开发语言·matlab
IT猿手2 小时前
多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码
开发语言·人工智能·算法·机器学习·matlab
青春男大2 小时前
java栈--数据结构
java·开发语言·数据结构·学习·eclipse
88号技师2 小时前
几款性能优秀的差分进化算法DE(SaDE、JADE,SHADE,LSHADE、LSHADE_SPACMA、LSHADE_EpSin)-附Matlab免费代码
开发语言·人工智能·算法·matlab·优化算法
Zer0_on2 小时前
数据结构栈和队列
c语言·开发语言·数据结构
一只小bit2 小时前
数据结构之栈,队列,树
c语言·开发语言·数据结构·c++
一个没有本领的人3 小时前
win11+matlab2021a配置C-COT
c语言·开发语言·matlab·目标跟踪
anyup_前端梦工厂3 小时前
初始 ShellJS:一个 Node.js 命令行工具集合
前端·javascript·node.js
5hand3 小时前
Element-ui的使用教程 基于HBuilder X
前端·javascript·vue.js·elementui