JavaScript作用域和作用域链

在JavaScript中,作用域和作用域链是理解代码执行和变量访问的关键概念。它们决定了变量和函数在代码中的可见性和生命周期。

一、作用域(Scope)

(一)什么是作用域?

作用域是在运行时代码中的某些特定部分中变量、函数和对象的可访问性。换句话说,作用域决定了代码区块中变量和其他资源的可见性。

作用域的主要作用是隔离变量,防止不同作用域下的同名变量发生冲突。例如:

function outFun2() {var inVariable = "内层变量2";
}
outFun2();
console.log(inVariable); // Uncaught ReferenceError: inVariable is not defined

在上面的例子中,变量inVariable在全局作用域中没有声明,因此在全局作用域下访问它会报错。

(二)全局作用域和函数作用域

1. 全局作用域

全局作用域是指在代码中任何地方都能访问到的对象。以下几种情形拥有全局作用域:

  • 最外层函数和在最外层函数外面定义的变量拥有全局作用域。
  • 所有未定义直接赋值的变量自动声明为拥有全局作用域。
  • 所有window对象的属性拥有全局作用域。
var outVariable = "我是最外层变量"; // 最外层变量
function outFun() { // 最外层函数var inVariable = "内层变量";function innerFun() { // 内层函数console.log(inVariable);}innerFun();
}
console.log(outVariable); // 我是最外层变量
outFun(); // 内层变量
console.log(inVariable); // inVariable is not defined

全局作用域的弊端是容易污染全局命名空间,引起命名冲突。因此,通常建议将代码封装在函数中,避免全局变量的滥用。

2. 函数作用域

函数作用域是指声明在函数内部的变量,这些变量只能在函数内部访问。例如:

function doSomething() {var stuName = "zhangsan";function innerSay() {console.log(stuName);}innerSay();
}
console.log(stuName); // 脚本错误
innerSay(); // 脚本错误

函数作用域的一个重要特点是内层作用域可以访问外层作用域的变量,但外层作用域不能访问内层作用域的变量。

(三)块级作用域

ES6引入了块级作用域,通过letconst关键字声明的变量具有块级作用域。块级作用域在以下情况被创建:

  1. 在一个函数内部。
  2. 在一个代码块(由一对花括号包裹)内部。

块级作用域的特点包括:

  • 声明变量不会提升到代码块顶部。
  • 禁止重复声明。
  • 循环中的绑定块作用域的妙用。
for (let i = 0; i < 10; i++) {console.log(i); // i 在循环内部有效
}
console.log(i); // ReferenceError: i is not defined

二、作用域链

(一)什么是自由变量?

自由变量是指在当前作用域中没有定义的变量。例如:

var a = 100;
function fn() {var b = 200;console.log(a); // 这里的 a 是一个自由变量console.log(b);
}
fn();

fn函数中,a是一个自由变量,因为它在fn函数的作用域中没有定义。

(二)什么是作用域链?

作用域链是指当访问一个变量时,编译器会从当前作用域开始,逐层向上查找,直到找到该变量或到达全局作用域。例如:

var a = 100;
function f1() {var b = 200;function f2() {var c = 300;console.log(a); // 100console.log(b); // 200console.log(c); // 300}f2();
}
f1();

f2函数中,ab是自由变量,它们的值通过作用域链从外层作用域中获取。

(三)关于自由变量的取值

自由变量的值是在函数定义时确定的,而不是在函数调用时确定的。例如:

var x = 10;
function fn() {console.log(x);
}
function show(f) {var x = 20;(function () {f(); // 输出 10,而不是 20})();
}
show(fn);

fn函数中,x的值是在fn函数定义时确定的,因此输出的是全局作用域中的x,而不是show函数中的x

三、作用域与执行上下文

许多开发人员经常混淆作用域和执行上下文的概念。虽然它们都与变量的访问和函数的执行有关,但它们是不同的概念。

  • 作用域:作用域是在函数定义时确定的,它决定了变量的可见性和生命周期。
  • 执行上下文:执行上下文是在函数执行时创建的,它包括变量对象、作用域链和this的指向。

(一)执行上下文的生命周期

执行上下文的生命周期分为两个阶段:

  1. 创建阶段:当代码执行进入一个环境时,会创建一个执行上下文。在这个阶段,执行上下文会进行以下操作:

    • 创建变量对象(Variable Object,VO):包括函数的形参、arguments对象、函数声明和变量声明。
    • 确定this的指向。
    • 确定作用域链。
  2. 执行阶段:在执行阶段,代码开始执行,变量被赋值,函数被调用,其他代码按顺序执行。

四、总结

理解作用域和作用域链的工作原理和实际应用,可以帮助你更好地理解代码的执行流程和变量的访问机制。如果你对本文的内容有任何疑问或补充,欢迎在评论区留言讨论。

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

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

相关文章

人工智能的“歧视”:“她数据”在算法运行中隐形

纵观人类的发展史&#xff0c;每一次科技进步都将对性别平等产生深刻影响。尤其是当下&#xff0c;人们对于借助人工智能技术快速发展来弥合性别不平等寄予厚望。 但很多人没想过&#xff0c;人工智能技术本身是客观中立、不存在“算法歧视”“性别偏见的吗&#xff1f; 弗吉…

设备全生命周期管理:从采购到报废的数字化闭环方案

在当今数字化时代&#xff0c;企业对设备的管理已不再局限于简单的维护与修理&#xff0c;而是追求从采购到报废的全生命周期数字化闭环管理。易点易动设备管理系统&#xff0c;正是这一趋势下的佼佼者&#xff0c;它为企业提供了一套高效便捷的设备管理解决方案。 采购阶段&a…

React中useState中更新是同步的还是异步的?

文章目录 前言一、useState 的基本用法二、useState 的更新机制1. 内部状态管理2. 状态初始化3. 状态更新 三、useState 的更新频率与异步行为1. 异步更新与批量更新2. 为什么需要异步更新&#xff1f; 四、如何正确处理 useState 的更新1. 使用回调函数形式的更新2. 理解异步更…

FEKO许可证与其他电磁仿真软件的比较

在电磁仿真领域&#xff0c;众多软件工具竞相争艳&#xff0c;而FEKO软件及其许可证制度在其中独树一帜。本文将对比FEKO许可证与其他电磁仿真软件&#xff0c;突出FEKO在许可证方面的卓越性能与独特优势&#xff0c;帮助您做出明智的选择。 一、许可证成本与价值比较 相较于其…

绿色云计算:数字化转型与可持续发展的完美融合

目录 引言 绿色云计算的概念与定义 云计算的环境影响与绿色云计算的重要性 绿色云计算的技术实践与策略 绿色云计算的案例研究与最佳实践 绿色云计算的挑战与限制 绿色云计算的未来趋势与预测 结论与展望 引言 随着云计算技术的迅猛发展和广泛应用&#xff0c;其环境影…

在innovus中如何设置让信号线打上双孔

知识星球【芯冰乐】入口 为了让设计的芯片良率能得到显著提升,一般在绕线资源允许的情况下,我们会在尽可能多的signal线上打上双孔,然而在进行某个项目的时候,小编惊讶的发现,在数字的layout上一个双孔都没出现,这是为什么呢?今天就让小编分享一下这次新奇的发现; 经…

DevExpress GridControl 复选列实时获取选中状态的解决方案

问题核心分析 用户在使用 DevExpress GridControl 的复选列时遇到两个关键问题&#xff1a; 1.使用 CellValueChanged 事件需要点击其他列才会触发&#xff0c;无法实时响应勾选动作 2.使用 CheckedChanged 事件并调用 PostEditor() 会导致复选框无法选中 这主要是因为 DevExp…

数据一致性校验算法

数据完整性校验 在 数据录入、通信协议&#xff08;CAN、LIN、Ethernet&#xff09; 和 存储&#xff08;Flash、EEPROM&#xff09; 领域&#xff0c;数据校验&#xff08;Error Checking&#xff09; 是确保 数据完整性和正确性的关键技术 示例&#xff1a;当我们从互联网上…

101个α因子#9

((0 < ts_min(delta(close, 1), 5)) ? delta(close, 1) : ((ts_max(delta(close, 1), 5) < 0) ? delta(close, 1) : (-1 * delta(close, 1))))worldquant brain平台上调整后的语法&#xff1a; ((0 < min(close-ts_delay(close, 1), ts_delay(close, 1)-ts_delay(c…

国产视频转换LT6211UX:HDMI2.0转LVDS/MIPI芯片简介,支持4K60Hz

1. LT6211UX HDMI2.0信号输入 支持HDMI2.0b, HDMI1.4和DVI1.0 支持HDCP2.2和HDCP1.4 数据速率高达6Gbps 自适应接收机均衡 支持4k60Hz 支持的3D格式&#xff1a; 对于HDMI -> LVDS&#xff1a; 直接3D输出 2路2D L/R输出 对于HDMI -> MIPI&#xff1a; 框架包装&#x…

华三(H3C)IRF堆叠心跳的LACP MAD、BFD MAD和ARP MAD差异

华三&#xff08;H3C&#xff09;IRF堆叠心跳的三种MAD&#xff08;多主检测&#xff09;机制——LACP MAD、BFD MAD和ARP MAD在实现原理、组网要求及适用场景上存在显著差异。以下是三者的对比分析&#xff1a; 一、核心区别对比 特性LACP MADBFD MADARP MAD检测原理扩展LAC…

宿州金博学校开展防震演练:夯实安全根基,守护校园平安

5月13日上午9点30分&#xff0c;金博学校原本宁静的校园被一阵急促的警报声打破&#xff0c;一场精心筹备、紧张有序的防震演练正式开启。本次演练意义重大&#xff0c;旨在强化全体师生的防震减灾意识&#xff0c;提高大家在地震突发时的应急反应与自我保护能力。 紧急避险&am…

DAY29 超大力王爱学Python

知识点回顾 类的装饰器装饰器思想的进一步理解&#xff1a;外部修改、动态类方法的定义&#xff1a;内部定义和外部定义 作业&#xff1a;复习类和函数的知识点&#xff0c;写下自己过去29天的学习心得&#xff0c;如对函数和类的理解&#xff0c;对python这门工具的理解等&…

RabbitMQ ④-持久化 || 死信队列 || 延迟队列 || 事务

消息确认机制 简单介绍 RabbitMQ Broker 发送消息给消费者后&#xff0c;消费者处理该消息时可能会发生异常&#xff0c;导致消费失败。 如果 Broker 在发送消息后就直接删了&#xff0c;就会导致消息的丢失。 为了保证消息可靠到达消费者并且成功处理了该消息&#xff0c;…

python打卡训练营打卡记录day31

知识点回顾 规范的文件命名规范的文件夹管理机器学习项目的拆分编码格式和类型注解 作业&#xff1a;尝试针对之前的心脏病项目ipynb&#xff0c;将他按照今天的示例项目整理成规范的形式&#xff0c;思考下哪些部分可以未来复用。 心脏病项目目录 目录结构:heart/ ├── conf…

mac .zshrc:1: command not found: 0 解决方案

nano ~/.zshrc 使用自带的nano命令打开文件&#xff0c;修改后 Ctrl X 然后输入y 然后回车即可保存成功 一般情况下&#xff0c;不是常用这个命令&#xff0c;除非是遇到有问题的文件&#xff0c;才用&#xff0c; 例如 遇到下面的问题 /Users/xxli/.zshrc:1: command no…

uniapp生成的app,关于跟其他设备通信的支持和限制

以下内容通过AI生成&#xff0c;这里做一下记录。 蓝牙 移动应用&#xff08;App&#xff09;通过蓝牙与其他设备通信&#xff0c;是通过分层协作实现的。 一、通信架构分层 应用层&#xff08;App&#xff09; 调用操作系统提供的蓝牙API&#xff08;如Android的BluetoothA…

第50天-使用Python+Qt+DeepSeek开发AI运势测算

1. 环境准备 bash 复制 下载 pip install pyside6 requests python-dotenv 2. 获取DeepSeek API密钥 访问DeepSeek官网注册账号 进入控制台创建API密钥 在项目根目录创建.env文件: env 复制 下载 DEEPSEEK_API_KEY=your_api_key_here 3. 创建主应用框架 python 复制…

上位机与Hid设备通信

前置知识 什么是HID&#xff1f; HID&#xff08;Human Interface Device&#xff09;是‌直接与人交互的电子设备‌&#xff0c;通过标准化协议实现用户与计算机或其他设备的通信&#xff0c;典型代表包括键盘、鼠标、游戏手柄等。‌ 为什么HID要与qt进行通信&#xff1f; …

JVM 工具实战指南(jmap / jstack / Arthas / MAT)

&#x1f50d; 从诊断到定位&#xff1a;掌握生产级 JVM 排查工具链 &#x1f4d6; 前言&#xff1a;系统故障时&#xff0c;如何快速定位&#xff1f; 无论 JVM 理论多么扎实&#xff0c;当线上服务出现 CPU 飙高、响应超时、内存泄漏或频繁 Full GC 时&#xff0c;仅靠猜测…