百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

深入理解javascript作用域系列第四篇——块作用域

myzbx 2024-12-07 15:12 19 浏览

前面的话

尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀、简洁的代码,比如块作用域。随着ES6的推广,块作用域也将用得越来越广泛。本文是深入理解javascript作用域系列第四篇——块作用域

let

for (var i= 0; i<10; i++) {
    console.log(i);
}

上面这段是很熟悉的循环代码,通常是因为只想在for循环内部的上下文中使用变量i,但实际上i可以在全局作用域中访问,污染了整个作用域

for (var i= 0; i<10; i++) {
     console.log(i);
}
console.log(i);//10

ES6改变了现状,引入了新的let关键字,提供了除var以外的另一种变量声明方式。let关键字可以将变量绑定到所在的任意作用域中(通常是{...}内部),实现块作用域

{
  let i = 1;  
};
console.log(i);//ReferenceError: i is not defined

块级作用域实际上可以替代立即执行匿名函数(IIFE)

(function{
  var i = 1;  
});
console.log(i);//ReferenceError: i is not defined

如果将文章最开始那段for循环的代码中变量i用let声明,将会避免作用域污染问题

for (let i= 0; i<10; i++) {
     console.log(i);
}
console.log(i);////ReferenceError: i is not defined

for循环头部的let不仅将i绑定到了for循环的块中,事实上它将其重新绑定到了循环的每一个迭代中,确保使用上一个循环迭代结束时的值重新进行赋值

//与上一段代码等价
{
    let j;
    for (j=0; j<10; j++) {
        let i = j; //每个迭代重新绑定
        console.log( i );
    }
}

循环

下面代码中,由于闭包只能取得包含函数中的任何变量的最后一个值,所以控制台输出5,而不是0

var a = ;
for(var i = 0; i < 5; i++){
    a[i] = function{
        return i;
    }
}
console.log(a[0]);//5

当然,可以通过函数传参,来保存每次循环的值

var a = ;
for(var i = 0; i < 5; i++){
    a[i] = (function(j){
        return function{
 return j;
        }
    })(i);
}
console.log(a[0]);//0

而使用let则更方便,由于let循环有一个重新赋值的过程,相当于保存了每一次循环时的值

var a = ;
for(let i = 0; i < 5; i++){
    a[i] = function{
        return i;
    }
}
console.log(a[0]);//0

重复声明

let不允许在相同作用域内,重复声明同一个变量

{
  let a = 10;
  var a = 1;//SyntaxError: Unexpected identifier
}
{
  let a = 10;
  let a = 1;//SyntaxError: Unexpected identifier
}

提升

使用let进行的声明不会在块作用域中进行提升

{
  console.log(i);//ReferenceError: i is not defined
  let i = 1;  
};

const

除了let以外,ES6还引入了const,同样可以用来创建块作用域变量,但其值是固定的(常量)。之后任何试图修改值的操作都会引起错误

if (true) {
    var a = 2;
    const b = 3; 
    a = 3; 
    b = 4;// TypeError: Assignment to constant variable
}
console.log( a ); // 3
console.log( b ); // ReferenceError: b is not defined

const声明的常量,也与let一样不可重复声明

const message = "Goodbye!";
const message = "Goodbye!";//SyntaxError: Identifier 'message' has already been declared

try

try-catch语句的一个常见用途是创建块级作用域,其中声明的变量仅仅在catch内部有效

{
    let a = 2;
    console.log(a); // 2
}
console.log(a); //ReferenceError: a is not defined

在ES6之前的环境中,可以使用try-catch语句达到上面代码的类似效果

try{
    throw 2;
}catch(a){
    console.log( a ); // 2
}
console.log( a ); //ReferenceError: a is not defined
//或者
try{
    throw undefined;
}catch(a){
    a = 2;
    console.log( a ); // 2
}
console.log( a ); //ReferenceError: a is not defined

相关推荐

Django零基础速成指南:快速打造带用户系统的博客平台

#python##服务器##API##编程##学习#不是所有教程都值得你花时间!这篇实战指南将用5分钟带你解锁Django核心技能,手把手教你从零搭建一个具备用户注册登录、文章管理功能的完整...

iOS 17.0 Bootstrap 1.2.9 半越狱来啦!更新两点

这款Bootstrap半越狱工具终于更新,离上一次更新已相隔很久,现在推出1.2.9版本,主要为内置两点功能进行更新,也是提升半越狱的稳定性。如果你正在使用这款半越狱工具的,建议你更新。注意!...

iOS 16.x Bootstrap 1.2.3 发布,支持运行清理工具

本文主要讲Bootstrap半越狱工具更新相关内容。如果你是iOS16.0至16.6.1和17.0系统的,想体验半越狱的果粉,请继续往下看。--知识点科普--Bootstrap...

SpringBoot整合工作流引擎Acticiti系统,适用于ERP、OA系统

今日推荐:SpringBoot整合工作流引擎Acticiti的源码推荐理由:1、SpringBoot整合工作流引擎Acticiti系统2、实现了三级权限结构3、持久层使用了mybatis框架4、流程包...

SpringCloud自定义Bootstrap配置指南

在SpringCloud中自定义Bootstrap配置需要以下步骤,以确保在应用启动的早期阶段加载自定义配置:1.添加依赖(针对新版本SpringCloud)从SpringCloud2020...

Python使用Dash开发网页应用(三)(python网页开发教程)

PlotlyDash开发Web应用示例一个好的网页设计通常都需要编写css甚至js来定制前端内容,例如非常流行的bootstrap框架。我们既然想使用Dash来搭建web应用,很大的一个原因是不熟悉...

Oxygen XML Editor 27.1 中的新功能

OxygenXMLEditor27.1版是面向内容作者、开发者、合作者和出版商的行业领先工具包的增量版本。在27.1版本中,AIPositronAssistant得到了增强,包括用于...

【LLM-多模态】Mini-Gemini:挖掘多模态视觉语言模型的潜力

一、结论写在前面论文提出了Mini-Gemini,一个精简而强大的多模态VLM框架。Mini-Gemini的本质在于通过战略性框架设计、丰富的数据质量和扩展的功能范围,发掘VLM的潜在能力。其核心是补...

谐云课堂 | 一文详解分布式改造理论与实战

01微服务与分布式什么是分布式?首先,我们对上图提到的部分关键词进行讲解。单体,是指一个进程完成全部的后端处理;水平拆分,是同一个后端多环境部署,他们都处理相同的内容,使用反向代理来均衡负载,这种也叫...

基于Abaqus的手动挡换挡机构可靠性仿真

手动挡,也称手动变速器,英文全称为Manualtransmission,简称MT,即用手拨动换挡操纵总成才能改变变速器内的齿轮啮合位置,改变传动比,从而达到变速的目的。家用轿车主要采用软轴连接的换挡...

【pytorch】目标检测:彻底搞懂YOLOv5详解

YOLOv5是GlennJocher等人研发,它是Ultralytics公司的开源项目。YOLOv5根据参数量分为了n、s、m、l、x五种类型,其参数量依次上升,当然了其效果也是越来越好。从2020...

超实用!50个非常实用的PS快捷键命令大全分享

今天,给大家介绍50个非常实用的快捷键命令大全,大家伙都是设计师,关于软件使用那是越快越好啊。一、常用的热键组合1、图层混合模式快捷键:正常(Shift+Option+N),正片叠底(Shif...

Pohtoshop中深藏不露的小技巧(科目一考试技巧记忆口诀看完必过)

邢帅教育ps教程为大家总结了一些Pohtoshop中深藏不露的小技巧,可以帮助到大家在设计时减少不必要的麻烦,提高工作效率哦~~~1.设置网格线保持像素完美不在1:1分辨率下也能保持像素完美,可以...

Ganglia监控安装总结(监控安装工作总结)

一、ganglia简介:Ganglia是一个跨平台可扩展的,高性能计算系统下的分布式监控系统,如集群和网格。它是基于分层设计,它使用广泛的技术,如XML数据代表,便携数据传输,RRDtool用于数据...

谁说Adobe XD做不出好看的设计?那是你没搞懂这些功能

AdobeXD的美化栏具有将设计视图美化的功能,它能使界面设计和原型设计更漂亮、更吸引眼球。美化栏的7个功能包括竖线布局设计、横线布局设计、重复网格、图形大小和位置设置、响应式调整大小、文字美化以及...