从项目中理解let和const为什么如此重要

变量声明

变量声明方式

伴随js诞生的var

// 语法  var varName = value
var a = 1  // 这样子你就得到了一个变量

var缺陷场景分析

var specialUser = "cj"; // 在A文件定义

var specialUser = "fk"; // A文件很大,你没去寻找是否定义此变量,直接定义

getImportantInformation(specialUser); // 在B文件定义

我们在定义一个变量,通常是跳过检查是否已经定义了此变量,尤其在编写局部代码时,这就更加容易导致了命名引起的重复定义,导致一些核心变量被覆盖,造成系统重大破坏,在上面的例子,就会因为spcialUser变量导致系统使用到该变量的地方全部行为异常,人要学会偷懒,是否定义此变量,编译器能够知道,为什么要我们程序员去定义变量前,还要在项目文件下查找此变量是否定义呢,代码编译时,如果有此变量的定义,直接告诉我们冲突,我们根据需要更换就好

js规范为了操碎了心,let的诞生了

其实上述覆盖掉了核心变量,我是在业务上遇到过的,估计不少程序猿遇到这种事情,然后ECMAScript官方就出来了,所有js语言的解释器,必须实现新的变量声明方式,帮助我们省下覆盖变量的操心。

let name = "cj"; // 无论在何处定义
let name = "cj"; // 如果此变量在此作用域找了let name 这样的,编译器就会说,你这个名字用过了,要换个名字。

如果变量定义作用域有了同名的变量,解释器就会告诉你,你和别人重名了,需要换名字,有了let从此就不用再担心原先的变量被覆盖了,放心定义变量即可,很舒服。

不止如此,var反常行为

在我们学习变量时,老师就会说,变量要先定义再访问,我们不服输,尝试一下先访问再定义

console.log(name)  // 咦? 为什么不会报错
var name = "cj"

嗯?此时js与老师的教导出现了冲突,没错,是老师错了,js可是个反常识的东西,当初为啥这样设计呢,不得而知,但是这里,可是增加了变量的使用成本,为什么这样说呢

code 1
code 2  //

var name = 1 // code 2 定义的变量,

有一天我们想在code1引用这个变量,也许会去搜索这个变量是否在code1前定义的,这是为了code1能够正常访问name,好的,你没猜错,我们又可以让编译器这个工具帮我们处理这件事,如果我们在定义变量之前访问变量,让编译器通知我们这里不能访问

console.log(name)
let name = "cj"

看到这熟悉的提示,喔,原来我们在定义变量之前访问了变量,这时候我们就修改一下代码调用顺序,其实,这种机制也保证了代码的显式调用顺序的健壮

console.log(name)   // 嗯? 不行?
let name = "cj"

console.log(name)  // 这样才对
let name = "cj"

不受控制的var

由于程序少则几百行,我们公司大就几十万行,这就出现了人的名字的管理问题,如何解决重名问题呢,在此基础上拓展新的标识是一个不错的方法,比如中国很多重名的,地址就是一个额外标记的好东西,我们程序也在内存里分块,但是这不是重点,在内存上一层的抽象,语言有一个叫做作用域的东西,相当于把程序分成不同的城市一般来说变量被限制在这些块里,通过这种方式,我们很多通用的变量名得以大量使用而不冲突,因为它们不属于一个块,想象一下,如果中国只有一个城市,那么同名的人就可能得叫支付宝-1 支付宝-2了,变量在这种情况下也是一样,需要大量前缀,所以作用域的作用可想而知,当然作用域的设计来源复杂多,嘻嘻,以后有空研究下,

if(condition) {
  var a = 11;
}
var a = 33  // 此时我想在if外面的作用域定义了一个变量,却以不小心覆盖了if内部的变量a,导致程序异常

上述代码还有致命问题,一般来说,我们在不同作用域定义变量是互不影响的,但是上面的代码却违反了这个规则,倒置变量可能的异常,上述代码在同步场景下,基本没什么影响,在异步场景就会因为后者定义覆盖的问题导致程序异常

if(true) {
  var a = 3
    setTimeout(  () =>  {
      console.log(a) //  5而不是3
    }, 0)
}
var a = 5

let 就使得js拥有了真正的块作用域

if(true) {
  let a = 3
    setTimeout(  () =>  {
      console.log(a) //  3
    }, 0)
}
let a = 5

let遗漏的场景

let PI = 3.14

PI = 3.14132

有时候我们需要定义一个变量,在很多地方使用,但是由于这个变量很重要,所以后续有对它的修改,都是会对程序造成破坏,我们不希望,但是,当我们对一个变量赋值时,怎么知道其是不能修改的呢,嗯,只能阅读源码,确定其重要性,这样费事费力,能让我们的工具人编译器帮助我们吗,是的,它做到了

const PI = 3.14
PI = 3.14132

在我们想修改一些值时,如果作者有使用const标记为不可修改变量,那么我们修改时,编译器就会告诉我们,嘿,兄弟,动了这个变量系统就会挂掉,真是棒极了。

总结

在新的语法大环境下,大家尽可能使用let 去定义变量,在这基础上,如果是不需要改变的变量,可以使用const去定义,一方面可以避免别人修改,一方面也可以提升编译器效率。

原文地址:https://www.cnblogs.com/sefaultment/p/11518271.html

时间: 2024-10-17 05:46:28

从项目中理解let和const为什么如此重要的相关文章

【J2EE】在项目中理解J2EE规范

J2EE平台由一整套服务(Service),应用程序接口(API)和协议构成,它对开发企业级应用提供了功能支持.13个核心技术分别是JDBC, JNDI, EJB, RMI, JSP, SERVLET, XML, JMS, JAVAIDL/CORBA, JTS, JTA, JAVAMAIL和 JAF. 何为企业级应用? 1.数据量特别大. 2.用户特别多. 3.性能要求高. 4.安全性要求高. 5.生命周期长. 这时候我们就要考虑数据存储和查询的问题,系统访问快慢即性能问题,如何使用事务保证安全

理解Redux以及如何在项目中的使用

今天我们来聊聊Redux,这篇文章是一个进阶的文章,建议大家先对redux的基础有一定的了解,在这里给大家推荐一下阮一峰老师的文章: http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html 对于基础部分我在这里稍微讲解一下 首先我们要知道我们为什么要使用Redux,我们在什么情况下才需要去使用Redux,在这里引用Redux的创造者的一句话:"只有遇到 React 实在解决不了的问题,你才需

理解java Web项目中的路径问题

本文以项目部署在tomcat服务器为例,其他相信也是一样的. 先说明请求页面的写法,在web中,页面路径主要写的有以下几种 1.请求重定向 2.浏览器的请求被服务器请求到新页面(我称为“转发”) 3.超链接 4.form表单提交的action 为了演示路径写法,首先先建一个项目(项目名WebPath),并建立一个servlet(PathServlet) 目录结构如下 以访问目录中index.jsp文件为例,jxf.path.PathServlet.jave中对以上四种路径的写法(红色部分) 1

记录一次线程池的在项目中的实际应用,讲解一下线程池的配置和参数理解。

前言:最近项目中与融360项目中接口对接,有反馈接口(也就是我们接收到请求,需要立即响应,并且还要有一个接口推送给他们其他计算结果),推送过程耗时.或者说两个接口不能是同时返回,有先后顺序. 这时我想到了把自己Controller立即返回接受成功,中间添加一个新的线程去做其他耗时的操作(线程池配置和参数测试讲解请阅读第5步). 1.Controller代码如下: @Autowiredprivate CallThreadDemo worker; @RequestMapping("/bandBank

SLAM+语音机器人DIY系列:(二)ROS入门——8.理解roslaunch在大型项目中的作用

摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人"miiboo"中的大部分程序也采用ROS进行开发,所以本文就重点对ROS基础知识进行详细的讲解,给不熟悉ROS的朋友起到一个抛砖引玉的作用.本章节主要内容: 1.ROS是什么 2.ROS系统整体架构 3.在ubuntu16.04中安装ROS kinetic 4.如何编写ROS的第一个程序hello_world 5.编写简单的消息发布器和订阅器 6.编写简单的s

c++ primer 中讲的顶层const 和 底层 const 理解

c++ primer 中讲的    顶层const 和 底层 const   以前没搞懂的顶层const和底层const,这次看了后感觉明白了. 首先,const是一个限定符,被它修饰的变量的值不能改变. 对于一般的变量来说,其实没有顶层const和底层const的区别,    而只有向指针这类复合类型的基本变量,才有这样的区别. 一 如何区分顶层const和底层const 指针如果添加const修饰符时有两种情况: 1 指向常量的指针:代表不能改变其指向内容的指针.声明时const可以放在类型

如何去除vue项目中的 # --- History模式

使用vue-cli搭建的环境,在配置好路由之后,可以看到下面的情况: 但是不难发现#的出现真的很丑陋,并且也不知道这是什么作用? 所以就去Stack Overflow上搜索了,果然还有~  看来Stack Overflow是真的强大,你在项目中遇到的问题实际上在so上都已经被问过并且解决了,这不:    这是最高票的回答,即在vue2中将mode模式设置为history,试过之后确实奏效! 但是知道这样可以解决问题,却不知道为什么,这是不行的, 随着连接,我们看到了文档. 所以这篇文章也就是引申

项目中进度条实现臆想

关于进度条的实现,主要把握点就是动态修改,且是行内缓冲更新. 关于这点就需要了解printf()的行缓冲问题了 可以做如下验证 #include <stdio.h> #include <stdlib.h> int main() { // printf("test"); case1:3秒后输出 printf("test\n"); //case2:立即输出 sleep(3); return 0; } 两个case的区别就在于\n了,所以问题的症结

C#项目中常用到的设计模式

1. 引言 一个项目的通常都是从Demo开始,不断为项目添加新的功能以及重构,也许刚开始的时候代码显得非常凌乱,毫无设计可言.但是随着项目的迭代,往往需要将很多相同功能的代码抽取出来,这也是设计模式的开始.熟练运用设计模式应该是每一个软件开发人员的必备技能.今天给大家介绍几个常用的设计模式. 2. 单例模式 单例模式恐怕是很多开发人员最先接触到的模式之一,可以认为就是一个全局变量.它的初始化过程无非就是一开始就new 一个instance,或者惰性初始化等需要用到的时候new 一个instanc