JavaScript 学习笔记(JS进阶 Day4)

「写在前面」

本文为 b 站黑马程序员 pink 老师 JavaScript 教程的学习笔记。本着自己学习、分享他人的态度,分享学习笔记,希望能对大家有所帮助。推荐先按顺序阅读往期内容:
1. JavaScript 学习笔记(Day1)
2. JavaScript 学习笔记(Day2)
3. JavaScript 学习笔记(Day3)
4. JavaScript 学习笔记(Day4)
5. JavaScript 学习笔记(Day5)
6. JavaScript 学习笔记(WEB APIs Day1)
7. JavaScript 学习笔记(WEB APIs Day2)
8. JavaScript 学习笔记(WEB APIs Day3)
9. JavaScript 学习笔记(WEB APIs Day4)
10. JavaScript 学习笔记(WEB APIs Day5)
11. JavaScript 学习笔记(WEB APIs Day6)
12. JavaScript 学习笔记(JS进阶 Day1)
13. JavaScript 学习笔记(JS进阶 Day2)
14. JavaScript 学习笔记(JS进阶 Day3)


目录

  • 1 深浅拷贝
  • 2 异常处理
  • 3 处理this
  • 4 性能优化
  • 5 综合案例
  • 6 完结撒花

1 深浅拷贝

1.1 浅拷贝

P188:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=188

首先浅拷贝和深拷贝只针对引用类型

浅拷贝:拷贝的是地址

常见方法:

  1. 拷贝对象: Object.assgin() / 展开运算符 {...obj} 拷贝对象
  2. 拷贝数组: Array.prototype.concat() 或者 [...arr]
const obj = {
uname: 'pink'
}
const o = { ...obj }
console.log(o) // {uname: 'pink'}
o.uname = 'red'
console.log(o) // {uname : 'red'}
console.log(obj) // {uname: 'pink' }

如果是简单数据类型拷贝值,引用数据类型拷贝的是地址 (简单理解: 如果是单层对象,没问题,如果有多层就有问题)

// 一个pink对象
const pink = {
name: 'pink老师',
age: 18,
famliy: {
mother: 'pink妈妈'
}
}
const red = {}
object.assign(red, pink)
console.log(red) // {name: 'pink老师', age: 18}
red.name = 'red老师'
// 更改对象里面的 family 还是会有影响
red.famliy.mother = 'red妈妈'
consoie.log(red) // {name: 'red老师', age: 18}
// 不会影响pink对象
console.log(pink) // {name: 'pink老师', age: 18}

1.2 深拷贝

P189:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=189

首先浅拷贝和深拷贝只针对引用类型

深拷贝:拷贝的是对象,不是地址

常见方法:

  1. 通过递归实现深拷贝
  2. lodash/cloneDeep
  3. 通过JSON.stringify()实现

1. 通过递归实现深拷贝

函数递归:

如果一个函数在内部可以调用其本身,那么这个函数就是递归函数

  • 简单理解:函数内部自己调用自己, 这个函数就是递归函数
  • 递归函数的作用和循环效果类似
  • 由于递归很容易发生“栈溢出”错误(stack overflow),所以 必须要加退出条件 return
let num = 1
// fn就是递归函数
function fn() {
console.log('我要打印6次')
if (num >= 6) {
return
}
num++
fn() // 函数内部调用函数自己
}
fn()

P190:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=190

通过递归函数实现深拷贝:

const o = {}
function deepCopy(newObj, oldObj) {
for (let k in old0bj) {
if (oldObj[k] instanceof Array) {
new0bj[k] = []
deepCopy(newObj[k], oldObj[k])
} else if (oldObj[k] instanceof Object) {
newObj[k]= {}
deepCopy(newObj[k], oldObj[k])
}
else {
newObj[k] = old0bj[k]}
}
}
}

2. js库lodash里面cloneDeep内部实现了深拷贝

P191:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=191

const obj = {
uname: 'pink',
age: 18,
hobby: ['篮球', '足球'],
family: {
baby: '小pink'
}
}
// 语法: _.cLoneDeep(要被克隆的对象)
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'
}
}
const o = JSON.parse(JSON.stringify(obj))
console.log(o)
o.family.baby = '老pink'
console.log(obj)

2 异常处理

2.1 throw 抛异常

P192:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=192

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

  1. throw 抛出异常信息,程序也会终止执行
  2. throw 后面跟的是错误提示信息
  3. Error 对象配合 throw 使用,能够设置更详细的错误信息
function counter(x, y) {
if (!x || !y) {
throw new Error('参数不能为空!”
}
return X + y
}
counter()

2.2 try /catch 捕获异常

我们可以通过try / catch 捕获错误信息(浏览器提供的错误信息) try 试试 catch 拦住 finally 最后

  1. try...catch 用于捕获错误信息
  2. 将预估可能发生错误的代码写在 try 代码段中
  3. 如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息
  4. finally 不管是否有错误,都会执行
<p>123</p>
<script>
function fn() {
try {
// 可能发送错误的代码要写到 try
const p = document.querySelector('.p')
p.style.color = 'red'
} catch (err) {
// 拦截错误,提示浏览器提供的错误信息,但是不中断程序的执行
console.log(err.message)
throw new Error('你看看,选择器错误了吧')
// 需要加return中断程序
// return
}
finally {
// 不管你程序对不对,一定会执行的代码
alert('弹出对话框')
}
console.log(11)
}
fn()
</script>

2.3 debugger

debugger 相当于打断点

alt

3 处理this

3.1 this指向

P193:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=193

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

alt

普通函数没有明确调用者时 this 值为 window,严格模式下没有调用者时 this 的值为 undefined

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

  1. 箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的
  2. 箭头函数中的this引用的就是最近作用域中的this
  3. 向外层作用域中,一层一层查找this,直到有this的定义
alt

注意情况1:

在开发中【使用箭头函数前需要考虑函数中 this 的值】,事件回调函数使用箭头函数时,this 为全局的 window

因此DOM事件回调函数如果里面需要DOM对象的this,则不推荐使用箭头函数

alt

注意情况2:

同样由于箭头函数 this 的原因,基于原型的面向对象也不推荐采用箭头函数

alt

3.2 改变this

P194:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=194

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) // windowconsole.log(x +y)
}
// 1.调用函数
// 2. 改变this指向
fn.call(obj, 1, 2)

2. apply()-理解

P195:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=195

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

语法:fun.apply(thisArg, [argsArray])

  • thisArg:在fun函数运行时指定的 this 值
  • argsArray:传递的值,必须包含在数组里面
  • 返回值就是函数的返回值,因为它就是调用函数
  • 因此 apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值
// 求和函数
function counter(x, y) {
return x + y
}
// 调用 counter 函数,并传入参数
let result = counter.apply(null, [5, 10])
console.log(result)

3. bind()-重点

P196:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=196

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()

相同点:

  • 都可以改变函数内部的this指向.

区别点:

  • call 和 apply 会调用函数, 并且改变函数内部this指向.
  • call 和 apply 传递的参数不一样, call 传递参数 aru1, aru2..形式 apply 必须数组形式[arg]
  • bind 不会调用函数, 可以改变函数内部this指向.

主要应用场景:

  • call 调用函数并且可以传递参数
  • apply 经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
  • bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向.

4 性能优化

4.1 防抖

P197:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=197

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

使用场景:

  • 搜索框搜索输入。只需用户最后一次输入完,再发送请求
  • 手机号、邮箱验证输入检测

4.2 防抖

P198:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=198

节流:单位时间内,频繁触发事件,只执行一次

使用场景:

高频事件:鼠标移动mousemove、页面尺寸缩放resize、滚动条滚动scroll等等

5 综合案例

P199:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=199

6 完结撒花

P200:https://www.bilibili.com/video/BV1Y84y1L7Nn?p=200

感谢这段时间奋斗的自己,
让我们这段时间变得有价值。


「结束」
alt

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/653217.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NodeJs环境安装与配置

最近电脑重装了系统&#xff0c;开发环境啥的都得重装&#xff0c;顺便记录下 nodeJs 的安装与配置&#xff0c;方便需要的同学查看&#xff0c;也方便自己以后查找。 安装 下载地址&#xff1a;https://nodejs.cn/download/ 根据需要选择自己环境需要的下载即可&#xff0c;…

【cdh】hive执行SQL提示缺少3.0.0-cdh6.3.2-mr-framework.tar.gz文件

问题&#xff1a;执行SQL报错提示缺少文件 异常信息如下 在hdfs上查看的时候连文件夹都没有&#xff0c;所以这个异常会抛出&#xff0c;但是我是基于CDH搭建的&#xff0c;可以直接基于下面操作 执行完成之后查看HDFS文件 重新执行SQL发现可以正常执行了

web前端项目-实现录音功能【附源码】

录音功能 运行效果&#xff1a;本项目可实现录音软件的录音、存储、播放等功能 HTML源码&#xff1a; &#xff08;1&#xff09;index.html&#xff1a; <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/h…

【BUG】联想Y7000电池电量为0且无法充电解决方案汇总

因为最近火灾很多&#xff0c;所以昨天夜晚睡觉的时候把插线板电源关掉了&#xff0c;电脑也关机了。 各位一定要注意用电安全&#xff0c;网上的那些事情看着真的很难受qvq。 第二天早上起床的时候一看发现电脑直接没电了&#xff0c;插上电源后也是显示 你一定要冲进去啊(ू˃…

springboot外出务工人员信息管理系统源码和论文

网络的广泛应用给生活带来了十分的便利。所以把疫情防控期间某村外出务工人员信息管理与现在网络相结合&#xff0c;利用java技术建设疫情防控期间某村外出务工人员信息管理系统&#xff0c;实现疫情防控期间某村外出务工人员信息的信息化。则对于进一步提高疫情防控期间某村外…

2024阿里云和腾讯云的第一战打响:搭建《幻兽帕鲁》私服游戏

为了搭建《幻兽帕鲁》游戏私服&#xff0c; 2024年阿里云 VS 腾讯云的第一场战争开始了…… 事情是这样的&#xff1a; 1月19日&#xff0c;最离谱新游 《幻兽帕鲁》突然爆火了&#xff0c;这是一款日本开发商展耗费4年开发的冒险类游戏&#xff0c;这款戏一推出就迅速俘获了…

DOM 型 XSS 攻击演示(附链接)

一、介绍 DOM&#xff08;Document Object Model&#xff09;型 XSS&#xff08;Cross-Site Scripting&#xff09;攻击是一种 Web 应用程序中的安全漏洞&#xff0c;其特点是攻击者成功地注入了恶意脚本&#xff0c;这些脚本在用户的浏览器中执行&#xff0c;从而导致恶意行为…

AcWing 895. 最长上升子序列(DP序列模型)

[题目概述] 给定一个长度为 N 的数列&#xff0c;求数值严格单调递增的子序列的长度最长是多少。 输入格式 第一行包含整数 N。 第二行包含 N 个整数&#xff0c;表示完整序列。 输出格式 输出一个整数&#xff0c;表示最大长度。 数据范围 1 ≤ N ≤ 1000 &#xff0c; …

【刷题】 leetcode 面试题 08.05.递归乘法

递归乘法 1 题目描述2 思路一&#xff08;返璞归真版&#xff09;3 思路二&#xff08;二进制乘法器版&#xff09;4 思路三&#xff08;变态版&#xff09;Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读下一篇文章见&#xff01;&#xff01;&#xff01; 1 题目…

不确定优化入门:用简单实例讲明白随机规划、鲁棒优化和分布鲁棒优化

文章目录 1 引言2 学习动机3 经典问题4 解决方案4.1 忽略不确定性4.2 随机规划4.3 鲁棒优化4.4 分布鲁棒优化 5 总结相关阅读 1 引言 按2024的原定计划&#xff0c;今年开始要学习不确定优化了。 粗略翻阅了一些相关的书籍和教程&#xff0c;大都包含许多数学公式&#xff0c…

SpringBoot引入主盘探活定时任务

主盘探活通常是指检查存储设备&#xff08;例如硬盘&#xff09;是否可读写&#xff0c;但在Java中并没有直接针对硬件级别的磁盘探活API。然而&#xff0c;我们可以模拟一个场景&#xff0c;即检查某个目录或文件是否可以被Java程序正常读写&#xff0c;以此作为主盘活跃的一个…

HCIP复习课(bgp实验)

1、ip配置&#xff1a; R1&#xff1a; R2&#xff1a; R9&#xff1a; R10&#xff1a; R11&#xff1a; R3&#xff1a; R4&#xff1a; R5&#xff1a; R6&#xff1a; R7&#xff1a; R8&#xff1a; 2、隧道配置&#xff1a; R2&#xff1a; 静态&#xff1a; R10&am…

第15次修改了可删除可持久保存的前端html备忘录:换了一个容器时钟,匹配背景主题:现代深色

第15次修改了可删除可持久保存的前端html备忘录&#xff1a;换了一个容器时钟&#xff0c;匹配背景主题&#xff1a;现代深色 备忘录代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv&qu…

WSL2 Debian系统添加支持SocketCAN

本人最近在使用WSL2&#xff0c;Linux系统选择的是Debian&#xff0c;用起来很不错&#xff0c;感觉可以代替VMware Player虚拟机。 但是WSL2 Debian默认不支持SocketCAN&#xff0c;这就有点坑了&#xff0c;由于本人经常要使用SocketCAN功能&#xff0c;所以决定让Debian支持…

Axolotl:一款极简的大模型微调(Finetune)开源框架

今天给大家分享一款工具&#xff0c;Axolotl[1] 是一个旨在简化各种AI模型的微调过程的工具&#xff0c;支持多种配置和架构。 特点&#xff1a; 可训练各种 Huggingface 模型&#xff0c;如 llama、pythia、falcon、mpt支持 fullfinetune、lora、qlora、relora 和 gptq使用简…

Maven入门及其使用

目录 一、Maven入门 1.1 初识Maven 1.2 Maven的作用 1.2.1 依赖管理 1.2.2 统一项目结构 1.2.3 项目构建 1.3 Maven坐标 1.4 Maven仓库 1.4.1 Maven仓库概述 二、Maven的下载与安装 2.1 安装步骤 2.1.1 解压安装&#xff08;建议解压到没有中文、特殊字符的路径下。&#xff09…

数据湖技术之应用场景篇

数据湖技术有较多的应用场景&#xff0c;本篇文章是针对一些典型的痛点场景做了一些介绍和说明。比如说在线数据抽取场景原有模式对线上库表产生较大压力&#xff0c;flink多流join维护的大状态导致的稳定性问题等等&#xff0c;具体场景如下图所示&#xff1a; 场景1:在线数据…

车载电子电器架构 —— 多核处理器刷写策略

车载电子电器架构 —— 多核处理器刷写策略 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消…

嵌入式Linux系统引导过程详解

大家好&#xff0c;今天给大家介绍嵌入式Linux系统引导过程详解&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 嵌入式Linux系统引导过程是系统启动的关键环节&#xff0c;它涉及…

代码随想录刷题笔记-Day10

1. 用栈实现队列 232.用栈实现队列https://leetcode.cn/problems/implement-queue-using-stacks/description/ 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xf…