当前位置: 首页 > news >正文

JavaScript 进阶(面试必备)--charater4


文章目录

  • 前言
  • 一、深浅拷贝
    • :one: 浅拷贝
    • :two:深拷贝
  • 二、异常处理
    • :one: throw 抛异常
    • :two: try /catch 捕获异常
    • :three:debugger
  • 三、处理this
    • `this指向` :one:普通函数this指向
    • `this指向` :two: 箭头函数this指向
    • 3.2 改变this
      • :one: call()
      • :two: apply()
      • :three: bind()
  • 四、性能优化
    • :one: 节流 throttle
    • :two:防抖 debounce
  • 总结


前言

这章学习目标:

  1. 深入this学习,知道如何判断this指向和改变this 指向
  2. 知道在JS中如何处理异常,学习深浅拷贝,理解递归。

提示:以下是本篇文章正文内容,下面案例可供参考

一、深浅拷贝

1️⃣ 浅拷贝

对于字符串类型,浅复制是对值的复制,对于对象来说,浅复制是对对象地址的复制,并没有开辟新的栈,也就是复制的结果是对两个对象指向同一个地址,修改其中一个对象的属性,则另外一个对象的属性也会改变。简单的来说,拷贝的是地址。
在这里插入图片描述
🔴拷贝对象之后,里面的属性值是简单数据类型直接拷贝值
🔴如果属性值是引用数据类型则拷贝的是地址

// 一个pink对象
const pink ={name:'pink老师'age:18
}
const red = pink
console.log(red)//{name:'pink老师',age:18}red.name='red老师'
console.log(red)//{name:'red者师',age:18}
//但是pink对象里面的name值也发生了变化
console.log(pink)//[name:'red老师',age:18}

⭕️常用方法
🕐拷贝对象:Object.assign() 或者展开符 {…obj } 拷贝对象

  const obj = {uname: 'pink',age: 18}const o = objconsole.log("o",o)o.age = 20console.log(" o.age",o)console.log("obj",obj)
 const obj = {uname: 'pink',age: 18}const o = {}Object.assign(o, obj)o.age = 20o.family.baby = '老pink'console.log(o)console.log(obj)

在这里插入图片描述
🕑拷贝数组:Array.prototype.concat() 或者[…arr]

✅ 直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址。

✅ 浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响,

2️⃣深拷贝

⭕️ 常见方法:

  1. 通过递归实现深拷贝
    如果一个函数在内部可以调用其本身,那么这个函数就是递归函数
    🆔递归函数的作用和循环效果类似
    🆔由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return
    在这里插入图片描述
    let i = 1function fn() {console.log(`这是第${i}`)if (i >= 6) {return}i++fn()// 函数内部调用自己}fn()

2. js库lodash 里clone Deep内部实现深拷贝

  <!-- 先引用 --><script src="./lodash.min.js"></script><script>const obj = {uname: 'pink',age: 18,hobby: ['乒乓球', '足球'],family: {baby: '小pink'}}const o = _.cloneDeep(obj)console.log(o)o.family.baby = '老pink'console.log(obj)

在这里插入图片描述
3. 通过JSON.stringify()实现

    const obj = {uname: 'pink',age: 18,hobby: ['乒乓球', '足球'],family: {baby: '小pink'}}// 把对象转换为 JSON 字符串// console.log(JSON.stringify(obj))const o=JSON.parse(JSON.stringify(obj))console.log(o)o.family.baby = '123'console.log(obj)

在这里插入图片描述

二、异常处理

1️⃣ throw 抛异常

异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行。

  1. throw 抛出异常信息,程序也会终止执行
  2. throw 后面跟的是错误提示信息
  3. Error 对象配合 throw 使用,能够设置更详细的错误信息

function counter(x,y){if(!x||!y){throw new Error('参数不能为空')}return x+y
}
counter()

2️⃣ try /catch 捕获异常

  1. try…catch 用于捕获错误信息。
  2. 将预估可能发生错误的代码写在 try 代码段中。
  3. 如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息
  4. finally 不管是否有错误,都会执行。
   function fn() {try {// 可能预估有问题的代码写到这里const p = document.querySelector('.p')p.style.color = 'red'} catch (err) {console.log(err.message)// 中断// returnthrow new Error('你是不是把选择器写错了')} finally {alert('执行')} console.log(111)}fn()

3️⃣debugger

我们可以通过try / catch 捕获错误信息(浏览器提供的错误信息)
在这里插入图片描述

三、处理this

不同的应用场合 this 的取值可能会有意想不到的结果,在此我们对以往学习过的关于【 this 默认的取值】情况进行归纳和总结。知道动态指定函数 this 值的方法。

this指向 1️⃣普通函数this指向

普通函数的调用方法决定了this的值,即【谁调用this 就指向谁】

 // 普通函数:  谁调用我,this就指向谁
1. console.log(this)  // windowfunction fn() {console.log(this)  // window    }window.fn()window.setTimeout(function () {console.log(this) // window }, 1000)2.document.querySelector('button').addEventListener('click', function () {console.log(this)  // 指向 button})3.const obj = {sayHi: function () {console.log(this)  // 指向 obj}}obj.sayHi()

this指向 2️⃣ 箭头函数this指向

箭头函数中的 this 与普通函数完全不同,也不受调用方式的影响,事实上箭头函数中并不存在 this

  1. 箭头函数会默认帮我们绑定外层this的值,所有在箭头函数中this的值和外层this是一样的
  2. 箭头函数中的this引用的就是最近作用域中的this
  3. 向外层作用域中,一层一层查找this,直到有this的定义
1.console.1og(this)//此处为window
//箭头函数
const sayHi = function(){console.log(this)//该箭头函数中的this为函数声明环境中this一致
}2.    //普通对象
const user={name:'小明',//该箭头函数中的this为函数声明环境中this一致walk:()=>{console.log(this)}
}

👿【使用箭头函数前需要考虑函数中 this 的值】,事件回调函数使用箭头函数时,this为全局的window 因此DOM 事件回调函数如果里面需要DOM对象的this,则不推荐使用箭头函数

//D0M 节点
const btn=document.queryselector('.btn')
//箭头函数此时this指向了window
btn.addEventListener('click',()=>console.log(this)
})//普通函数此时this指向了DoM对象
btn.addEventListener('click',function (){console.log(this)
})

😈同样由于this的原因,原型的对象不推荐采用箭头函数。

  1. 函数内不存在this,沿用上一级的this
  2. 不适应构造函数,原型函数,dom事件函数等等。
  3. 需要用上层this的地方。

3.2 改变this

JavaScript 允许指定函数中this 的指向,有3个方法可以动态指定普通函数中 this 的指向

1️⃣ call()

使用call 方法调用函数,同时指定被调用函数中 this 的值。

fun.call(thisArg, arg1, arg2, ...)

thisArg:在fun 函数运行时指定的this
arg1,arg2:传递参数
返回值就是函数的返回值,因为它就是调用函数。

    const obj = {uname: 'pink'}function fn(x, y) {console.log(this) // window.objectconsole.log(x + y)// 3}// 1. 调用函数  // 2. 改变 this 指向fn.call(obj, 1, 2)

2️⃣ apply()

使用 apply 方法调用函数,同时指定被调用函数中 this 的值。

  1. 调用函数
    2. 改变this指向
 fn.apply(this指向谁, [数组参数])
    const obj = {age: 18}function fn(x, y) {console.log(this) // Object{age: 18}console.log(x + y)// 3}fn.apply(obj, [1, 2])//  返回值   本身就是在调用函数,所以返回值就是函数的返回值

thisArg:在fun函数运行时指定的 this 值
argsArray:传递的值,必须包含在数组里面
返回值就是函数的返回值。因为它就是调用函数
apply 主要跟数组有关系,比如使用Math.max() 求数组的最大值。

1.const max = Math.max(1,2,3)
2.const arr =[100 , 45 ,55]
const max =Math.math.apply(Math,arr)
const min =Math.math.apply(Matg,arr)
console.log(max,min)
3. console.log(Math.max(...arr))

3️⃣ bind()

bind() 方法不会调用函数,但是能改变函数内部this 指向。

fun.bind(thisArg, arg1, arg2, ...)

thisArg:在 fun 函数运行时指定的 this 值
arg1,arg2:传递的其他参数
返回由指定的this 值和初始化参数改造的 原函数
如果不想调用函数来改变this指向时,可以使用bind,比如改变定时器内部的this 指向

  // 普通函数function sayHi() {console.log(this)}let user = {name: '小明',age: 18}// 调用 bind 指定 this 的值let sayHello = sayHi.bind(user);// 调用使用 bind 创建的新函数sayHello()

🔥注:bind 方法创建新的函数,与原函数的唯一的变化是改变了 this 的值。

四、性能优化

1️⃣ 节流 throttle

节流就指连续触发事件但是在n秒中只执行一次函数。就如等到上一个人完成动作,才能进行下一个人执行。
开发使用场景小米轮播图点击效果鼠标移动页面尺寸缩放resize滚动条滚动 就可以加节流。
如果一张轮播图完成切换需要300ms,不加节流效果,快速点击,就会快速切换。

2️⃣防抖 debounce

防抖就是触发事件后在n秒内函数只能执行一次,如果在n秒内再次触发事件,则会重新计算

开发使用场景- 搜索框防抖
假设输入就可以发送请求,但是不能每次输入都去发送请求,输入比较快发送请求会比较多,我们设定一个时间,假如300ms, 当输入第一个字符时候,300ms后发送请求,但是在200ms的时候又输入了一个字符,则需要再等300ms 后发送请求。

总结

本章深入学习里this学习,知道如何判断this指向和改变this指向,深浅拷贝,递归等知识点,在面试备考中希望能帮助到大家❤️

相关文章:

JavaScript 进阶(面试必备)--charater4

文章目录前言一、深浅拷贝:one: 浅拷贝:two:深拷贝二、异常处理:one: throw 抛异常:two: try /catch 捕获异常:three:debugger三、处理thisthis指向 :one:普通函数this指向this指向 :two: 箭头函数this指向3.2 改变this:one: call():two: apply():three: bind()四、性能优化:on…...

ARM+FPGA架构开发板PCIE2SCREEN示例分析与测试-米尔MYD-JX8MMA7

本篇测评由电子发烧友的优秀测评者“zealsoft”提供。 本次测试内容为米尔MYD-JX8MMA7开发板其ARM端的测试例程pcie2screen并介绍一下FPGA端程序的修改。 ​ 01. 测试例程pcie2screen 例程pcie2screen是配合MYD-JX8MMA7开发板所带的MYIR_PCIE_5T_CMOS 工程的测试例&#…...

51单片机入门 - SDCC / Keil_C51 会让没有调用的函数参与编译吗?

Small Device C Compiler&#xff08;SDCC&#xff09;是一款免费 C 编译器&#xff0c;适用于 8 位微控制器。 不想看测试过程的话可以直接划到最下面看结论&#xff1a;&#xff09; 关于软硬件环境的信息&#xff1a; Windows 10STC89C52RCSDCC &#xff08;构建HEX文件&…...

OpenCV只含基本图像模块编译

编译OpenCV4.5.5只含基本图像模块&#xff0c;环境为Windows10 x64CMake3.23.3VS2019。默认编译选项编译得到的OpenCV库往往大几百MB甚至上GB&#xff0c;本文配置下编译得到的库压缩后得到的zip包大小仅6.25MB&#xff0c;适合使用OpenCV基本图像功能模块的项目移植而不牵涉其…...

Java实现阴历日历表(附带星座)

准备工作 1.无敌外挂(GitHub直达源码) Nobb 直击灵魂 https://github.com/xuyishanBD/Java_create_calendar.git2.maven配置(如果没有走上面的捷径) <dependencies><dependency><groupId>net.sourceforge.javacsv</groupId><artifactId>javac…...

Python入门之最基础

Python入门之最基础 IDLE有两种模式&#xff0c;一种是交互模式&#xff0c;通俗讲就是写一个代码&#xff0c;会得到相应的反馈&#xff0c;另一种为编辑模式. 注意事项&#xff1a; 标点符号一定要用英文符号 要注意缩进 dir(builtins)可以看到python所有的内置函数&#…...

浏览器缓存策略

先走强缓存&#xff0c;再走协商缓存 强缓存 不发送请求&#xff0c;直接使用缓存的内容 状态码200 当前会话没有关闭的话就是走memory cache&#xff0c;否则就是disk cache 由响应头的 Pragma&#xff08;逐渐废弃&#xff0c;优先级最高&#xff09;&#xff0c;catch-…...

高清无码的MP4如何采集?python带你保存~

前言 大家早好、午好、晚好吖 ❤ ~ 又是我,我又来采集小姐姐啦~ 这次我们采集的网站是(看下图): 本文所有模块\环境\源码\教程皆可点击文章下方名片获取此处跳转 话不多少,我们赶快开始吧~ 第三方模块: requests >>> pip install requests 如果安装python第三方模块…...

python+pytest接口自动化(1)-接口测试基础

接口定义一般我们所说的接口即API&#xff0c;那什么又是API呢&#xff0c;百度给的定义如下&#xff1a;API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;是一些预先定义的接口&#xff08;如函数、HTTP接口&#xff09;&#xff0c;或…...

go单元测试

接着上一篇中的go module创建项目calc为例&#xff0c;在simplemath包中&#xff0c;是使用在命令行中使用交互式的方式进行测试&#xff0c;现在可以为这几个函数实现单元测试&#xff0c; go test&#xff0c;这个测试工具来自于 Go 官方的 gc 工具链。 运行 go test 命令将执…...

Mybatis之一级缓存二级缓存

介绍 缓存&#xff0c;就是将经常访问的数据&#xff0c;放到内存中&#xff0c;减少对数据库的访问&#xff0c;提高查询速度。Mybatis中也有缓存的概念&#xff0c;分为一级缓存和二级缓存。 一级缓存 一级缓存是Mybatis中SqlSession对象的缓存。当我们执行查询以后&#x…...

人脸考勤机项目

文章内容如下&#xff1a; 1&#xff09;项目简介 2&#xff09;开发环境和使用的技术知识 3&#xff09;功能实现 4&#xff09;项目源码 一。项目简介 此项目是基于HOG和Dlib开发的一套实时无感考勤系统。首先是待考勤人员的个人信息录入。然后在过道或者入口处装置人脸…...

Python编程自动化办公案例(3)

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.前几章代码 1.获取到第一题的选项单元格 2.实现批量获取文件 二. 批…...

Linux-MYSQL 登录数据库(命令行,图形化) 及 远程登录

命令行登录 &#xff1a;mysql 命令登录数据库语法 &#xff1a; mysql -u用户名 -p密码 -h 连接的数据库服务器的ip [-D] 数据库名 -p 端口注 &#xff1a; 上面的 mysql 命令是指的是 客户端的指令 ~&#xff01;&#xff01;-h &#xff1a; 指的就是 连接数据库服务器的 ip…...

electron网络环境在线/离线事件探测

electron判断网络环境问题&#xff0c;可以说在任何桌面应用都可以使用到&#xff0c;处理方式有很多种&#xff0c;我介绍几种办法第一种HTML5 API navigator.onLine&#xff1a;官方案例给的&#xff0c;这边为直接贴出地址了&#xff0c;有兴趣的同学可自行查看https://www.…...

UE 项目导航数据生成配置

WP构建及常规构建操作WP构建方式 &#xff1a;https://docs.unrealengine.com/5.0/zh-CN/world-partitioned-navigation-mesh/常规构建方式针对WP的构建方式特殊配置项关闭就好&#xff1a;取消勾选RecastNavMesh-XXX下的IsWorldPartitioned执行n.bNavMeshAllowPartitionedBuil…...

494.目标和

1. 回溯算法 这题和之前做的那些排列、组合的回溯稍微有些不同&#xff0c;你不需要每次选数据时都是for遍历去选择&#xff0c;很明显这是顺序选择的 比如 数组[0,1]&#xff0c;target1&#xff1b; 递归数组&#xff0c;每个元素都 或者 - &#xff0c;然后取最后结果为0…...

滑台模组的应用有哪些?

在自动化生产中&#xff0c;我们常常会看到滑台模组的身影&#xff0c;那么&#xff0c;滑台模组究竟在自动化生产设备中起着怎样的作用呢&#xff1f; 简单点说&#xff0c;滑台模组由滑块、滚珠丝杆、导轨、主体等其它传动零件组成的自动化晋级单元&#xff0c;经过各单元的组…...

CS224W课程学习笔记(四):node2vec算法原理与说明

引言 什么是图嵌入&#xff1f; 我想从上节的deepwalk中已经有一个十分完整的轮廓了&#xff0c;这里引出deepwalk论文中的一张很形象的图&#xff08;当然&#xff0c;上节的一些实战演练&#xff0c;也将这种嵌入关系进行了模拟与可视化&#xff0c;前文为&#xff1a;&…...

扩展lucas定理

前置知识&#xff1a; lucas定理中国剩余定理 介绍 当正整数n,mn,mn,m很大&#xff0c;且质数ppp较小的时候&#xff0c;要求CnmC_n^mCnm​对ppp取模后的值&#xff0c;可以用lucas定理。 但如果ppp不是质数&#xff0c;那该怎么办呢&#xff1f;如果mmm较小&#xff0c;则…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...