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

JavaScript 进阶A(作用域、闭包、变量和函数提升、函数相关只是、数组解构、对象解构、构造函数

1.作用域

作用域主要分为:局部作用域和全局作用域。

局部作用域又分为:函数作用域和块作用域

  • 函数作用域:在函数中定义的变量只能在函数内部使用,外部无法访问
  • 块作用域:被大括号{}包起来的代码块,在这个代码块中定义的变量就生存在块作用域内

 全局作用域:全局作用域可以被其他作用域访问

作用域链

作用域链就是变量查找的机制,在函数被调用的时候,会优先查找函数作用域内的变量。如果找不到再去依次向外层父作用域查找。
如果被调函数作用域内有与外部变量同名变量,优先调用函数作用域内部变量

作用域之间的关系:子作用域可以访问父作用域,父作用域不可访问子作用域

 2.闭包

我们来看一个简单的闭包实例

function outter(){let a =0function inner(){a++console.log(a)}return inner
}let key = outter()
//实际上就是 key = inner 因为outter()最后的返回值是innerkey()
//调用一次就执行一次inner()函数

这是一个简单的计数器的例子,当我们使用key接收inner的值的时候。其实就是执行了一边outter函数然后把函数的返回值赋给key。此时的key()就是执行inner函数。

按理来说变量a会随着outter函数的结束而销毁。但是实际情况却并不是,我们通过key依旧可以访问这个变量。这里就要讲一下js的垃圾回收机制了。

js的垃圾回收机制是根据变量是否被引用而决定是否销毁它。因为在inner函数中我们通过console.log引用了外部的变量a。这就导致了内部的函数引用了外部的变量。虽然外部函数结束了,但是由于这个变量依旧被引用,所以变量得以保存

详细的过程:

1.当outter函数被执行的时候,会创建一个局部变量a
2.当inner函数被定义的时候会捕获其所在的词法环境
3.outter函数执行结束,正常情况是a被销毁,但是由于inner函数的引用,让a得以保存
4.当inner函数执行的时候仍然可以访问a,因为闭包保留了a

至于为什么不直接使用变量去实现计数器的效果,是因为闭包会把一个变量变为私有变量。正常的访问是无法访问这个变量的。只有我们通过inner函数调用的时候才会访问这个变量。这在一定程度上提升了安全性。

3.变量和函数提升

变量提升

变量的声明有三种方式:1.let  2.const  3.var

前两种我们经常会用到,但是第三种我们在之前都没怎么用过。

其实let和var本质上都是差不多的,唯一的区别在一var会存在“变量提升”

变量提升就是允许变量在声明之前被访问

我们来看两个案例:

案例1console.log(num)let num =10案例2console.log(num)var num =10结果:案例一报错。案例二打印undefined

通过这个我们可以很明确的发现,使用var声明的变量可以在声明语句前被访问,但是访问的结果是undefined,变量在未赋值之前访问结果是undefined。这也就说明了:变量提升只会提升变量的定义,不会提升赋值。

案例2的代码就相当于:

let a
console.log(a)
a=10

我们应该避免使用var

函数提升

函数提升和变量提升基本上一样,函数提升就是把当前作用域的函数声明提升到最前面。

我们在之前的代码中可能都会把函数声明来写到后面。

按照之前的思路来说,应该是先声明在使用。但是函数自己的定义就会有提升的效果。也就是说函数默认有函数提升。

我们之后在编写代码的时候如果有函数需要单独的写出来,我们建议写在最前面。

4.函数相关(参数、箭头函数

函数参数

动态参数

我们在编写代码的时候一般都会提前写好有几个参数,但是有的时候我们并不能确定我这个函数需要几个参数。这个时候再编写函数的代码的时候就会非常困难。

但是我们有一种方法可以解决这个问题:函数内置的arguments伪数组。

 function fn(){console.log(arguments.length)console.log(arguments[0], arguments[1], arguments[2])console.log(typeof arguments[0], typeof arguments[1], typeof arguments[2])}fn(1,1.1,"Www")

看这段代码,我的函数在定义的时候是没有声明形参的,但是我调用的时候却传入了三个实参。

然后我通过arguments这个函数内置的伪数组得到了这三个参数。

arguments是函数内置的伪数组,它可以存储调用函数的时候传入的参数。即使函数定义了形参我依旧可以通过arguments获取这个形参

剩余参数

剩余参数:我们在传参的时候一般都是一一对应的传参,如果传递的实参数量大于形参,剩余的没有对应的参数就是剩余参数。我们可以把这些剩余参数表示为一个真数组

下面看案例来理解:

 function fn(num,...arr){console.log(num);console.log(arr);}fn(1,2,3,4,5,7)

最后输出num是1,arr是一个数组,数组包含2,3,4,5,7

这个arr就是一个剩余参数构成的数组,一般来说我们都会把剩余参数写在参数列表的后面。

展开运算符:...数组 -》可以把数组的所有元素拿出来
假设有一个数组arr=[1,2,3,4,5,6,7] 则 ...arr = 1,2,3,4,5,6,7(不是字符串

箭头函数

箭头函数基本形式

(参数)=>{函数体}

1.如果参数只有一个 :可以省略参数的小括号: 参数=>{函数体}

2.如果函数体只有一条语句:可以省略大括号: (参数)=>语句  并且这个语句的结果就是返回值

箭头函数的this --- 继承父级的this

一个对象里面的方法(普通函数)的this指向这个对象,因为是对象调用了这个方法
一个对象里面的方法(箭头函数)的this指向window,因为箭头函数的this继承了对象的this

数组解构

作用:快速批量赋值

用法1.

arr = [1,2,3,4,5,6,7]

const [a,b,c,d,e,f,g] = arr 或者 const [a,b,c,d,e,f,g] = [1,2,3,4,5,6,7]

用法2.

有两个变量,想交换它们的值:[a,b] = [b,a]

注:const [a,b,c] = [1,2]这种情况下c是undefined
const [a,b] = [1,2,3]这种情况下会舍去多余的
可以使用剩余参数防止丢失:const[a,b,...c] = [1,2,3,4,5,6,7,8,9] 这种情况a1,b2,c是数组

对象解构

对象解构的作用和数组结构一样

我们先来回顾以下对象

对象名={对象内容},对象内容可以是变量或者函数,变量称为属性,函数称为方法。中间使用逗号隔开

obj ={name:"www",age:11,outer:function(){console.log(this.name,this.age)    }
}const {name,age,outer} = objconsole.log(name,age)
outer()

具体使用没什么区别,然后要注意的是数组使用[]对象使用{}
方法结构出来可以调用它。但是outer是不能输出我们想要的内容的,主要是解构出来之后调用者从obj变成了window。

变量的名字要和属性名一致

如果想让变量不和属性一个名字可以使用const{name:aaa}这种方式让name变成aaa

 构造函数

我们首先讲一下new关键字,这个关键字用于创建一个空对象
这个空的对象里面什么都没有,我们有两个方法为这个对象添加属性或者方法
1.new 构造函数()
2.new一个对象,通过对象.属性/方法添加

这是通过构造函数:

构造函数的作用就是创建和初始化对象。他需要使用new关键字调用

下面是一个简单的构造函数:

function student(stu_name,stu_age,stu_gender,stu_add){this.name=stu_name;this.age=stu_age;this.gender=stu_gender;this.add=stu_add;}const stu1= new student("xxx",11,"nan","001100")console.log(stu1)

我们首先声明了一个构造函数,这个函数接收四个参数

通常来说,这个函数里面的this指的是window。但是通过new关键字调用构造函数会把new关键字创建的新对象绑定到构造函数的this。
我们只需要记住通过new关键字调用构造函数,构造函数的this指向new创建的对象
其实我们在构造函数里面打印一下this就能知道this指向的是谁了。上面的例子里打印this会打印出student

这是通过手动添加:

我们需要先创建一个空的对象:const obj = new Object()

然后obj.属性/方法    添加属性或者方法

相关文章:

JavaScript 进阶A(作用域、闭包、变量和函数提升、函数相关只是、数组解构、对象解构、构造函数

1.作用域 作用域主要分为:局部作用域和全局作用域。 局部作用域又分为:函数作用域和块作用域 函数作用域:在函数中定义的变量只能在函数内部使用,外部无法访问块作用域:被大括号{}包起来的代码块,在这个…...

mybatis映射文件相关的知识点总结

mybatis映射文件相关的知识点总结 mybatis官网地址 英文版:https://mybatis.org/mybatis-3/index.html 中文版:https://mybatis.p2hp.com/ 搭建环境 /* SQLyog Ultimate v10.00 Beta1 MySQL - 8.0.30 : Database - mybatis-label *****************…...

【UCB CS 61B SP24】Lecture 21: Data Structures 5: Priority Queues and Heaps 学习笔记

本文介绍了优先队列与堆,分析了最小堆的插入与删除过程,并用 Java 实现了一个通用类型的最小堆。 1. 优先队列 1.1 介绍 优先队列是一种抽象数据类型,其元素按照优先级顺序被处理。不同于普通队列的先进先出(FIFO)&…...

【JAVA】ThreadPoolTaskExecutor 线程池学习、后端异步、高并发处理

ThreadPoolTaskExecutor 是 Spring 框架提供的一个线程池实现类,基于 Java 原生的 ThreadPoolExecutor 进行了封装和扩展,支持更灵活的配置,并与 Spring 的依赖注入、生命周期管理等功能无缝集成。它常用于异步任务处理、定时任务调度和高并发…...

C#:LINQ学习笔记01:LINQ基础概念

一、LINQ 架构体系 1. LINQ 的核心思想 统一查询模型:对对象、XML、数据库等不同数据源使用一致的语法。强类型检查:编译时类型安全,减少运行时错误。 2. 核心组件 技术数据源典型场景LINQ to Objects内存集合 (IEnumerable)过滤/排序集合…...

爬虫系列之发送请求与响应《一》

一、请求组成 1.1 请求方式:GET和POST请求 GET:从服务器获取,请求参数直接附在URL之后,便于查看和分享,常用于获取数据和查询操作 POST:用于向服务器提交数据,其参数不会显示在URL中,而是包含在…...

【零基础到精通Java合集】第十集:List集合框架

课程标题:List集合框架(15分钟) 目标:掌握List接口核心实现类(ArrayList/LinkedList)的使用与场景选择,熟练操作有序集合 0-1分钟:List概念引入 以“购物清单”类比List特性:元素有序(添加顺序)、可重复、支持索引访问。说明List是Java集合框架中最常用的数据结构…...

小米手机如何录制屏幕?手机、电脑屏幕录制方法分享

大家最近有没有遇到想记录手机屏幕操作的情况? 比如精彩的游戏瞬间、有趣的视频教程,或者需要录制屏幕来制作演示材料。小米手机在这方面可是个好帮手,今天就来给你好好唠唠,小米手机如何录制屏幕,以及后续如何处理这…...

【RTC】 TM32 RTC(实时时钟)库函数 配置

1. 硬件配置 与HAL库相同,需确保以下硬件条件: 外部低速晶振(LSE,32.768kHz)连接至 OSC32_IN 和 OSC32_OUT 引脚。 备用电池(VBAT)已连接,确保断电时RTC持续运行。 2. 标准外设库(库函数)配置步骤 2.1 初始化RTC时钟源 #include "stm32f10x.h" #include…...

策略模式的C++实现示例

核心思想 策略模式是一种行为型设计模式,它定义了一系列算法,并将每个算法封装在独立的类中,使得它们可以互相替换。策略模式让算法的变化独立于使用它的客户端,从而使得客户端可以根据需要动态切换算法,而不需要修改…...

deepseek、腾讯元宝deepseek R1、百度deepseekR1关系

分析与结论 区别与联系 技术基础与定制方向: DeepSeek官网R1版本:作为基础版本,通常保留通用性设计,适用于广泛的AI应用场景(如自然语言处理、数据分析等)。其优势在于技术原生性和官方直接支持。腾讯元宝…...

Leetcode 面试150题(三)

一、题目 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &am…...

3D Web轻量化引擎HOOPS Communicator的核心优势解析:高性能可视化与灵活部署!

在当今数字化时代,工业领域的工程应用不断向基于Web的方向发展,而HOOPS Web平台作为一款专为构建此类工程应用程序打造的软件开发套件集,正发挥着日益重要的作用,成为构建强大工程应用的基石。 一、HOOPS Web平台概述 HOOPS Web…...

python爬虫:python中使用多进程、多线程和协程对比和采集实践

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. 多进程爬虫1.1 python多进程样例1.2 实现多进程爬虫2. 多线程爬虫2.1 python多线程样例2.2 实现多线程爬虫3. 协程爬虫3.1 python协程样例3.2 实现协程爬虫在网络爬虫中,为了提高抓取效率,常常需要使用多进程、多线…...

从 JVM 源码(HotSpot)看 synchronized 原理

大家好,我是此林。 不知道大家有没有这样一种感觉,网上对于一些 Java 框架和类的原理实现众说纷纭,看了总是不明白、不透彻。常常会想:真的是这样吗? 今天我们就从 HotSpot 源码级别去看 synchronized 的实现原理。全…...

深入探索Python机器学习算法:模型调优

深入探索Python机器学习算法:模型调优 文章目录 深入探索Python机器学习算法:模型调优模型调优1. 超参数搜索方法1.1 网格搜索(Grid Search)1.2 随机搜索(Random Search)1.3 贝叶斯优化(Bayesia…...

windows 上删除 node_modules

在 Windows 11 上,你可以通过命令行来删除 node_modules 文件夹并清除 npm 缓存。以下是具体步骤: 删除 node_modules 打开命令提示符(Command Prompt)或终端(PowerShell)。 导航到项目目录。你可以使用 …...

postman请求后端接受List集合对象

后端集合 post请求,即前端请求方式...

Kimi“撞车”DeepSeek!新一代注意力机制的极限突破!

近期,各方大佬在注意力机制上又“打起来了”。首先登场的是顶流DeepSeek,新论文梁文锋署名,提出了一种新的注意力机制NSA。同天,Kimi杨植麟署名的新注意力架构MoBA开源。紧接着,华为诺亚提出高效选择注意力架构ESA。 …...

如何在Android中实现服务(Service)

在Android中,Service 是一种用于在后台执行长时间运行操作而不提供用户界面的组件。Service 可以执行各种后台任务,如下载文件、播放音乐、执行定时任务等。以下是如何在Android中实现Service的基本步骤: 1. 创建一个Service类 首先&#x…...

计算机网络---SYN Blood(洪泛攻击)

文章目录 三次握手过程SYN Flood攻击原理防御措施协议层优化网络层拦截系统配置调整 TCP协议是 TCP/IP 协议栈中一个重要的协议,平时我们使用的浏览器,APP等大多使用 TCP 协议通讯的,可见 TCP 协议在网络中扮演的角色是多么的重要。 TCP 协议…...

Ollama存在安全风险的情况通报及解决方案

据清华大学网络空间测绘联合研究中心分析,开源跨平台大模型工具Ollama默认配置存在未授权访问与模型窃取等安全隐患。鉴于目前DeepSeek等大模型的研究部署和应用非常广泛,多数用户使用Ollama私有化部署且未修改默认配置,存在数据泄露、算力盗…...

视频流畅播放相关因素

视频播放的流畅度是一个综合性问题,涉及从视频文件本身到硬件性能、网络环境、软件优化等多个环节。以下是影响流畅度的关键因素及优化建议: 一、视频文件本身 1. 分辨率与帧率 1.问题:高分辨率(如4K)或高帧率&#…...

蓝桥杯试题:二分查找

一、问题描述 给定 n 个数形成的一个序列 a,现定义如果一个连续子序列包含序列 a 中所有不同元素,则该连续子序列便为蓝桥序列,现在问你,该蓝桥序列长度最短为多少? 例如 1 2 2 2 3 2 2 1,包含 3 个不同的…...

机器人训练环境isaac gym以及legged_gym项目的配置问题

完整的安装环境教程(强烈推荐):...

Qt QOCI driver available but not loaded(可用但未加载)

参考Linux Qt 6安装Oracle QOCI SQL Driver插件(适用WSL),根据SQL Database Drivers成功将libqsqloci.so、qsqloci.debug等文件安装到/opt/Qt6.8.2/6.8.2/gcc_64/plugins/sqldrivers后,运行Qt程序并尝试连接数据库时仍然报错 QSql…...

健康医疗大数据——医疗影像

一、 项目概述 1.1 项目概述 1.2 项目框架 1.3 项目环境 1.4 项目需求 二、项目调试与运行 2.1需求分析 2.2具体实现 三、项目总结 项目概述 项目概述 本项目旨在应用大数据技术于医疗影像领域,通过实训培养团队成员对医疗大数据处理和分析的实际…...

学生管理信息系统的需求分析与设计

伴随教育的迅猛演进以及学生规模的不断扩增,学生管理信息系统已然成为学校管理的关键利器。此系统能够助力学校管控学生的课程成绩、考勤记载、个人资讯等诸多数据,提升学校的管理效能与服务品质。 一.需求分析 1.1 学生信息管理 学生信息在学校管理体…...

基于微信小程序的停车场管理系统的设计与实现

第1章 绪论 1.1 课题背景 随着移动互联形式的不断发展,各行各业都在摸索移动互联对本行业的改变,不断的尝试开发出适合于本行业或者本公司的APP。但是这样一来用户的手机上就需要安装各种软件,但是APP作为一个只为某个公司服务的一个软件&a…...

【AI深度学习基础】NumPy完全指南终极篇:核心功能与工程实践(含完整代码)

NumPy系列文章 入门篇进阶篇终极篇 一、引言 在完成NumPy入门篇的基础认知与进阶篇的特性探索后,我们终于迎来这场终极技术深潜。本文不再停留于API使用层面,而是直指NumPy的架构内核与高性能工程实践的本质矛盾。作为Python科学计算领域的基石&#…...