【前端】JavaScript中的函数形式参数:预解析与作用域详解
文章目录
- 💯前言
- 💯示例代码
- 💯1. 形式参数的预解析
- 模拟预解析后的代码
- 💯2. 函数作用域与子函数的关系
- 代码详解
- 💯3. 扩展:块作用域与变量提升
- 💯4. 实际应用场景与最佳实践
- 💯小结
💯前言
- 在 JavaScript 编程中,
函数的形式参数
是一个经常被忽视但极为重要的概念。形式参数不仅充当局部变量的角色,其初始化方式
和作用域规则更是与普通变量存在显著差异。这些独特规则不仅影响代码的可读性
和维护性,还可能在复杂的嵌套作用域中引发意料之外的行为。理解形式参数的预解析机制及其在不同作用域中的表现,是开发者深入掌握 JavaScript 的关键
。
本文以一个具体的示例代码为基础,详细剖析 JavaScript 中形式参数的预解析
、作用域规则及其与子函数的相互影响,并通过扩展讨论块作用域与变量提升
的问题,最终总结出实用的开发建议与最佳实践。
JavaScript
💯示例代码
以下是本文分析的核心代码示例:
function a(nms) {nms = 100; // 修改形式参数 nmsconsole.log(nms); // 输出 100function b() {var w = 10; // 声明局部变量 wconsole.log(nms); // 此处访问的依然是 a() 函数的 nms 参数nms = 20; // 修改的仍然是 a() 函数作用域内的 nms}
}
💯1. 形式参数的预解析
在JavaScript中,形式参数的行为等同于在函数体顶部以var
声明一个变量。这意味着,在函数内部执行代码之前,形式参数已被隐式声明并初始化为局部变量。
模拟预解析后的代码
为了更清晰地理解形式参数的预解析过程,我们通过模拟代码展示实际执行的逻辑:
function a(nms) {// 预解析阶段的效果,相当于在函数顶部添加以下代码:var nms; // 形式参数被隐式声明为局部变量function b() { //函数声明提前var w // 变量声明提前w = 10;console.log(nms); // 此处访问的依然是 a() 函数的 nms 参数nms = 20; // 修改的仍然是 a() 函数作用域内的 nms}// 执行阶段nms = 100; // 修改的是函数 a 内部作用域的形式参数 nmsconsole.log(nms); // 输出 100
}
解析:
- 形式参数
nms
在函数定义时已被隐式声明,相当于在函数顶部添加var nms
。 - 在函数内部,形式参数的作用域优先级高于任何同名的全局变量或外部变量。
这种预解析过程与JavaScript的变量提升机制密切相关。变量声明会被提升到作用域的顶部,但赋值操作仍保持在原有位置。形式参数因而可以在整个函数体内使用,其初始值仅在实际调用函数时被赋予。
验证形式参数的优先级:
let nms = 50;
function a(nms) {console.log(nms); // 输出 undefined,因为形式参数在作用域中被隐式声明但尚未赋值
}
这种行为在实际开发中有助于避免局部变量命名覆盖全局变量或外部变量,从而提高代码的稳定性和可维护性。
💯2. 函数作用域与子函数的关系
JavaScript采用词法作用域(Lexical Scope),即函数的作用域在定义时就已确定,而非在运行时动态生成。在示例代码中,子函数b
可以访问父函数a
中的形式参数nms
,且对其的修改会直接影响父函数的nms
。
代码详解
-
父函数作用域的继承
function a(nms) {nms = 100;console.log(nms); // 输出 100function b() {var w = 10;console.log(nms); // 输出 100,访问的是父函数的 nms} }
- 子函数
b
的作用域链包括自身作用域、父函数a
的作用域以及全局作用域。 - 子函数
b
能够读取父函数a
中定义的局部变量nms
。
- 子函数
-
子函数对父函数变量的修改
function a(nms) {nms = 100;console.log(nms); // 输出 100function b() {nms = 20; // 修改的是父函数作用域中的 nmsconsole.log(nms); // 输出 20}b(); // 调用子函数 bconsole.log(nms); // 输出 20,因为 nms 已经被子函数 b 修改 }
- 子函数
b
直接修改了父函数a
中的nms
。 - 因为
nms
是父函数a
的局部变量,子函数和父函数共享这部分作用域。
- 子函数
这种设计机制在需要多个嵌套函数共享数据时尤其有用。
💯3. 扩展:块作用域与变量提升
在ES6之前,JavaScript仅支持函数作用域(Function Scope),而没有块作用域(Block Scope)。这导致了变量提升(Hoisting)的现象。
function test() {console.log(x); // 输出 undefined,因为变量 x 被提升但尚未赋值var x = 10;
}
ES6引入了let
和const
,使块作用域成为可能,解决了变量提升带来的问题。
function test() {console.log(x); // 报错:ReferenceError,因为 x 在块作用域内未被声明let x = 10;
}
此外,块作用域还使得循环中的变量处理更加安全:
for (let i = 0; i < 5; i++) {setTimeout(() => console.log(i), 1000);
}
// 输出:0, 1, 2, 3, 4
相比之下,使用var
时,由于变量提升问题,console.log
会输出相同的值。
💯4. 实际应用场景与最佳实践
-
避免全局变量污染
- 使用局部变量代替全局变量,确保形式参数不会覆盖全局变量。
function process(data) {let result = data + 100; // 使用 let 声明局部变量console.log(result); }
-
理解作用域链
- 理解作用域链的工作机制,避免在子函数中无意修改父函数的变量。
-
使用严格模式
- 在严格模式下,未声明变量会导致运行时错误,从而减少作用域相关问题。
'use strict'; function a(nms) {nms = 100;console.log(nms); }
-
模块化编程
- 使用ES6模块或CommonJS模块,将变量作用域局限于模块内部,避免全局污染。
💯小结
本文深入探讨了 JavaScript 中函数形式参数的预解析
和作用域管理。通过分析具体代码示例,我们了解了形式参数如何被隐式声明为局部变量,以及它们在函数执行过程中所表现出的独特行为。我们还探讨了函数作用域链、块作用域与变量提升
,并总结了适用于实际开发的最佳实践。
现代 JavaScript 提供了let
和const
等新特性,使开发者能够更精确地控制变量作用域。通过实践严格模式和模块化编程,开发者可以有效减少作用域相关错误,提高代码质量。掌握这些关键概念将帮助开发者更自信地编写复杂应用,避免常见的作用域问题,最终提升开发效率
与代码可维护性。
相关文章:
【前端】JavaScript中的函数形式参数:预解析与作用域详解
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 💯前言💯示例代码💯1. 形式参数的预解析模拟预解析后的代码 💯2. 函数作用域与子函数的关系代码详解 💯3. 扩展:块作用域与变量提…...
自然语言处理的未来愿景
自然语言处理的未来愿景 在这个信息爆炸的时代,计算机如何理解和生成我们日常使用的语言,已经成为一个引人注目的问题。你有没有想过,为什么智能助手能理解你的指令?又或者,为什么社交媒体上的推荐引擎能够精准地推荐你喜爱的内容?这背后,正是自然语言处理(NLP)在发挥…...
Vmodel环境配置
1.conda create -n pytorch311 python3.11 # 重新进入虚拟环境 source activate # 退出虚拟环境 conda deactivate 最后,重新执行 conda activate pytorch311 pip install torch-2.0.0cpu-cp311-cp311-linux_x86_64 配置Graph-WaveNet网络: pip…...
nvm-windows | node版本管理
问题: npm ERR! notsup Not compatible with your version of node/npm: npm10.9.2 npm ERR! notsup Required: {"node":"^18.17.0 || >20.5.0"} npm ERR! notsup Actual: {"npm":"9.5.0","node":"v18.…...
GLM-4V-Flash:智谱AI引领多模态视觉模型新潮流
点击访问 chatTools 免费体验GPT最新模型,包括o1推理模型、GPT4o 和Claude等模型! 随着人工智能技术的不断进步,多模态模型逐渐成为行业关注的焦点。智谱AI作为国内领先的人工智能公司,再次以创新姿态推出了首款免费多模态视觉模型…...
二、ubuntu单盘改软raid1
将单盘系统转换为软 RAID 1 是一个复杂的过程,尤其是在已经有数据的生产环境中进行时。这个过程涉及备份现有数据、创建 RAID 阵列、迁移数据以及更新引导加载程序(如 GRUB)。以下是详细的步骤指南: 前提条件 备份数据ÿ…...
「Mac玩转仓颉内测版45」小学奥数篇8 - 排列组合计算
本篇将通过 Python 和 Cangjie 双语讲解如何计算排列与组合。这道题目旨在让学生学会使用排列组合公式解决实际问题,并加深对数学知识和编程逻辑的理解。 关键词 小学奥数Python Cangjie排列与组合 一、题目描述 编写一个程序,计算从 n 个不同元素中取…...
【零成本抽象】基本概念与在C++中的实现
零成本抽象概念是由 Bjarne Stroustrup 提出的,他在 1994 年的著作中就有相关设想,2016 年其在 C++ 大会登台演讲时,明确阐述了 C++ 中的 “零成本抽象” 这一理念。 一、零成本抽象概念 Bjarne Stroustrup提出的零成本抽象概念,是指在编程中使用高级抽象机制时,不会产生…...
域渗透入门靶机之HTB-Cicada
easy难度的windows靶机 信息收集 端口探测 nmap -sT --min-rate 10000 -p- 10.10.11.35 -oA ./port 发现开放了53,88,389等端口,推测为域控 进一步信息收集,对爆破的端口进行更加详细的扫描 小tips:对于众多的端口&…...
(仓颉) Cangjie 刷力扣基础语法小结
文章目录 🧓官方资料🧓力扣经典前 3 题🕷️[1. 两数之和 - 力扣(LeetCode)](https://leetcode.cn/problems/two-sum/description/)🕷️[2. 两数相加 - 力扣(LeetCode)](https://leet…...
Phoenix5.1.3安装
环境说明 准备三台服务器,分别为:bigdata141(作为HBase主节点)、bigdata142、bigdata143,已经搭建好HBase集群,我这边HBase版本为2.2.7再准备一台服务器,bigdata144,可作为Phoenix客…...
深入理解 Apache Shiro:安全框架全解析
亲爱的小伙伴们😘,在求知的漫漫旅途中,若你对深度学习的奥秘、JAVA 、PYTHON与SAP 的奇妙世界,亦或是读研论文的撰写攻略有所探寻🧐,那不妨给我一个小小的关注吧🥰。我会精心筹备,在…...
机器学习:全面学习路径指南
摘要: 本文精心规划了一条从入门到精通机器学习的学习路线,详细涵盖了基础理论构建、核心技术栈掌握、主流算法学习、实践项目锻炼以及前沿领域探索等多个关键阶段。通过逐步深入各个层面,介绍必备的数学知识、编程工具、经典与现代机器学习算…...
二叉树交换相关算法题|递归/非递归交换所有节点左右子树(C)
交换左右子树 设树B是一棵采用链式结构存储的二叉树,编写一个把树B中所有节点的左右子树进行交换的函数 算法思想 采用递归算法实现交换二叉树的左右子树,首先交换root节点左孩子的左右子树,然后交换root节点右孩子的左右子树,…...
什么是纯虚函数?什么是抽象类?纯虚函数和抽象类在面向对象编程中的意义是什么?
纯虚函数 纯虚函数是一个在基类中声明但不实现的虚函数。它的声明方式是在函数声明的末尾添加 0。这意味着这个函数没有提供具体的实现,任何继承这个基类的派生类都必须提供这个函数的实现,否则它们也会变成抽象类,无法实例化。 示例&#…...
高效利用资源:分布式有状态服务的高可靠性设计
在分布式系统设计中,实现有状态服务的高可靠性通常采用主备切换的方式。当主服务停止工作时,备服务接管任务,例如通过Keepalive实现VIP的切换以保证可用性。然而,这种方式存在资源浪费的问题,因为备服务始终处于空转状…...
网络安全中的 SOC 是什么?
当今世界,网络威胁日益增多,确保网络安全已成为各种规模企业的首要任务。网络安全讨论中经常出现的一个术语是 SOC,即安全运营中心的缩写。但网络安全中的 SOC 是什么呢? SOC在防御网络威胁、管理安全事件和全天候监控系统方面发…...
QtCreator UI界面 菜单栏无法输入中文
如下图红色所示的区域,直接输入是无法输入中文的: 解决方法:在右边的属性值里输入即可 也可以参考这位同学的解决方法:友情链接...
圆桌对话:AI数字笔迹,数字化时代的重要驱动力 | 2024 AI+数字笔迹创新应用发展论坛
12月6日,以“聚焦创新应用,AI引领赋能”为主题的2024 AI数字笔迹创新应用发展论坛在重庆两江新区举办。本届论坛由重庆市大数据应用发展管理局和重庆两江新区管理委员会联合指导,重庆亲笔签数字科技有限公司主办。 论坛现场一场题为“数字化…...
Tablesaw封装Plot.ly实现数据可视化
上文介绍tablesaw的数据处理功能,本文向你展示其数据可视化功能,并通过几个常用图表示例进行说明。 Plot.ly包装 可视化是数据分析的重要组成部分,无论你只是“查看”新数据集还是验证机器学习算法的结果。Tablesaw是一个开源、高性能的Java…...
在Linux(ubuntu22.04)搭建rust开发环境
1.安装rust 1.安装curl: sudo apt install curl 2.安装rust最新版 curl --proto ‘https’ --tlsv1.2 https://sh.rustup.rs -sSf | sh 安装完成后出现:Rust is installed now. Great! 重启当前shell即可 3.检验是否安装成功 rustc --version 结果出现&…...
Less和SCSS,哪个更好用?
前言 Less 和 SCSS 都是流行的 CSS 预处理器,它们的目的都是扩展 CSS 的功能,使样式表更具组织性、可维护性和可重用性。虽然它们有许多相似之处,但在语法、特性和工作方式上也存在一些差异。 Less Less 是一种动态样式表语言,…...
vuex作用及五大组成部分
Vuex 是 Vue.js 官方的状态管理工具,用于管理应用中的全局状态。它的作用主要是解决组件间的状态共享和数据同步问题,特别是在组件复杂嵌套或兄弟组件通信中提供清晰、结构化的解决方案。 Vuex 的作用 集中管理状态: 将组件的共享状态抽取出…...
vue借助西瓜播放器插件实现视频播放
西瓜播放器官网 西瓜播放器 安装 npm install xgplayer 使用案例 vue3为例 <script setup lang"ts"> import Player from xgplayer import { ref, unref, onMounted, watch, onBeforeUnmount, nextTick } from vue import xgplayer/dist/index.min.csscon…...
PHP无法读取.env的配置变量原因
今天帮一个客户在一台服务器配置laravel,在安装好宝塔后,配置了php环境,把laravel项目上传,并且在根目录的.env上配置好数据库等信息后,发现无法正常使用 通过排查发现.env的变量无法正常获取,排查了好久后…...
Android 15(V)新功能适配,雕琢移动细节之美
Android 15,内部代号为Vanilla Ice Cream,是Android移动操作系统的最新主要版本,于2024年2月16日在开发者预览版1中发布。Android 15源代码于 2024年9月4日发布。Android 15稳定版于2024年10月15日发布。 以下是针对 Android 15(…...
Qt自定义类型在信号槽中的使用
引言 示例自定义数据类型信号槽效果检查代码注册自定义类型信号槽使用QVariant传递参数总结附加绑定信号槽,传递的参数如果是自定义类型的变量,槽函数不会响应。为什么呢?是因为自定义类型没有被写入元对象系统,对于Qt来说,不认识这个数据类型,Qt是以事件来驱动的,信号槽…...
自适应卡尔曼滤波(包括EKF、UKF、CKF等)的创新思路——该调什么、不该调什么
在调节自适应卡尔曼滤波时,需要注意的参数和矩阵都对滤波器的性能有直接影响。本文给出详细的说明,包括相关公式和 MATLAB 代码示例 文章目录 需要调节的参数1. **过程噪声协方差矩阵 Q Q Q**:2. **测量噪声协方差矩阵 R R R**:…...
Ape-DTS:开源 DTS 工具,助力自建 MySQL、PostgreSQL 迁移上云
Ape-DTS 是一款高效、轻量级且功能强大的开源工具,专注于解决数据迁移、同步、校验、订阅与加工的需求。无论是将自建的 MySQL/PostgreSQL 数据库迁移到云端,还是在不同数据库间进行数据迁移,Ape-DTS 都能为您提供便捷且可靠的解决方案。它特…...
SpringBoot中使用MyBatis-Plus详细介绍
目录 一、MyBatis-Plus的使用步骤 1.引入MybatisPlus的起步依赖 2.定义Mapper(也叫dao)层的接口 3.MyBatis-Plus中常用注解 4. 使用MyBatis-Plus时要做如下配置 5.条件构造器 Wrapper 一、MyBatis-Plus的使用步骤 1.引入MybatisPlus的起步依赖 My…...
Buuctf Web题解
写在前面, 本人小白一枚,记录一下web做题过程,大部分为个人理解可能有些地方写的不够明确还请见谅。当然由于刚入手web题,所以有些题会没有思路,这时会参考其他大佬的题解过程。本文会一直更新,由于是第一次…...
Linux 支持多个spi-nor flash
1. 需求 通常在嵌入式开发过程中可能会遇到需要再同一个SPI总线上挂载多个spi nor flash才能满足存储需求。 2. 技术简介 对于spi-nor flash驱动通常不需要驱动开发人员手搓,一般内核会有一套固定的驱动,而且走的是内核的MTD子系统那一套,市…...
APP、小程序对接聚合广告平台,有哪些广告变现策略?
开发者对接聚合广告平台,可以让自身流量价值最大化,获得更多的广告曝光机会,对接单一的广告联盟容易造成广告填充不足,收益不稳定的问题。#APP广告变现# APP开发者根据应用的生命周期、用户特征和产品定位,选择最适合…...
RPC设计--应用层缓冲区,TcpBuffer
为什么需要应用层的buffer 为了方便数据处理,从fd上直接读写然后做包的组装、拆解不够方便方便异步发送,将数据写到应用层buffer后即可返回,让epoll即event_loop去异步发送。提高发送效率,多个小包可合并发送 buffer 设计 可以…...
微服务的问题
1.创建maven项目 然后配置对应的maven地址 2.创建父工程 删掉其中的src文件 在父pom中进行版本依赖和管理 如下图所示 3.在子文件中进行添加依赖 然后刷新maven进行下载...
开源模型应用落地-知识巩固-如何正确搭建生产级AI服务(一)
一、前言 将大语言模型集成至vllm,能够显著实现推理加速,让模型在处理任务时更加高效快捷,极大地提升了响应速度,减少用户等待时间。具体而言,一方面它能大幅提高吞吐量,vLLM 借助 PagedAttention巧妙地对attention中缓存的张量进行高效管理,从而达成比 HuggingFace Tra…...
Uniapp Android SpringBoot3 对接支付宝支付(最新教程附源码)
Uniapp Android SpringBoot3 对接支付宝支付(最新教程附源码) 1、效果展示2、后端实现2.1 引入支付宝SDK依赖 pom.xml2.2 配置 application.yml2.3 支付宝相关代码2.3.1 AlipayConfig.java2.3.2 ZfbPayConfig.java2.3.3 支付接口2.3.4 支付回调处理接口&…...
SpringSpringBoot常用注解
Spring 和 Spring Boot 是 Java 开发中广泛使用的框架,它们提供了许多注解来简化配置和开发过程。以下是一些 Spring 和 Spring Boot 中常用的注解: Spring 常用注解 Component 用于标注一个类为 Spring 容器的一个组件,Spring 会自动…...
【机器人】振动分析和控制工具之Bode图
Bode 图完整介绍 Bode 图由两个部分组成: 幅值图 (Magnitude Plot):描述系统对不同频率输入信号的增益大小(幅值响应)。相位图 (Phase Plot):描述系统输出信号相对于输入信号的相位差。 Bode 图的横轴是频率&#x…...
基于SpringBoot的“外卖点餐系统”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“外卖点餐系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能图 用户功能界面 订单管理界面 配送单管理…...
第十七章 使用 MariaDB 数据库管理系统
1. 数据库管理系统 数据库是指按照某些特定结构来存储数据资料的数据仓库。在当今这个大数据技术迅速崛起的年代,互联网上每天都会生成海量的数据信息,数据库技术也从最初只能存储简单的表格数据的单一集中存储模式,发展到了现如今存储海量…...
sql多表联查图文
内连接(INNER JOIN) 语法: SELECT 列名 FROM 表1 INNER JOIN 表2 ON 表1.列名 表2.列名;示例: SELECT 列名 FROM 表1 LEFT JOIN 表2 ON 表1.列名 表2.列名;左外连接(LEFT JOIN) 语法 SELECT 列名 FROM…...
网络安全——防火墙
基本概念 防火墙是一个系统,通过过滤传输数据达到防止未经授权的网络传输侵入私有网络,阻止不必要流量的同时允许必要流量进入。防火墙旨在私有和共有网络间建立一道安全屏障,因为网上总有黑客和恶意攻击入侵私有网络来破坏,防火…...
单独测试 pyautogui 的鼠标点击功能,确保它能够在当前环境中正常工作,鼠标自动点击的录制回放功能
感谢您提供的详细日志信息。根据您的反馈,问题可能出在 pyautogui 没有正确获取鼠标焦点或无法在预期的位置执行点击操作。我们将采取以下步骤来进一步诊断和解决这个问题: 1. **确保 pyautogui 正确执行点击操作**: - 我们将添加更多的调…...
图片底部空白缝隙解决法方案(CSS)
当我想实现一个垂直轮播图时,图片底部会出现一个空白缝隙导致切换轮播图片显示不完整。 这里可以用两个方法解决 一、给图片添加(垂直对齐)vertical-align:baseline|middle|top; vertical-align属性的值可以是 (1)关键字值:baseline|midd…...
URI 未注册(设置 语言和框架 架构和 DTD)
一、问题描述:在springboot项目中的resources中新建mybatis-config.xml文件时,从mybatis文档中复制的代码报错:URI 未注册(设置 | 语言和框架 | 架构和 DTD) 二、解决:在Springboot项目的设置->架构和DTD中添加 红色的网址&…...
STL-string类
目录 string类的意义 C语言原始的字符串 字符串类题目 string类 string类文档 auto和范围for auto是个关键字 范围for string类的接口 string的模拟实现 浅拷贝 深拷贝 写时拷贝 string类的意义 C语言原始的字符串 字符串是以\0结尾的字符的合集,为了方便操作,C标准库提…...
HTML前端开发-- Iconfont 矢量图库使用简介
一、SVG 简介及基础语法 1. SVG 简介 SVG(Scalable Vector Graphics)是一种基于 XML 的矢量图形格式,用于在网页上显示二维图形。SVG 图形可以无限缩放而不会失真,非常适合用于图标、图表和复杂图形。SVG 文件是文本文件&#x…...
C++的一些经典算法
以下是C的一些经典算法: 一、排序算法 冒泡排序(Bubble Sort) 原理: 它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换…...
LNMP和Discuz论坛
文章目录 LNMP和Discuz论坛1 LNMP搭建1.1 编译安装nginx服务1.1.1 编译安装1.1.2 添加到系统服务 1.2 编译安装MySQL服务1.2.1 准备工作1.2.2 编辑配置文件1.2.3 设置路径环境变量1.2.4 数据库初始化1.2.5 添加mysqld系统服务1.2.6 修改mysql的登录密码 1.3 编译安装PHP服务1.3…...