JavaScript高级 —— 学习(一)

目录

一、作用域

(一)局部作用域

1.函数作用域

2.块作用域

(二)全局作用域

二、垃圾回收机制 GC

(一)生命周期

1.内存分配

2.内存使用

3.内存回收

4.特殊情况——内存泄漏:

注意:

(二)算法说明

1.堆栈空间分配区别

2.常见的浏览器垃圾回收算法

引用计数法(基本不咋用)

标记清除法

三、闭包

(一)闭包简介

(二)闭包的基本格式

(三)闭包应用——实现函数的私有

四、变量提升

五、函数进阶

(一)函数提升

(二)函数参数

1.动态参数

2.剩余参数

 展开运算符

求最大值

合并数组

(三)箭头函数

1.箭头函数介绍

2.基本语法

2.箭头函数参数

2.箭头函数 this

六、解构赋值

(一)数组解构

 特殊情况

1.变量多单元值少

2.变量少单元值多

3.利用剩余参数解决 2

 4.防止 undefined 传递

 5.按需导入忽略某些值

 6.支持多维数组的解构

(二)对象解构(特别重要)

1.对象解构语法

2.对象解构改名

3.简单数组对象解构

4.多级对象解构

遍历数组 forEach 方法 (重点)

筛选函数 filter 方法(重点)

练习: 对象解构在函数中的用处


一、作用域

(一)局部作用域

作用域链的本质是:底层的变量查找机制

函数被执行时,优先查找当前函数作用域,如果找不到再层层往父亲层次查找,直到全局作用域

嵌套关系的作用域串联起来形成了作用域链

而且父亲不能访问孩子

1.函数作用域

函数内部声明的变量,外部无法访问,函数执行完毕内部的变量被清空了

2.块作用域

在 JavaScript 中被 { } 包围的代码被称为代码块,在代码块内部被声明的变量有可能无法被访问

用 let 和 const 声明会产生块作用域,外面无法访问

var 定义的变量不会产生块级作用域,外面可以访问

(二)全局作用域

<script> 标签 和 .js 文件的最外层,就是全局作用域,在其中声明的变量在其他作用域也可被访问

window 对象添加的属性默认也是全局的,不推荐

函数中没用关键字声明的 也默认为全局变量,不推荐

尽量少的减少全局变量,防止污染。

二、垃圾回收机制 GC

js 中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回回收器自动回收

(一)生命周期

js 环境中分配的内存,一般的生命周期:

1.内存分配

声明变量函数对象时,系统自动分配内存

2.内存使用

读写内存,使用变量函数等

3.内存回收

使用完毕,由垃圾回收器自动回收不再使用的内存

4.特殊情况——内存泄漏:

程序中的内存由于某种原因未释放,或无法释放

注意:

全局变量一般不回收,关闭页面时回收

局部变量的值,不用了会被自动回收

(二)算法说明

1.堆栈空间分配区别

1、栈:操作系统自动分配释放函数的参数值,局部变量等,基本数据类型放到栈里面。

2、堆:由程序员分配释放,如果程序员不释放,就由垃圾回收机制回收,复杂数据类型放到堆里面。

2.常见的浏览器垃圾回收算法
引用计数法(基本不咋用)

定义内存不再使用的对象,看对象是否有指向它的引用,如果没有引用了就回收对象。

但是如果两个对象相会被引用 就无法回收了,因为一直使用这两个对象

算法:

记录被引用的次数

被引用就次数加 1 多次就累加

如果减少就减 1 --

引用次数为 0 就释放内存

标记清除法

定义无法到达的对象,从根部定期扫描对象,就是全局变量找不到的对象,就需要被回收。解决了上一个算法的问题

三、闭包

(一)闭包简介

一个函数堆周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域

内存函数加外层函数的变量就是闭包,就是里层函数使用外层函数的变量

<body><script>function outer() {const a = 1function f() {console.log(a)}f()}</script>
</body>

(二)闭包的基本格式

外部的函数调用了函数内部的变量,最后本质是用 fun() 调用了 fn 函数

<body><script>function outer() {const i = 1function fn() {console.log(i)}return fn}const fun =outer()fun()</script>
</body>

(三)闭包应用——实现函数的私有

比如统计函数被调用的次数,调用就次数加一

不能使用全局变量 容易被修改 所以可以用闭包进行封装

在外面改变 i 的值不会影响 结果的计算 因为 i 是局部作用域 在外面无法改变

而且 i 局部变量不会被回收 这是很巧妙的地方,外面定义了个全局作用域 result 一直在调用

count(),这样函数不结束被调用就不会被销毁,就能一直加加 i

这也属于内存泄露的一种情况

<body><script>function count() {let i = 0function fn() {i++console.log(i)}return fn}const result = count()</script>
</body>

四、变量提升

es6 引入了块级作用域,let const 就更方便了

允许变量被声明前被访问 只有 var 变量存在

在代码执行前,会检测所有 var 变量 然后提到当前作用域的最前面进行定义

下面这段代码不会报错,按理来说会报错的,因为代码按顺寻执行,但是因为 var 变量 变量提升,所以定义了 var 类型的变量 num 但是赋值不会提升,所以输出 undefined

只提升声明 不提升赋值

<body><script>console.log(num)var num = 10</script>
</body>

五、函数进阶

(一)函数提升

代码执行前也会 把所有函数声明提到当前作用域的最前面

<body><script>fn()function fn(){console.log('函数提升')}</script>
</body>

 只提升函数声明不提升函数调用,调用还是按顺序执行的

下面这种情况会报错注意,因为下面 var 变量提升 但是只提升定义不提升赋值

就相当于

var fn

fn()

fn = function()

fn 被调用时不是个函数,所以会报错

<body><script>fn()var fn = function (){console.log('函数提升')}</script>
</body>

(二)函数参数

1.动态参数

不知道实参的数量时 就可以用动态参数

arguments 函数内部内置的伪数组变量,包含了调用函数时传入的所有实参

只存在于函数内部,是动态的,实参有几个,伪数组里面就有几个

<body><script>function getSum(){console.log(arguments)}getSum(2, 3, 1)</script>
</body>

 将 arguments 伪数组里面的元素求和

<body><script>function getSum() {let sum = 0for (let i = 0; i < arguments.length; i++) {sum += arguments[i]}console.log(sum)}getSum(2, 3, 1)</script>
</body>
2.剩余参数

剩余参数也能完成上面的任务,不知道实参的数量,它是个真数组,可以用 push pop 方法

剩余参数允许我们将一个不定数量的参数表示为一个数组,它是把剩余的参数变成一个数组

用法差不多,实际开发中提倡使用 剩余参数

下面的例子中,先把 2 传到 参数 1 然后把 3 传给参数 b 最后把1, 5 ,9 单独封装成一个数

组,剩余参数的名字就是这么来的,就是被剩下的参数

<body><script>function getSum(a, b, ...arr) {console.log(arr)}getSum(2, 3, 1, 5, 9)</script>
</body>
 展开运算符

... 三个点,如果不用在 函数参数中,就是起到展开数组的作用

最大的用处就是 求数组最大值,合并数组等

<body><script>const arr = [1, 2, 3]console.log(...arr)</script>
</body>
求最大值

...能把数组变成字符串的形式

<body><script>const arr = [1, 2, 3]console.log(Math.max(...arr))</script>
</body>
合并数组
<body><script>const arr1 = [1, 2, 3]const arr2 = [2, 3, 4]const arr = [...arr1, ...arr2]console.log(arr)</script>
</body>

(三)箭头函数

1.箭头函数介绍

引入箭头函数的目的是让函数书写更简短,而且不绑定 this 箭头函数比函数表达式更简洁,

主要用于本来需要使用匿名函数的地方

2.基本语法

两种函数新旧对比,参数就正常写在小括号中

<body><script>// 旧版函数写法const fn = function(){console.log(123)}// 新版箭头函数写法const fn1 = () => {console.log(123)}</script>
</body>

如果参数参数只有一个,小括号可以省略

<body><script>const fn = x => {console.log(x)}fn(1)</script>
</body>

只有一行代码时可以省略大括号

<body><script>const fn = x => console.log(x)fn(1)</script>
</body>

箭头函数能直接返回一个对象,因为后面大括号和对象的大括号冲突了,所以用小括号包住

<body><script>const fn = (uname) => ({ uname: uname })fn('一个人')</script>
</body>
2.箭头函数参数

箭头函数没有 arguments 动态参数,但是有剩余参数 ...args

<body><script>const getSum = (...arr) => {let sum = 0for (let i = 0; i < arr.length; i++) {sum += arr[i]}return sum}console.log(getSum(2, 3))</script>
</body>
2.箭头函数 this

函数外面的 this 指向 window 默认是 window

dom 回调函数中还是不推荐使用 箭头函数

this 之前的定义是 this 指向函数的调用者

这里的 this 指向对象 obj

<body><script>const obj = {uname: '一个人',say: function () {console.log(this)}}obj.say()</script>
</body>

箭头函数的 this 指向箭头函数的上一级作用域链

下面代码都指向 window

<body><script>const fn = () => {console.log(this)}</script>
</body>
​<body><script>const obj = {uname: '一个人',say: function () {console.log(this)}}obj.say()</script>
</body>​

六、解构赋值

(一)数组解构

是将数组的单元值快速批量的赋值给一系列变量的简洁语法,就是把数组元素赋给变量,能分别得到三个变量

<body><script>const arr = [100, 60, 80]const [max, min, avg] = arrconsole.log(max)</script>
</body>

 例子如下:数组解构时一定要在数组的前面加上分号,同理立即执行函数,要不然数组前面的数字就会连上数组 ,变成2 [b, a] = [a, b] 从而报错

<body><script>let a = 1let b = 2;[b, a] = [a, b]console.log(a, b)  </script>
</body>
 特殊情况
1.变量多单元值少

如下代码,变量有a,b,c ,d 四个变量,但是只有1,2,3 三个单元值,abc 分别被赋值123,d的值为 undefined 很像前面的变量的赋值。

<body><script>const [a,b,c,d] = [1,2,3]</script>
</body>
2.变量少单元值多

多余的单元值就不进行赋值了

3.利用剩余参数解决 2

利用 ... 展开运算符来存其余的数值

<body><script>const [a,b,...c]= [1,2,3,4]</script>
</body>
 4.防止 undefined 传递

设置一个默认参数就能解决

<body><script>const [a = 0,b = 0]= [1,2]</script>
</body>
 5.按需导入忽略某些值

如下面例子 就忽略了 后面的值 3

<body><script>const [a,b, ,d]= [1,2,3,4]</script>
</body>
 6.支持多维数组的解构

下面成功帮助多维数组解构了

<body><script>const [a, b, [c,d]] =  [1, 2, [3, 4]]</script>
</body>

(二)对象解构(特别重要)

将对象属性和方法快速批量赋值给一系列变量的简洁语法

1.对象解构语法

注意:必须等号左右两边的属性名和变量名必须相同,而且之前不能起和对象内部属性相同的变量名,要不然就会 undefined。

下面的例子和数组结构的方法类似

<body><script>const { uname, age } = {uname: '一个人',age: 18}console.log(uname)</script>
</body>
2.对象解构改名

对象解构的变量名可以改名,但是语法很特殊,新改的名字写在后面。

<body><script>const { uname: name, age } = {uname: '一个人',age: 18}console.log(name)</script>
</body>
3.简单数组对象解构
<body><script>const arr = [{uname: '一个人',age: 18}]const [{uname, age}] = arrconsole.log(uname)</script>
</body>
4.多级对象解构

就如下形式书写即可,数组对象同理

<body><script>const pig = {name: '佩奇',family:{mother: '猪妈妈',father: '猪爸爸',sister: '乔治'}}const {name, family:{mother, father,sister}} = pigconsole.log(mother)</script>
</body>

遍历数组 forEach 方法 (重点)

和 map 遍历类似 但是 map 最后返回一个数组 forEach 只进行遍历不返回数组,可以看作加强版的 for 循环

语法:被遍历的数组.forEach(function (当前数组元素,当前元素索引号)){

函数体

}

当前数组元素就是数组里面的值,会依次遍历输出出来,index 是每个元素的下标,下标可以省略

<body><script>const arr = ['red', 'green', 'pink']const result = arr.forEach(function (item, index) {console.log(item)console.log(index)})</script>
</body>

筛选函数 filter 方法(重点)

filter() 方法是创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,用于筛选数组中符合条件的元素,并返回筛选后的数组。

<body><script>const arr = [10, 20, 30]const newArr = arr.filter(item => item >= 20)console.log(newArr)</script>
</body>

练习: 对象解构在函数中的用处

结果展示:

 代码部分:
 

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>const msg = {"code": 200,"msg": "获取新闻列表成功","data": [{"id": 1,"title": "5G商用自己,三大运营商收入下降","count": 58},{"id": 2,"title": "5G商用自己,三大运营商收入下降","count": 56},{"id": 3,"title": "5G商用自己,三大运营商收入下降","count": 1669}]}function jie({ data: myData }) {console.log(myData)}jie(msg)</script>
</body></html>

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

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

相关文章

Manjaro 安装全新 Linux 版微信,从此告别 Wine

目前已经基本上使用 Manjaro 来工作&#xff0c;而工作离不开微信作为日常的工作沟通工具。因为微信官方一直没有 Linux 版本的&#xff0c;所以之前都只能够使用 Wine 版本&#xff0c;然后踩了不少坑&#xff0c;但还算能勉强使用。 最近听说微信终于要发布 Linux 版本的&am…

Linux之冯诺依曼体系,操作系统,进程的理解,进程状态,以及进程的优先级

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 算法 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.冯诺依曼体系 二.操作系统 2.1概念 2.2结构示意图&…

基于Axios封装请求---防止接口重复请求解决方案

一、引言 前端接口防止重复请求的实现方案主要基于以下几个原因&#xff1a; 用户体验&#xff1a;重复发送请求可能导致页面长时间无响应或加载缓慢&#xff0c;从而影响用户的体验。特别是在网络不稳定或请求处理时间较长的情况下&#xff0c;这个问题尤为突出。 服务器压力…

树状数组与线段树基础3

本来想练练线段树的&#xff0c;没想到有许多细节忘了&#xff0c;加上今天的金工实习坐牢坐穿了&#xff0c;于是再复习一下吧。 首先介绍一下树状数组&#xff08;貌似第一篇就讲了&#xff0c;不过那个东西真是一坨Shit,当时还没有怎么理解就写了&#xff09; 首先它的复杂…

知识图谱与大数据:区别、联系与应用

目录 前言1 知识图谱1.1 定义1.2 特点1.3 应用 2 大数据2.1 定义2.2 应用 3. 区别与联系3.1 区别3.2 联系 结语 前言 在当今信息爆炸的时代&#xff0c;数据成为了我们生活和工作中不可或缺的资源。知识图谱和大数据是两个关键概念&#xff0c;它们在人工智能、数据科学和信息…

30-3 越权漏洞 - 水平越权(横向越权)

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、定义 攻击者可以访问和操作与其拥有同级权限的用户资源。 示例: 学生A在教务系统上正常只能修改自己的作业内容,但由于不合理的权限校验规则等原因,学生A可以修改学生B的内…

【python】flask执行上下文context,请求上下文和应用上下文原理解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【Java - 框架 - Lombok】(2) SpringBoot整合Lombok完成日志的创建使用 - 快速上手;

"SpringBoot"整合"Lombok"完成日志的创建使用 - 快速上手&#xff1b; 环境 “Java"版本"1.8.0_202”&#xff1b;“Lombok"版本"1.18.20”&#xff1b;“Spring Boot"版本"2.5.9”&#xff1b;“Windows 11 专业版_22621…

厨余垃圾处理设备工业监控PLC连接APP小程序智能软硬件开发之功能原理篇

接着上一篇《厨余垃圾处理设备工业监控PLC连接APP小程序智能软硬件开发之功能结构篇》继续总结一下厨余垃圾处理设备智能软硬件统的原理。所有的软硬件系统全是自己一人独自开发&#xff0c;看法和角度难免有局限性。希望抛砖引玉&#xff0c;将该智能软硬件系统分享给更多有类…

Web APIs

文章目录 Web APIs1. DOM1.1 介绍DOM 树DOM 节点document 1.2 获取DOM对象1.3 操作元素内容1.4 操作元素属性常用属性修改控制样式属性操作表单元素属性自定义属性 1.5 间歇函数1.6 事件事件监听事件类型事件处理程序 1.7 事件类型鼠标事件键盘事件焦点事件文本框输入事件 1.8 …

数据分析之Power BI

POWER QUERY 获取清洗 POWER PIVOT建模分析 如何加载power pivot 文件-选项-加载项-com加载项-转到 POWER VIEW 可视呈现 如何加载power view 文件-选项-自定义功能区-不在功能区中的命令-新建组-power view-添加-确定 POWER MAP可视地图

vue3-pinia使用(末尾有彩蛋)

什么是 pinia Pinia 是 Vue 的专属状态管理库&#xff0c;它允许你跨组件或页面共享状态。 之前用的是 vuex&#xff0c;后面 vue 官方团队不维护了&#xff0c;推荐使用 pinia 安装 yarn add pinia # 或者使用 npm npm install piniapnpm install piniaStore 是什么&#xf…

AIGC-Stable Diffusion发展及原理总结

目录 一. AIGC介绍 1. 介绍 2. AIGC商业化方向 3. AIGC是技术集合 4. AIGC发展三要素 4.1 数据 4.2 算力 4.3 算法 4.3.1 多模态模型CLIP 4.3.2 图像生成模型 二. Stable Diffusion 稳定扩散模型 1. 介绍 1.1 文生图功能&#xff08;Txt2Img) 1.2 图生图功能&…

八大技术趋势案例(区块链量子计算)

科技巨变,未来已来,八大技术趋势引领数字化时代。信息技术的迅猛发展,深刻改变了我们的生活、工作和生产方式。人工智能、物联网、云计算、大数据、虚拟现实、增强现实、区块链、量子计算等新兴技术在各行各业得到广泛应用,为各个领域带来了新的活力和变革。 为了更好地了解…

C语言中如何动态分配内存并进行操作

C语言文章更新目录 C语言学习资源汇总&#xff0c;史上最全面总结&#xff0c;没有之一 C/C学习资源&#xff08;百度云盘链接&#xff09; 计算机二级资料&#xff08;过级专用&#xff09; C语言学习路线&#xff08;从入门到实战&#xff09; 编写C语言程序的7个步骤和编程…

设计模式之单例模式精讲

UML图&#xff1a; 静态私有变量&#xff08;即常量&#xff09;保存单例对象&#xff0c;防止使用过程中重新赋值&#xff0c;破坏单例。私有化构造方法&#xff0c;防止外部创建新的对象&#xff0c;破坏单例。静态公共getInstance方法&#xff0c;作为唯一获取单例对象的入口…

港大新工作 HiGPT:一个模型,任意关系类型 !

论文标题&#xff1a; HiGPT: Heterogeneous Graph Language Model 论文链接&#xff1a; https://arxiv.org/abs/2402.16024 代码链接&#xff1a; https://github.com/HKUDS/HiGPT 项目网站&#xff1a; https://higpt-hku.github.io/ 1. 导读 异质图在各种领域&#xf…

Polar靶场web(三)

期待得到某一件事物的时候&#xff0c;才是最美好的。 签到 发现不能提交&#xff0c;看一下f12 发现提交按钮被禁用了&#xff0c;且最大输入9个字符&#xff0c;我们可以改一下。 现随便提交一个发现要提交ilovejijcxy session文件包含 发现有文件包含&#xff0c;那先包含…

基于单片机的便携式瓦斯检测仪系统设计

**单片机设计介绍&#xff0c;基于单片机的便携式瓦斯检测仪系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的便携式瓦斯检测仪系统设计是一个针对煤矿等工业环境中瓦斯气体浓度检测的重要项目。以下是该设计…

智慧城市一屏统览,数字孪生综合治理

现代城市作为一个复杂系统&#xff0c;牵一发而动全身&#xff0c;城市化进程中产生新的矛盾和社会问题都会影响整个城市系统的正常运转。智慧城市是应对这些问题的策略之一。城市工作要树立系统思维&#xff0c;从构成城市诸多要素、结构、功能等方面入手&#xff0c;系统推进…