拷贝 & 异常 & this & 防抖节流

拷贝

浅拷贝和深拷贝只针对引用类型(对象)

浅拷贝

  • 拷贝对象之后,对象里面的属性值是简单数据类型直接拷贝值
  • 如果对象里面的属性值是引用数据类型则拷贝的是地址

简单理解: 如果是单层对象,浅拷贝没问题,如果有多层就有问题

深拷贝

递归

JavaScript 中可以使用 obj[属性]obj.属性 两种方式来访问对象的属性值

在 for in 中只能使用 [] 语法,而不能用 . 语法

通过递归实现简单深拷贝,示例代码如下:

const oldObj = {
    uname: '校花',
    age: 18,
    hobby: ['乒乓球', '足球'] // 对象
}
const newObj = {}
// 拷贝函数
function deepCopy(newObj, oldObj) {
    // 遍历对象中的元素,k 为属性名,oldObj[k] 为值
    for (let k in oldObj) {
        // 处理数组的问题
        if (oldObj[k] instanceof Array) {
            newObj[k] = [] // 给 newObj 添加属性为 k 的空数组
            deepCopy(newObj[k], oldObj[k])
        } else {
            newObj[k] = oldObj[k]
        }

    }
}

deepCopy(newObj, oldObj)

oldObj.hobby[0] = '篮球'  // 修改对象
console.log(newObj)
console.log(oldObj)

lodash

js 库 lodash 里面的 _cloneDeep 方法实现了深拷贝,示例代码如下:

<script src="./lodash.min.js"></script>
<script>
  const oldObj = {
    uname: '校花',
    age: 18,
    hobby: ['乒乓球', '足球']
  }

  const newObj = _.cloneDeep(oldObj)
  newObj.hobby[0] = '铅球'
  console.log(newObj)
  console.log(oldObj)
</script>

JSON

使用 JSON 字符串进行转换,示例代码如下:

const oldObj = {
  uname: '校花',
  age: 18,
  hobby: ['乒乓球', '足球'] // 对象
}
// JSON.stringify(oldObj):把对象转为 json 字符串
const newObj = JSON.parse(JSON.stringify(oldObj))
newObj.hobby[0] = '羽毛球'
console.log(newObj)
console.log(oldObj)
  • js 中字符串是基本数据类型
  • java 中 String 是不可变对象

异常

throw

function fn(x, y) {
    if (!x || !y) {
        throw new Error('没有参数')
    }
    return x + y
}
fn()

try/catch

function fn() {
    try {
        const p = document.querySelector('p')
        p.style.color = 'red'
    } catch (err) {
        console.log(err.message)
    } finally {
        console.log('最终都要执行的')
    }
}
fn()

debugger

使用 debugger 关键字写在代码中打断点

改变 this

call

使用 call 方法调用函数,同时指定被调用函数中 this 的值,语法如下:

fun.call(thisArg, arg1, arg2, ...)
  • thisArg:在调用 fun 函数时指定的 this 对象
  • arg1,arg2:传递的其他参数
  • 返回值是 fun 的返回值

示例代码如下:

const xh = {
    uname: '校花'
}
function fn(a) {
    console.log(a)
    console.log(this)
}
fn.call(xh, '程序员校花')

apply

使用 apply 方法调用函数,同时指定被调用函数中 this 的值,语法如下:

fun.apply(thisArg, [argsArray])
  • thisArg:在调用 fun 函数时指定的 this 对象

  • argsArray:传递的值,必须包含在数组里面

  • 返回值是 fun 的返回值

示例代码如下:

const xh = {
    age: 18
}
function fn(x, y) {
    console.log(this) // xh
    console.log(x + y) // 3
}
fn.apply(xh,[1, 2])

// 使用场景:求数组最大值
const max1 = Math.max(1, 2, 3, 4)
console.log(max1) // 4
const max2 = Math.max.apply(Math, [1, 2, 3])
console.log(max2) // 3

bind

bind 方法不会调用函数,但是能指定被调用函数中 this 的值,语法如下:

fun.bind(thisArg, arg1, arg2, ...)
  • thisArg:在调用 fun 函数时指定的 this 对象
  • arg1,arg2:传递的其他参数
  • 返回值:一个由指定的 this 值和传递的其他参数构成的新函数(不需要再传递实参,因为在绑定函数时已经预设了参数)

示例代码如下:

const xh = {
    age: 18
}

function fn() {
    console.log(this) // xh
}

const fun = fn.bind(xh)
fun()

// 需求,有一个按钮,点击禁用,1 秒之后开启
const btn = document.querySelector('button')
btn.addEventListener('click', function () {
    // 禁用按钮
    this.disabled = true
    window.setTimeout(function () {
        this.disabled = false
    }.bind(this), 1000) // 这个 this 即 btn
})

性能优化

防抖

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

  • 使用场景:

    • 搜索框搜索输入,只需要用户最后一次输入完,再发送请求
    • 手机号、邮箱验证输入检测
在这里插入图片描述

lodash 实现

使用 lodash 库实现防抖效果,要求: 鼠标在盒子上移动,鼠标停止之后(即最后一次事件结束后),500 ms 后里面的数字就会变化 + 1,示例代码如下:

<div class="box"></div>
<script src="lodash.min.js"></script>
<script>
  const box = document.querySelector('.box')
  let i = 1
  function mouseMove () {
    box.innerHTML = i++
    // 如果里面存在大量消耗性能的代码,比如 dom 操作、数据处理,可能会造成卡顿
  }
  // box.addEventListener('mousemove', mouseMove)
  box.addEventListener('mousemove', _.debounce(mouseMove, 500))

</script>

节流

  • 节流:单位时间内,频繁触发事件,只执行一次
  • 使用场景:高频事件
    • 鼠标移动 mousemove
    • 页面尺寸缩放 resize
    • 滚动条滚动 scroll

在这里插入图片描述

lodash 实现

使用 lodash 库实现节流效果,要求: 鼠标在盒子上移动频繁触发事件,但是使用节流操作使 2 秒内只触发一次事件,示例代码如下:

<div class="box"></div>
<script src="lodash.min.js"></script>
<script>
  const box = document.querySelector('.box')
  let i = 1
  function mouseMove () {
    box.innerHTML = i++
    // 如果里面存在大量消耗性能的代码,比如 dom 操作、数据处理,可能会造成卡顿
  }
  // box.addEventListener('mousemove', mouseMove)
  box.addEventListener('mousemove', _.throttle(mouseMove, 2000))

</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值