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.mzph.cn/news/789603.shtml

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

相关文章

了解与生成火焰图

目录 一、如何看懂火焰图 1、基本特征 2、基本分类 二、如何生成火焰图 1、捕获调用栈 2、折叠栈 3、转换为 svg 格式 4、展示 svg 一、如何看懂火焰图 1、基本特征 &#xff08;1&#xff09;纵轴&#xff1a;即每一列代表一个调用栈&#xff0c;每一个格子代表一个函…

【跨境商家福音】一款性价比高、好用的跨境选品工具

亚马逊、速卖通、Shopee 、Lazada、美客多、eBay、SHEIN、Temu、Tiktok、shopify等跨境电商平台&#xff0c;其用户消费喜好多样&#xff0c;涵盖服装、美妆、电子产品等多个品类。而店雷达作为一款基于大数据和人工智能技术的电商分析工具&#xff0c;为商家提供了强大的选品和…

宁盾身份域管与Coremail邮件系统完成兼容互认证,持续深化信创布局

在信创国产化改造的背景下&#xff0c;企业邮箱的替换是许多党政、央国企、金融、制造企业面临的重要任务。为了满足企业对国产邮箱、OA等其他应用、终端实现统一身份认证&#xff0c;宁盾国产化身份域管与 Coremail XT 安全增强电子邮件系统 V5.0、V6.0 完成了产品兼容互认证&…

破解密码:掌握2024年的营销归因

Cracking the Code: Mastering Marketing Attribution in 2024 营销归因是识别哪些营销渠道和触及点有助于销售或转化的过程。随着消费者继续通过多个渠道与品牌互动&#xff0c;掌握营销归因对企业来说变得越来越重要。在这篇文章中&#xff0c;我们将探讨破解代码和有效衡量…

游戏运营分析:如何在新游戏上线初期实现精细化运营?

一、背景介绍 在当今的手游市场中&#xff0c;每一款新游戏的发布都如同踏上一段充满未知与挑战的探险之旅。游戏刚上线时&#xff0c;运营情况往往如同飘摇的小船&#xff0c;随时可能受到风浪的侵袭。此时&#xff0c;如何准确地找到问题所在&#xff0c;为游戏的健康运营和持…

【Python项目】AI动物识别工具

目录 背景 技术简介 系统简介 界面预览 背景 成像技术在全球科技发展中扮演了关键角色。在科学研究领域&#xff0c;拍摄所得的图像成为了一种不可或缺的研究工具。特别是在生态学与动物学研究中&#xff0c;鉴于地球的广阔地域和多样的气候条件&#xff0c;利用图像技术捕…

【Qt 学习笔记】输入框实现helloworld | QLineEdit的使用

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 输入框实现helloworld | QLineEdit的使用 文章编号&#xff1a;Qt 学习…

pytest接口自动化框架实际应用

一、自动化实现的目标 1、测试用例数据驱动。 2、测试数据和用例分离。 3、每个测试用例拥有专属的测试数据有明确的测试初始状 4、测试用例的执行不依赖其他测试用例执行所产生的数据 5、建立体系化测试数据&#xff0c;进行数据依赖管理&#xff0c;覆盖全部测试分层策略要求…

PCB的电气/物理特性检查项目需思考的问题

在PCB设计、制造和装配过程中&#xff0c;为确保产品性能和质量&#xff0c;电子工程师必须进行电气特性和物理特性检查&#xff0c;然而对很多新人来说如何高效进行检查是个难题&#xff0c;所以下面将分别探讨这些检查时需要考虑的问题。 1、PCB电气特性检查项目①导线参数分…

CLIP 图文检索,相似度计算

CLIP 是OpenAI提出的神经网络&#xff0c;它可以从自然语言监督中有效地学习视觉概念。 CLIP 可以应用于任何视觉分类基准&#xff0c;只需提供要识别的视觉类别的名称&#xff0c;类似于 GPT-2 和 GPT-3 的“零样本”功能。 相关paper 用法可以参考github 这里举几个使用CLI…

CTK插件框架学习-信号槽(05)

CTK插件框架学习-事件监听(04)https://mp.csdn.net/mp_blog/creation/editor/137171155 一、主要流程 信号发送者告诉服务要发送的信号信号发送者发送信号信号接收者告诉服务当触发某个订阅的主题时通知槽函数信号接收者处理槽函数信号槽参数类型必须为&#xff08;const ctk…

[RK3588-Android12] 调试MIPI-双通道-压缩屏(Video Mode/MIPI Dphy 8Lane/DSC 144HZ)

问题描述 被测屏幕&#xff1a;小米Pad6 分辨率&#xff1a;1800X2880 模式&#xff1a;Video Mode/MIPI Dphy 8Lane/DSC 144HZ PPS: 11 00 00 89 30 80 0B 40 03 84 00 14 01 C2 01 C2 02 00 01 F4 00 20 01 AB 00 06 00 0D 05 7A 06 1A 18 00 10 F0 03 0C 20 00 06 0B 0B 33…

linux进程退出之exit与_exit

linux进程退出之exit与_exit _exitexit流程清理函数atexit()函数&#xff1a;on_exit()函数&#xff1a; _exit /* Terminate program execution with the low-order 8 bits of STATUS. */ /** status参数定义了进程的终止状态&#xff0c;父进程可以通过wait&#xff08;&am…

腾讯云邮件推送功能有哪些?如何有效使用?

腾讯云邮件推送如何设置&#xff1f;怎么用邮件推送做高效营销&#xff1f; 腾讯云作为业界领先的云服务提供商&#xff0c;其邮件推送功能在便捷性、稳定性和安全性上都有着出色的表现。那么&#xff0c;腾讯云邮件推送功能究竟有哪些呢&#xff1f;让AokSend来探个究竟。 腾…

基于SpringBoot+微信小程序的图书借阅管理系统(包运行调试)

介绍 系统介绍 是一套图书借阅管理系统&#xff0c;包括用户小程序以及后台管理系统。 前台商城系统包含用户注册登录、首页门户、图书查询、在线借阅、个人中心、我的信息、我的借阅、押金充值。 后台管理系统包含统计分析、用户管理、分类管理、图书管理、借阅管理、管理员…

HarmonyOS NEXT应用开发之@Observed装饰器和\@ObjectLink装饰器:嵌套类对象属性变化

上文所述的装饰器仅能观察到第一层的变化&#xff0c;但是在实际应用开发中&#xff0c;应用会根据开发需要&#xff0c;封装自己的数据模型。对于多层嵌套的情况&#xff0c;比如二维数组&#xff0c;或者数组项class&#xff0c;或者class的属性是class&#xff0c;他们的第二…

教育信创 | 云轴科技ZStack联合飞腾发布全场景教育信创白皮书

随着数字化时代的到来&#xff0c;教育行业正面临着前所未有的挑战与机遇。为了推动教育行业的数字化转型和信创人才培养&#xff0c;云轴科技ZStack联合飞腾于3月28日正式发布了《教育行业数字化自主创新飞腾生态解决方案白皮书》&#xff08;简称《教育白皮书》&#xff09;。…

新能源汽车充电桩主板产业链解析

新能源汽车充电桩主控制板&#xff0c;简称汽车充电桩主板&#xff0c;是充电桩设施的核心部件&#xff0c;主要负责控制充电桩的整体运行和管理充电过程。了解汽车充电桩主板的整体产业链是非常重要的&#xff0c;这可以帮助您更好地了解供应链、采购渠道以及行业发展趋势。 产…

抓住信号如此简单,WeTrade一个指标1分钟轻松解决

在交易中是不是有这样的困惑&#xff0c;没有清晰的计算逻辑还抓不住交易的信号&#xff0c;这样的投资者有福了&#xff0c;今天WeTrade众汇分享一个指标1分钟轻松解决这个困惑。 ROC全称Rate of Change&#xff0c;中文名为变动速度指标或变动率指标&#xff0c;它以百分比的…

Java就近原则和this关键字

Java 中的就近原则和 this 关键字有着密切的关系&#xff0c;特别是在处理成员变量与方法参数同名的情况下。就近原则指的是在同一作用域下&#xff0c;优先使用最近声明的变量或参数。 在 Java 中&#xff0c;如果一个方法的参数与类的成员变量同名&#xff0c;为了明确指示要…