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,一经查实,立即删除!

相关文章

Springcloud Alibaba 使用Canal将MySql数据实时同步到Elasticsearch

本篇文章在Springcloud Alibaba使用Canal将Mysql数据实时同步到Redis保证缓存的一致性-CSDN博客 基础上使用canal将mysql数据实时同步到Elasticsearch。 1. 数据库准备 CREATE DATABASE /*!32312 IF NOT EXISTS*/shop /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8m…

117. 填充每个节点的下一个右侧节点指针 II

层序遍历&#xff0c;有点类似这道题。 104. 二叉树的最大深度 /* // Definition for a Node. class Node {public int val;public Node left;public Node right;public Node next;public Node() {}public Node(int _val) {val _val;}public Node(int _val, Node _left, Node…

Spring的Bean你了解吗

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

Raid的介绍

一、RAID的介绍 1.什么是raid "RAID"一词是由David Patterson, Garth A. Gibson, Randy Katz 于1987年在加州大学伯克利分校发明的。在1988年6月SIGMOD会议上提交的论文"A Case for Redundant Arrays of Inexpensive Disks”"中提出&#xff0c;当时性能最…

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

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

Linux 赛题FTP配置

部署FTP站点&#xff08;匿名用户&#xff09; mkdir -p /var/ftp/文档中心 //创建目录 cd /var/ftp/文档中心 mkdir 产品技术文档 公司品牌宣传 常用软件工具 公司规章制度 chown -R ftp.ftp /var/ftp/文档中心 //修改所属主和所属组&#xff0c;避免用户无法读写目录中…

2024前端React最新面试题:React设计思想是什么?

React设计思想是什么&#xff1f; 回答思路&#xff1a;react的组件化-->react的数据驱动-->react的虚拟DOMreact的组件化数据驱动视图虚拟DOM 回答思路&#xff1a;react的组件化–>react的数据驱动–>react的虚拟DOM react的组件化 每个组件都符合开放封闭原则…

方案:智能分析网关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…

Swift学习笔记第二节:数组类型

1、代码 import Foundationlet arr1 [1, 2, 3, 4, 5, 6] let arr2 ["a", "b", "c", "d", "e", "f"] let arr3 [true, false, true] let arr4: Array<Int> [1, 2, 3] let arr5: [Int] [1, 2, 3] let a…

【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…

机器学习(三) -- 特征工程(更新中)

系列文章目录 未完待续…… 目录 系列文章目录 前言 tips&#xff1a;这里只是总结&#xff0c;不是教程哈。 “***”开头的是给好奇心重的宝宝看的&#xff0c;其实不太重要可以跳过。 此处以下所有内容均为暂定&#xff0c;因为我还没找到一个好的&#xff0c;让小白&…

第7章 1 异常处理

bug的由来及分类 p81 字符串形式表示的数字之间也可以比较大小 import re ageinput(年龄&#xff1a;) if age>18:print(age)列表的append操作每次只能添加一个元素&#xff1a; lst[] lst.append(A) lst.append(B) # lst.append(A,B) 错误python中的异常处理机制 p82 t…

mysql5.7 数据库主从同步实现

mysql5.7 数据库主从同步实现&#xff0c;实操环境&#xff1a;linux centos7 一&#xff0c;安装mysql5.7 1 配置MySql5.7的 Yum仓库配置 yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm2 安装mysql5.7 yum install -y mysql-c…

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

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