JavaScript高级 —— 学习(一)

news2024/12/23 10:40:08

目录

一、作用域

(一)局部作用域

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 = 1
      function f() {
        console.log(a)
      }
      f()
    }
  </script>
</body>

(二)闭包的基本格式

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

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

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

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

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

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

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

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

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

<body>
  <script>
    function count() {
      let i = 0
      function 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 = 0
      for (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 = 0
      for (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] = arr
    console.log(max)
  </script>
</body>

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

<body>
  <script>
    let a = 1
    let 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}] = arr
   console.log(uname)
  </script>
</body>
4.多级对象解构

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

<body>
  <script>
   const pig = {
    name: '佩奇',
    family:{
      mother: '猪妈妈',
      father: '猪爸爸',
      sister: '乔治'
    }
   }
   const {name, family:{mother, father,sister}} = pig
   console.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.coloradmin.cn/o/1553647.html

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

相关文章

【MySQL】数据库--表操作

目录 一、创建表 二、查看表 三、修改表 1. 添加字段--add 2.修改表名--rename to 3.修改列名--change 4.修改字段的数据类型--modify 5.删除字段&#xff08;列&#xff09;--drop 四、删除表 一、创建表 create [temporary]table[if not exists]table_name [([colu…

答题小程序功能细节揭秘:如何提升用户体验和满足用户需求?

答题小程序功能细节体现 随着移动互联网的快速发展&#xff0c;答题小程序成为了用户获取知识、娱乐休闲的重要平台。一款优秀的答题小程序不仅应该具备简洁易用的界面设计&#xff0c;更应该在功能细节上做到极致&#xff0c;以提升用户体验和满足用户需求。本文将从题库随机…

Java毕业设计-基于springboot开发的游戏分享网站平台-毕业论文+答辩PPT(附源代码+演示视频)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1、开发说明2、需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、后台登录2.1管理员功能模块2.2用户功能模块 四、毕设内容和源代码获取总结 Java毕业设计-基于springboot开发的…

类与对象中C++

加油&#xff01;&#xff01;&#xff01; 文章目录 前言 一、类的6个默认成员函数 ​编辑 二、构造函数 1.概念 三、析构函数 1.概念 2.特性 四、拷贝构造函数 1.概念 2.特征 拷贝构造函数典型调用场景 五、赋值运算符重载 1.运算符重载 2.赋值运算符重载 赋值运算符重载格式…

Day24:私信列表、私信详情、发送私信

测试用户&#xff1a;用户名aaa 密码aaa 查询当前用户的会话列表&#xff1b;每个会话只显示一条最新的私信&#xff1b;支持分页显示。 首先看下表结构&#xff1a; conversation_id: 用from_id和to_id拼接&#xff0c;小的放前面去&#xff08;因为两个人的对话应该在一个会…

如何使用剪映专业版剪辑视频

1.操作界面功能介绍 2.时间线的使用 拖动前端后端缩减时长&#xff0c;有多个素材可以拖动调节前后顺序拼接。 分割视频 删除

新零售SaaS架构:客户管理系统的应用架构设计

客户管理系统的应用架构设计 应用层定义了软件系统的应用功能&#xff0c;负责接收用户的请求&#xff0c;协调领域层能力来执行任务&#xff0c;并将结果返回给用户&#xff0c;功能模块包括&#xff1a; 客户管理&#xff1a;核心功能模块&#xff0c;负责收集和更新客户信息…

FPGA时钟资源详解(3)——全局时钟资源

FPGA时钟系列文章总览&#xff1a;FPGA原理与结构&#xff08;14&#xff09;——时钟资源https://ztzhang.blog.csdn.net/article/details/132307564 一、概述 全局时钟是 FPGA 中的一种专用互连网络&#xff0c;旨在将时钟信号分配到 FPGA 内各种资源的时钟输入处。这种设计…

探索数据库--------------mysql主从复制和读写分离

目录 前言 为什么要主从复制&#xff1f; 主从复制谁复制谁&#xff1f; 数据放在什么地方&#xff1f; 一、mysql支持的复制类型 1.1STATEMENT&#xff1a;基于语句的复制 1.2ROW&#xff1a;基于行的复制 1.3MIXED&#xff1a;混合类型的复制 二、主从复制的工作过程 三个重…

IMU评估产后腹直肌分离康复训练

腹直肌分离&#xff08;Diastasis Recti Abdominis&#xff0c;DRA&#xff09;是由腹部纤维联结组织——腹白线的过度伸张所致&#xff0c;这项研究的目标是通过惯性测量单元&#xff08;IMU&#xff09;感应器信号来分析产后康复。传统的康复方式通常包括针对性的物理疗法&am…

《QT实用小工具·一》电池电量组件

1、概述 项目源码放在文章末尾 本项目实现了一个电池电量控件&#xff0c;包含如下功能&#xff1a; 可设置电池电量&#xff0c;动态切换电池电量变化。可设置电池电量警戒值。可设置电池电量正常颜色和报警颜色。可设置边框渐变颜色。可设置电量变化时每次移动的步长。可设置…

CleanMyMac X 4.15.1 for Mac 最新中文破解版 系统优化垃圾清理工具

CleanMyMac X for Mac 是一款功能更加强大的系统优化清理工具&#xff0c;相比于 CleanMyMac 4.15.1来说&#xff0c;功能增加了不少&#xff0c;此版本为4.15.1官方最新中英文正式破解版本&#xff0c;永久使用&#xff0c;解决了打开软件崩溃问题&#xff0c;最新版4.15.1版本…

neo4j相同查询语句一次查询特慢再次查询比较快。

现象&#xff1a; neo4j相同查询语句一次查询特慢再次查询比较快。 分析&#xff1a; 查询语句 //查询同名方法match(path:Method) where id(path) in [244333030] and NOT path:Constructor//是rpc的方法match(rpc_method:Method)<-[:DECLARES]-(rpc_method_cls:Class) -…

2024年智能版控费系统方案卓健易控

2024年智能版控费系统方案卓健易控 详细可咨询&#xff1a;19138173009 设备智能卓健易控ZJ-V8.0控费方案在科学和技术不断发展的背景下&#xff0c;逐渐实现了更新和迭代。现如今&#xff0c;感应技术、生物识别技术、智能图像识别技术、过程记录技术、监管控制技术等方面的…

Pytorch的hook函数

hook函数是勾子函数&#xff0c;用于在不改变原始模型结构的情况下&#xff0c;注入一些新的代码用于调试和检验模型&#xff0c;常见的用法有保留非叶子结点的梯度数据&#xff08;Pytorch的非叶子节点的梯度数据在计算完毕之后就会被删除&#xff0c;访问的时候会显示为None&…

解析为什么使用celery的task装饰就有delay属性

分析task装饰器原理 from celery.task import periodic_task task源码如下 def task(*args, **kwargs):"""Deprecated decorator, please use :func:celery.task."""return current_app.task(*args, **dict({base: Task}, **kwargs))这里回调…

JavaSE day14笔记

第十四天课堂笔记 课上: 适当做笔记课下 : 总结 , 读代码 , 反复敲代码 , 做练习 数组★★★ 数组 : 存储多个 同一类型 的容器格式 :数组类型 : 引用数据类型, new运算符在堆中 分配一块连续的存储空间 , 系统会给数组元素默认初始化 , 将该数组的引用赋值给数组名 引用数据…

如何在Win10使用IIS服务搭建WebDAV网站并实现无公网IP访问内网文件内容

文章目录 前言1. 安装IIS必要WebDav组件2. 客户端测试3. 使用cpolar内网穿透&#xff0c;将WebDav服务暴露在公网3.1 安装cpolar内网穿透3.2 配置WebDav公网访问地址 4. 映射本地盘符访问 前言 在Windows上如何搭建WebDav&#xff0c;并且结合cpolar的内网穿透工具实现在公网访…

腾讯云4核8G服务器价格,12M带宽一年646元,送3个月

2024年腾讯云4核8G服务器租用优惠价格&#xff1a;轻量应用服务器4核8G12M带宽646元15个月&#xff0c;CVM云服务器S5实例优惠价格1437.24元买一年送3个月&#xff0c;腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云4核8G服务器优惠价格 轻…

ArcGIS矢量裁剪矢量

一、利用相交工具 Arctoolbox工具一分析工具一叠加分析一相交