JS作用域:全局作用域,函数作用域,块级作用域

JS作用域:全局作用域,函数作用域,块级作用域

  • 背景
  • 作用域
    • 全局作用域
    • 函数作用域
    • 块级作用域
      • 通过调用栈分析块级作用域
      • 开发者工具查看作用域
      • 选项卡示例

背景

由于 JavaScript 存在变量提升这种特性,从而导致很多与直觉不符的代码,这也是 JavaScript 的一个重要设计缺陷,这种设计缺陷带来的问题可以去看看JS变量和函数提升。

所以 ES6 通过引入块级作用域并配合 letconst 关键字来避开了这种设计缺陷,但是由于 JavaScript 需要向下兼容,所以变量提升在相当长一段时间内还会继续存在。

作用域

作用域是指在程序中定义变量的区域,该位置决定了变量的生命周期。即,作用域是变量和函数的可访问范围,控制着变量和函数的可见性和生命周期。

ES6(2015年6月) 之前,ES 的作用域只有两种:全局作用域函数作用域。相较而言,其他语言则都普遍支持块级作用域

全局作用域

全局作用域中的对象在代码中的任何地方都能访问,其生命周期伴随着页面的生命周期。

函数作用域

函数作用域就是在函数内部定义的变量或函数,并且定义的变量或函数只能在函数内部被访问,函数执行结束后,函数内部定义的变量就会被销毁。

块级作用域

ES6 中给 JavaScript 新增了块级作用域

  • 块级作用域由{}包括,if语句和for语句里面的{}都属于块级作用域
  • var定义的变量没有块级作用域概念,可以跨块级作用域访问
  • letconst定义的变量只能在块级作用域里访问

下面几段示例代码可以帮助你对块级作用域的理解:

{var a = 1let b = 2const c = 3
}
console.log(a) // 1
console.log(b) // 报错(let和const只能在块级作用域中访问)
console.log(c) // 报错
for(var a = 0; a < 3; a++) {var d = 5
}
console.log(a) // 3
console.log(d) // 5for(let a = 0; a < 3; a++) {var d = 5
}
console.log(a) // 报错(for语句属于块级作用域)
console.log(d) // 5
if(true) {var a = 5
}
console.log(a) // 5if(true) {let a = 5
}
console.log(a) // 报错(if语句属于块级作用域)

通过调用栈分析块级作用域

不了解调用栈的可以先去看JS调用栈

function foo() {var a = 1let b = 2{let b = 3var c = 4let d = 5console.log(a)console.log(b)}console.log(b)console.log(c)console.log(d)
}
foo()
  1. 第一步编译并创建执行上下文。函数内部通过 var 声明的变量在编译阶段全都被存到变量环境里
    在这里插入图片描述

  2. 第二步继续执行代码。执行到函数内部代码块,在块级作用域之前,变量环境中的 a 已经被设置成了 1,词法环境中的 b 已经被设置成了 2
    在这里插入图片描述

  3. 进入函数内的块级作用域,块级作用域中通过 let 声明的变量会被存放在词法环境一个单独的区域中,这个区域中的变量并不影响块级作用域块外面的变量,比如它们都有一个变量 b其实在词法环境中维护了一个小型的栈结构,栈底时函数最外层的变量,进入一个块级作用域后,就会把该作用域内的变量压入栈中,当该作用域执行完成后就从栈中弹出。当然,这里的变量是指通过 letconst 声明的变量。
    在这里插入图片描述

  4. 当执行到块级作用域中的 console.log(a) 这行代码时,需要在词法环境和变量环境中查找 a 的值,具体查找方向是:沿着词法环境的栈顶向下查询,如果有直接返回给 JavaScript 引擎,如果都没有就去变量环境中查找。

  5. 块级作用域执行完后返回内容,弹出栈中,执行结果为
    在这里插入图片描述
    在这里插入图片描述

所以,块级作用域是通过词法环境的栈结构来实现的,而变量提升是通过变量环境来实现的,通过两者的结合,JavaScript 引擎也就同时支持了变量提升和块级作用域了。

开发者工具查看作用域

var a = 'hello'
let b = 18
const c = 'female'
{var aa = 'hi'let bb = 188const cc = 'male'debugger
}
function foo() {var aaa = 'go'let bbb = 10const ccc = 'man'{var aaaa = 'ok'let bbbb = 8const dddd = 'girl'debugger}debugger
}
foo()

打开Chrome开发者工具查看这段代断点处作用域下变量值

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

选项卡示例

<style>button.active{color: red;}p{display: none;}p.active{display: block;background-color: red;}
</style><body><button>选项一</button><button>选项二</button><button>选项三</button><p>内容一</p><p>内容二</p><p>内容三</p>
</body>
// 用var
<script>let buttons = document.querySelectorAll('button')let ps = document.querySelectorAll('p')for(var i = 0; i < buttons.length; i++) {buttons[i].index = ibuttons[i].onclick = function() {for(var j = 0; j < buttons.length; j++) {buttons[j].className = ''ps[j].className = ''}this.className = 'active'ps[this.index].className = 'active'}}
</script>
</body>
// 使用let块级作用域
let buttons = document.querySelectorAll('button')
let ps = document.querySelectorAll('p')for(let i = 0; i < buttons.length; i++) {buttons[i].onclick = function() {for(var j = 0; j < buttons.length; j++) {buttons[j].className = ''ps[j].className = ''}this.className = 'active'ps[i].className = 'active' // i的for循环每一次都会生成一个块级作用域所以每个i都在指定的作用域中工作}
}

总结:选项卡实例中,使用var没有块级作用域所以for循环结束,i就变成了最后的值,所以必须要将索引值赋值给每一个元素,然后点击的时候根据索引去判断显影性。
使用let创造了块级作用域,每次循环都会创造一个块级作用域的i,所以可以直接使用ps[i]去对对应的元素设置类名。

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

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

相关文章

Spring的Bean你了解吗

Bean的配置 Spring容器支持XML(常用)和Properties两种格式的配置文件 Spring中XML配置文件的根元素是,中包含了多个子元素&#xff0c;每个子元素定义了一个Bean,并描述了该Bean如何装配到Spring容器中 元素包含了多个属性以及子元素&#xff0c;常用属性及子元素如下所示 i…

python可视化界面自动生成,python如何做可视化界面

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python gui可视化操作界面制作&#xff0c;python做出的炫酷的可视化&#xff0c;现在让我们一起来看看吧&#xff01; 目录 前言 一.环境配置 插件&#xff1a; 1.python 2.Chinese 3.Open In Default Browser 安装pyt…

方案:智能分析网关V4区域人数超员AI算法模型的应用场景介绍

视频AI智能分析技术已经深入到人类生活的各个角落&#xff0c;与社会发展的方方面面紧密相连。从日常生活中的各种场景&#xff0c;如人脸识别、车牌识别&#xff0c;到工业生产中的安全监控&#xff0c;如工厂园区的翻越围栏识别、入侵识别、工地的安全帽识别、车间流水线产品…

MySQL 8.0 InnoDB Tablespaces之Undo Tablespaces(UNDO表空间)

文章目录 MySQL 8.0 InnoDB Tablespaces之Undo Tablespaces&#xff08;UNDO表空间&#xff09;Undo Tablespaces&#xff08;UNDO表空间&#xff09;默认UNDO表空间添加 Undo 表空间查看Undo 相关的信息查看Undo 相关参数变量查看Undo 状态信息通过information_schema.innodb_…

python使用watchdog监听文件变化并打包成docker镜像

文章目录 简介1.监听文件的代码2.获取依赖列表文件3.创建Dockerfile文件4.上传文件到服务器上5.构建容器并启动6.更新main.py代码操作 简介 最近用python帮公司写了一个监控目录下文件发生变化的插件&#xff0c;在打包成docker镜像的过程中出现了一些小问题&#xff0c;特意记…

Unity中Shader裁剪空间推导(透视相机到裁剪空间的转化矩阵)

文章目录 前言一、简单看一下 观察空间—>裁剪空间—>屏幕空间 的转化1、观察空间&#xff08;右手坐标系、透视相机&#xff09;2、裁剪空间&#xff08;左手坐标系、且转化为了齐次坐标&#xff09;3、屏幕空间&#xff08;把裁剪坐标归一化设置&#xff09;4、从观察空…

基于YOLOv8的遥感SAR舰船小目标识别

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;基于YOLOv8的遥感SAR舰船小目标&#xff0c;阐述了整个数据制作和训练可视化过程 1.YOLOv8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的…

【LangChain】与文档聊天:将OpenAI与LangChain集成的终极指南

欢迎来到人工智能的迷人世界&#xff0c;在那里&#xff0c;人与机器之间的通信越来越模糊。在这篇博客文章中&#xff0c;我们将探索人工智能驱动交互的一个令人兴奋的新前沿&#xff1a;与您的文本文档聊天&#xff01;借助OpenAI模型和创新的LangChain框架的强大组合&#x…

【2023 CCF 大数据与计算智能大赛】基于TPU平台实现超分辨率重建模型部署 基于FSRCNN的TPU平台超分辨率模型部署方案

2023 CCF 大数据与计算智能大赛 基于TPU平台实现超分辨率重建模型部署 基于FSRCNN的TPU平台超分辨率模型部署方案 WELL 刘渝 人工智能 研一 西安交通大学 中国-西安 1461003622qq.com 史政立 网络空间安全 研一 西安交通大学 中国-西安 1170774291qq.com 崔琳、张…

Vue - 实现文件导出文件保存下载

1 文件导出&#xff1a;使用XLSX插件 需求背景&#xff1a;纯前端导出&#xff0c;如 在前端页面勾选部分表格数据&#xff0c;点击"导出"按钮导出Excel文件。 实现思路&#xff1a; 1.通过XLSX插件的 XLSX.utils.book_new()方法&#xff0c;创建excel工作蒲对象wb…

Element UI之el-tabs的样式修改字体颜色、下划线、选中/未选中

目录 默认样式 修改默认字体颜色&#xff1a; 修改鼠标悬浮/选中字体颜色&#xff1a; 去掉长分割线并修改下划线颜色 完整代码 默认样式 注意事项&#xff1a;一定要在 <style scoped>不然修改的样式不会覆盖生效 修改默认字体颜色&#xff1a; ::v-deep .el-tabs__…

[鹏城杯 2022]简单包含

[鹏城杯 2022]简单包含 wp 题目代码如下&#xff1a; <?php highlight_file(__FILE__); include($_POST["flag"]); //flag in /var/www/html/flag.php; 直接 POST 传参&#xff1a; flag/var/www/html/flag.php 会触发 waf 。 尝试用伪协议读取&#xff1a; …

canvas绘制红绿灯路口

无图不欢&#xff0c;先上图 使用方法&#xff08;以vue3为例&#xff09; <template><canvas class"lane" ref"laneCanvas"></canvas> </template><script setup> import { ref, onMounted } from vue import Lane from …

C实现数组奇数在前偶数在后排序

一、运行结果&#xff1b; 二、源码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//实现调整函数move_odd_even函数&#xff1b; void move_odd_even(int arr[], int sz) {//初始化变量值&#xff1b;int left 0;int right sz - 1;//循环判断和…

CSP CCF 201312-2 ISBN号码 C++满分题解

解题思路&#xff1a; 1.用一个int数组单独存储每个数字&#xff1b;用char数组存储原始标识符串&#xff0c;方便输出 2.计算后得到标识码&#xff0c;判断是否正确 #include<iostream> using namespace std;int main() {int num[15]; //存储每个位置的数char arr[15…

【高性能篇】QPS概念、RT概念

什么是QPS&#xff0c;什么是RT&#xff1f; ✔️典型解析✔️扩展知识仓✔️RT ✔️QPS✔️ QPS和TPS✔️并发用户数✔️最佳线程数 ✔️典型解析 QPS&#xff0c;指的是系统每秒能处理的请求数(Query Per Second)&#xff0c;在Web应用中我们更关注的是Web应用每秒能处理的re…

Radar System Pro - Plug Play Solution

Radar System Pro是一款功能多样且可定制的资源,旨在通过功能齐全且易于使用的雷达系统增强您的Unity项目。无论您是在开发第一人称射击游戏、策略游戏还是太空探索模拟器,我们的雷达系统都将为您提供所需的工具,以创建引人入胜且身临其境的体验。 雷达系统是一个模块化资产…

2023年华为OD机试(python)B卷-符合要求的结对方式

一、题目 题目描述&#xff1a; 用一个数组A代表程序员的工作能力&#xff0c;公司想通过结对编程的方式提高员工的能力&#xff0c;假设结对后的能力为两个员工的能力之和&#xff0c;求一共有多少种结对方式使结对后能力为N。 二、输入输出 输入描述: 5 1 2 2 2 3 4 第一行为…

Unity 贝塞尔曲线工具获取运动轨迹

Unity 贝塞尔曲线工具获取运动轨迹 一、介绍贝塞尔曲线二、Unity中贝塞尔曲线工具介绍1.创建一个空物体挂在上BezierSpline.cs脚本组件2.由上图可知刚创建出来的有两个点和两个手柄组成3.我们可修改其坐标看下效果4.这样我们就可以获得这两个点之间的指定数量的点来作为某个物体…

openGauss学习笔记-177 openGauss 数据库运维-逻辑复制-逻辑解码-逻辑解码概述

文章目录 openGauss学习笔记-177 openGauss 数据库运维-逻辑复制-逻辑解码-逻辑解码概述177.1 功能描述177.2 注意事项177.3 性能 openGauss学习笔记-177 openGauss 数据库运维-逻辑复制-逻辑解码-逻辑解码概述 177.1 功能描述 openGauss对数据复制能力的支持情况为&#xff…