JavaScript进阶 (2)

浅拷贝和深拷贝

只针对引用数据类型

浅拷贝

简单数据类型拷贝值,引用数据类型拷贝地址(只适合单层)

方法:

1.拷贝对象:Object.assgin() 或 展开运算符{...obj}

2.拷贝数组:Array.prototype.concat() 或 [...arr]

const obj = {
  uname: 'pink',
  age: 18
}

const o = {...obj}//不影响原对象
const obj = {
  uname: 'pink',
  age: 18
}

const o = {}

Object.assgin(o,obj)

但存在缺陷:

const obj = {
  uname: 'pink',
  age: 18,
  family: {
    baby:'小明'
  }
}

const o = {}
Object.assign(o, obj)
o.family.baby='小明'

console.log(o)
console.log(o)

更里层变量均发生改变

深拷贝

拷贝的是对象,而不是地址

方法:

1.递归方式实现深拷贝

2.lodash / cloneDeep

3.通过JSON.stringify()实现

递归函数

函数自己调用自己,由于容易栈溢出,必须添加退出条件 return

案例:

利用递归函数实现setTimeout模拟 setInterval效果


    function getTime() {
      document.querySelector('div').innerHTML = new Date().toLocaleString()
      setTimeout(getTime, 1000)
    }
    getTime()

递归实现深拷贝


   const obj = {
      uname: 'Tom',
      age: 18,
      sport: ['111', '222'],
      family: {
        son: 'Jack'
      }
    }
    const o = {}
    function deepCopy(newobj, oldobj) {
      for (let k in oldobj) {
        if (oldobj[k] instanceof Array) {//有Object不能放在前面,因为任何数据类型都是object,放在最后
          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]
        }

      }
    }

lodash和JSON实现深拷贝

JSON方法:

const obj = {
      uname: 'Tom',
      age: 18,
      sport: ['111', '222'],
      family: {
        son: 'Jack'
      }
    }

    const o = json.parse(JSON.stringify(obj)) 

异常处理

throw抛异常

预估计代码执行过程中可能发生的错误,最大程度错误发生导致程序无法运行

1.throw抛出异常信息,程序也会终止

2.throw后跟着错误信息

3.和Error搭配,信息更详细

function fn(x){
  if(!x)
throw new Error('参数为空!')
}

try/catch 捕获异常信息

1.try...catch用于捕获错误信息

2.将预估可能发生的错误写在try代码中

3.try中代码错误,执行catch,截获错误信息

4.不管错没错,finally都会执行

debugger

类似打断点

在代码中写可以在操作台直接定位

this深入

this指向-普通函数

谁调用函数,this就指向谁

this指向-箭头函数

不受调用方式影响,箭头函数不存在this

箭头函数中this绑定的是最近作用域中的this,沿作用域链查找

DOM事件回调函数和原型对象中函数不建议使用箭头函数

因此我们可以改变this方向

call方法改变this方向

作用:

1.调用函数

2.改变this的值

语法:  函数名.call(this.Arg,arg1,arg2...)

thisArg:运行时指定this值

arg1,arg2是传递的其他参数

tt

 const obj = {
      uname: 'Tom',
      age: 18,
      sport: ['111', '222'],
      family: {
        son: 'Jack'
      }
    }
    function fn(x, y) {

    }

    fn.call(obj, x, y)//fn的this指向obj,并调用了fn

apply()

语法:  函数名.apply(this.Arg,[arr])

[arr]: 传递的值必须在数组里

bind()

bind()不会调用函数,但会改变函数内部this指向

语法:  函数名.bind(this.Arg,arg1,arg2...)

返回 指定this值和初始化参数改造的原拷贝函数

const obj = {

}

function fn() {

}

const fun = fn.bind()//返回对原函数的拷贝,但this值发生变化
fun()

比如定时器内部this指向

const btn = document.querySelector('button')

    btn.addEventListener('click', function () {
      this.disabled = ture
      window.setTimeout(function () {
        this.disabled = false
      }.bind(this), 2000)//this指向变化
    })

防抖及其底层

防抖(debounce):单位时间内,频繁触发事件,只执行最后一次

缓冲时间段再次执行会取消上一次执行,防止消耗性能

案例:鼠标滑动,数字增加(停止500ms数字才会增加)

lodashjs库方法:

const box = document.querySelector('.box')
    let i = 1
    function move() {
      box.innerHTML = i++
    }

    box.addEventListener('mousemove', _.debounce(move, 500))//防止太过消耗性能

底层:

防抖的核心是定时器(setTimeout)实现

在定时器内执行代码,在特定条件下取消定时器

const box = document.querySelector('.box')
    let i = 1
    function move() {
      box.innerHTML = i++
    }


    function debounce(fn, t) {//返回函数,否则会立即执行
      let timer
      return function () {
        if (timer) clearTimeout(timer)
        timer = setTimeout(function () {
          fn()
        }, t)
      }
    }

    box.addEventListener('mousemove', debounce(move, 500))

节流

一段时间内只能触发一次

案例:

const box = document.querySelector('.box')
    let i = 1
    function move() {
      box.innerHTML = i++
    }


    function throttle(fn, t) {//返回函数,否则会立即执行
      let timer
      return function () {
        if (!timer)
        timer = setTimeout(function () {
          fn()
          timer = null
        }, t)
      }
    }

    box.addEventListener('mousemove', throttle(move, 500))

防抖与节流的区别

防抖:单位时间频繁触发,只执行最后一次,电话号码输入检测

节流:单位时间高频触发,只执行一次,mousemove

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

象更

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值