关于JS作用域浅析

在JS中定义变量有3个标识符,即var、let与const,其中let与const是ES6标准中引入的。在ES5及以下版本,JS作用域只有全局作用域与局部作用域,而在ES6中引入了块状作用域(主要是针对let与const而言,而var不受此限)。

    一、三种作用域定义

全局作用域,是指window对象作用范围内所属,也就是<script>标签内部和JS脚本文件中定义的变量。在全局作用域中定义的变量、属性及方法为window对象调用,在此定义的变量为浏览器页面所创建,生命周期为页面存续期间。

局部作用域,是指在函数体内所属,包括有名函数体、匿名函数体和箭头函数体内定义的变量。在此定义的变量,为函数体对象调用函数体期间创建,当执行完成后变量随函数体对象一起销毁,不复存在。

块状作用域,是指在字符“{”和“}”中之间区域,包括除函数体{}外的所有其他{}间,如if{}、else if{}、else{}、for{}、while{}、switch{}、do{}以及单独{}等。此作用域对var来说,不起作用,其内的变量作用范围由当前{}的上一级作用域决定,隶属于上一级作用域。但对let和const而言,当前{}就相当于其上一级作用域的下一级作用域,以它们定义的变量只能在当前{}中使用,外面不能使用。

    二、三种变量标识符用法理解

(一)var变量标识符

1.var由于提升机制,在整个作用域内都可调用

用var定义的变量(如果不指定标识符默认为var定义),无论其是在当前作用域(指全局或局部作用域)的哪里声明的,在JS预编译时都会将其提升到当前作用域的顶部,这即所谓的Hoisting提升机制。

function getValue(condition){

              console.log("作用域顶部"+value);//输出结果:作用域顶部undefined

       if(condition){

              var value="blue";

              console.log("if"+value);//输出结果:ifblue

       }else{

              console.log("else"+value);//由于conditon为真,此处无输出

       }

              console.log("作用域尾部"+value);//输出结果:作用域尾部blue

};

getValue(true);

由于var提升机制,块状作用域对var不起作用,其处于函数体作用域,因此对于if(condiion)是否为true,都将创建var,相当于在if块状体前就创建了var,只不过没有赋值,为undefined状态。

2.var可以使用上一级作用域变量,不能使用下一级作用域内变量

    var top="上一级变量";

       function show(){

              var buttom="下一级变量";

              console.log(top);//输出结果:上一级变量

       }

       show();

       console.log(buttom);//输出结果:出现错误,提示buttom is not defined

    3.var在不同作用域定义相同变量名,是具有不同的取值作用

    var msg="全局作用域msg";

       function show(){

              var msg="局部作用域msg";//当局部作用域有msg时,就取局部作用域的变量,没有时再取上一级相同变量

              console.log(msg);//输出结果:局部作用域msg

       }

       show();

       console.log(msg);//输出结果:全局作用域msg

4.var是可以在当前作用域中重复定义(或多次赋值)的,只取最后一次定义(赋值),

var msg="第一次定义msg";

var msg="第二次定义msg";

console.log(msg);//输出结果:第二次定义msg

msg="改变msg值";

console.log(msg);//输出结果:改变msg值

    (二)let变量标识符

1.let变量不存在提升机制,因此要注意定义及访问位置

function show(){

       //在定义之后访问

       let one="第一个变量";

       console.log(one);//输出结果:第一个变量

       //在定义之前访问

       console.log(two);//输出结果:出现错误,提示Cannot access 'two' before initialization

       let two="第二个变量";

}

show();

2.let变量不能进行重复定义,也不能与var变量名相同,将抛出错误

//var与let不能定义相同名变量

var msg="用var定义的msg";

let msg="用let定义msg";

console.log(msg);//输出结果:抛出错误,提示Identifier 'msg' has already been declared

//let不能重复定义

let msg="用let第一次定义msg";

let msg="用let第二次定义msg";

console.log(msg);//输出结果:抛出错误,提示Identifier 'msg' has already been declared

    3.let变量可多次赋值,取最后一次赋值结果

let msg="定义msg";

msg="改变msg值1";

       msg="改变msg值2";

       console.log(msg);//输出结果:改变msg值2

4.let变量的临时死区(TDZ)特性

所谓临时死区(TDZ)特性,是块状作用域的独有特性。由于块状作用域是针对let和const声明的,而不针对var。如果也让块状作用域中的let、const变量也象var将它们提升到上一级作用域,当块状作用域完成执行后,还保存在内存中就会造成内存浪费及上一级作用域再定义相同变量时出现let、const重复定义错误。因而,在块状作用域中,var变量实际上是提升至块状作用域的上一级中,而let、const则放在块状态作用域专门开辟的死区(TDZ)中,当块状作用域完成执行后,它的死区(TDZ)随即销毁。对其理解,请看下面两个实例。

//当在块状态作用内访问未先定义的let变量会报错

if(true){

       console.log(typeof value);//输出结果:报错,提示Cannot access 'value' before initialization

       let value="blue";

}

//而当在块状态作用外,访问未先定义的变量不会报错,系统会默认创造一个var类型的变量,只是未初始化

console.log(typeof value);//输出结果:undefined

if(true){

       let value="blue";

}

5.let变量在全局作用域中的特性

let和const与var在全局作用域中的是不一样的,var在全局作用域时,它会创建一个新的全局window对象的属性,这意味着用var很可能会无意中覆盖一个已经存在的全局属性(相同变量名)。

//var变量在全局作用域中定义,可会覆盖有相同变量名的变量

var RegExp="Hello!";

console.log(window.RegExp===RegExp);//输出结果:true

//let变量在全局作用域中定义,不会覆盖有相同变量名的变量

let RegExp="Hello!";

console.log(window.RegExp===RegExp);//输出结果:false

换句话说,在全局部作用域中,使用let、const定义变量的话,如域有相同变量名的变量,不会进行覆盖,只是创建一个新的绑定,只能是拦截遮蔽它,让它指向新的地址,而不会覆盖它。

    (三)const变量标识符

    1.具有上述let的1、2、4、5特性,可参照举例

2.const变量不能重复赋值

if(true){

const PI=3.14;

PI=3.1415;//出现报错,提示Assignment to constant variable.

console.log(PI);//由于前句出现报错,因此此句无执行

}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Java语言程序设计基础篇_编程练习题18.36 (思瑞平斯基三角形)

目录 题目&#xff1a;18.36 (思瑞平斯基三角形) 代码示例 代码逻辑 1. 应用程序入口 2. GUI设置 3. 事件处理 4. 绘制逻辑 5. 递归绘制 输出结果 题目&#xff1a;18.36 (思瑞平斯基三角形) 编写一个程序&#xff0c;让用户输入一个阶数&#xff0c;然后显示填充的…

送书!一大波LLM大模型学习教程书籍

最近整理了日前市面上一大波大模型的书&#xff0c;已经打包成pdf了&#xff0c;大家有需要的&#xff0c;可以自行添加获取&#xff0c;纯福利&#xff0c;无套路&#xff0c;添加后说明是哪本书&#xff0c;会直接给大家&#xff01; &#x1f449;CSDN大礼包&#x1f381;&a…

国产SSL证书品牌怎么选择?

有人在歪曲大型央国企“信创化”与数字化转型建设思路&#xff0c;为了自身的利益开始造谣一些虚假传播信息国外SSL证书不安全问题&#xff0c;然而国外的SSL证书每个上网用户都在使用&#xff0c;然而发布虚假广告的一些人实际上是换了个马甲贴个名字就叫国产SSL证书了&#x…

等保测评误区与应对:企业常见问题解析

标题&#xff1a;等保测评误区与应对&#xff1a;企业常见问题解析 信息安全等级保护&#xff08;等保&#xff09;测评是企业信息安全建设的重要组成部分&#xff0c;但在实际操作中&#xff0c;企业常会陷入一些误区。本文将解析企业等保测评中常见的误区&#xff0c;并提出…

【Python报错已解决】IndexError: list index out of range

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

Flutter 之 ftcon24usa 大会,创始人分享 Flutter 十年发展史,一闪而过的鸿蒙身影

之前一直关注 Fluttercon 的相关活动&#xff0c;正如 Flutter 3.24 发布时所说&#xff0c;继 Fluttercon 欧洲之后&#xff0c;近日 Fluttercon 2024 USA 在纽约如期举行&#xff0c;大会带来了一些有趣消息和 Flutter 发展历程&#xff0c;本次也是通过 X 和 OpenWebF 创始人…

免费ppt模板哪里找?职场必备这些利器

一眨眼&#xff0c;9月份的尾声渐近&#xff0c;无论是学生还是职场人士&#xff0c;都开始准备着新一轮的演讲和报告。在这个忙碌的时期&#xff0c;一份精美的PPT模板能够大幅提升你的工作效率&#xff0c;让你的演示更加引人入胜。 不用担心高昂的版权费用&#xff0c;市场…

什么是反射,反射用途,spring哪些地方用到了反射,我们项目中哪些地方用到了反射

3分钟搞懂Java反射 一、反射是什么 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的工具&#xff0c;它允许程序在运行时获取和操作类、接口、构造器、方法和字段等。反射是Java语言的一个重要特性&#xff0c;它为开发人员提供了许多灵活性&#xf…

单片机项目合集列表与专栏说明——Excel合集列表目录查阅(持续更新)

阿齐Archie《单片机项目合集》专栏项目 为方便查找本专栏的项目&#xff0c;特整理Excel合集列表供查阅&#xff08;可搜索或按系列查找&#xff09; 持续更新链接如下&#xff1a; 阿齐单片机项目合集 (kdocs.cn)https://www.kdocs.cn/l/cmrxCxJN05YN 打开链接如下Exce表所…

使用API有效率地管理Dynadot域名,注册域名服务器(NS)信息

前言 Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮箱&…

视频去水印 —— 释放创意,让学习与创作更自由!

&#x1f31f; 视频去水印 —— 释放创意&#xff0c;让学习与创作更自由&#xff01; 在这个短视频盛行的时代&#xff0c;抖音、快手、小红书等平台成为了创意与灵感的聚集地。你是否曾遇到过想要学习或进行二次创作&#xff0c;却被视频中的水印所困扰&#xff1f;现在&…

fo-dicom开发之DICOM数据解析:常见数据类型及处理方法详解

前言 前面的文章&#xff0c;我们介绍了fo-dicom是一个怎样的开源库&#xff1a;fo-dicom&#xff0c;第一个基于.NET Standard 2.0 开发的DICOM开源库&#xff0c;以及 学会使用fo-dicom前&#xff0c;了解其非常重要的基本概念&#xff0c;本次我们将了解&#xff0c;当进行…

力扣最热一百题——最小覆盖子串

目录 题目链接&#xff1a;76. 最小覆盖子串 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 提示&#xff1a; 解法一&#xff1a;滑动窗口 1. 初始化 2. 构建 mapT 3. 滑动窗口 4. checkT 方法 5. 返回结果 Java写法&#xff1a; 运行时间 C写法&#x…

人工智能与自然语言处理发展史

前言 在科技的浪潮中&#xff0c;人工智能 (AI) 作为一股不可阻挡的力量&#xff0c;持续推动着社会与科技的进步。本博客旨在深入剖析人工智能及其核心领域——神经网络、自然语言处理、统计语言模型、以及大规模语言模型——的演进历程&#xff0c;以专业的视角展现这一领域…

基于C语言开发(控制台)通讯录管理程序

通讯录程序设计 一、课程设计题目与要求 题目 &#xff1a;通讯录管理程序 1. 问题描述 编写一个简单的通讯录管理程序。通讯录记录有姓名&#xff0c;地址(省、市(县)、街道)&#xff0c;电话号码&#xff0c;邮政编码等四项。2. 基本要求 程序应提供的基本基本管理功能有…

豆包 MarsCode 代码练习体验

我最近体验了豆包MarsCode的代码练习&#xff0c;感觉非常棒&#xff01;首先&#xff0c;进入平台后&#xff0c;界面简洁明了&#xff0c;使用起来非常方便。选择内置题目时&#xff0c;题目类型丰富多样&#xff0c;涵盖了基础知识和一些进阶挑战&#xff0c;非常适合不同水…

【Kubernetes知识点】解读HPA的 thrashing(抖动)问题

【Kubernetes知识点】解读HPA的 thrashing&#xff08;抖动&#xff09;问题 目录 1 概念 1.1 什么是 Thrashing 现象&#xff1f;1.2 HPA 中 Thrashing 产生的原因1.3 解决 Thrashing 的优化措施 1.3.1 设置合适的阈值1.3.2 使用自定义指标和基于负载的自动扩缩1.3.3 增加扩…

探寻大模型时代智慧农业新未来,商汤与上海市农委达成战略合作

近日&#xff0c;在中国农民丰收节上海会场丰收庆典活动上&#xff0c;商汤科技与上海市农业农村委员会&#xff08;下称&#xff1a;上海市农委&#xff09;签署战略合作协议&#xff0c;双方将依托先进的AI大模型技术&#xff0c;共同推进上海智慧农业发展&#xff0c;打造国…

基向量和投影矩阵

文章目录 1. 投影向量2. 基向量&#xff0c;列向量秩1分解3. SVD&#xff0c;奇异向量秩1分解4. 小结&#xff1a;5. 图解分析 1. 投影向量 假设我们有一个向量b和一个向量q,求向量b在向量q上的投影向量p: 求向量p的长度&#xff1a; q T b ∣ q ∣ ⋅ ∣ b ∣ ⋅ cos ⁡ …

UNet 眼底血管分割实战教程

✨ Blog’s 主页: 白乐天_ξ( ✿&#xff1e;◡❛) &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山冈&#xff01; &#x1f4ab; 欢迎来到我的学习笔记&#xff01; 在医学影像分析领域&#xff0c;准确地分割眼底血管对于眼科疾病的诊断和治疗至关重要。…