从项目中理解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去定义,一方面可以避免别人修改,一方面也可以提升编译器效率。
从项目中理解let和const为什么如此重要的更多相关文章
- 从项目中理解SSM框架
我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教学课堂中,也会把SSH作为最核心的教学内容. 但是,我们在实际应用中发现,SpringMVC可以完全替代Struts,配 ...
- 【J2EE】在项目中理解J2EE规范
J2EE平台由一整套服务(Service),应用程序接口(API)和协议构成,它对开发企业级应用提供了功能支持.13个核心技术各自是JDBC, JNDI, EJB, RMI, JSP ...
- 理解Redux以及如何在项目中的使用
今天我们来聊聊Redux,这篇文章是一个进阶的文章,建议大家先对redux的基础有一定的了解,在这里给大家推荐一下阮一峰老师的文章: http://www.ruanyifeng.com/blog/20 ...
- 理解java Web项目中的路径问题
本文以项目部署在tomcat服务器为例,其他相信也是一样的. 先说明请求页面的写法,在web中,页面路径主要写的有以下几种 1.请求重定向 2.浏览器的请求被服务器请求到新页面(我称为“转发”) 3. ...
- .NET抽象工厂模式微理解--教你在项目中实现抽象工厂
.NET抽象工厂模式微理解--教你在项目中实现抽象工厂 最近在学习MVC,对于MVC里面的一些项目上的东西都和抽象模式有关,今天就微说明一下个人对于抽象工厂模式的理解,以方便学习MVC及工厂模式相关的 ...
- 你真的理解 Spring Boot 项目中的 parent 吗?
前面和大伙聊了 Spring Boot 项目的三种创建方式,这三种创建方式,无论是哪一种,创建成功后,pom.xml 坐标文件中都有如下一段引用: <parent> <groupId ...
- SLAM+语音机器人DIY系列:(二)ROS入门——8.理解roslaunch在大型项目中的作用
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
- 记录ThreadPoolTaskExecutor线程池的在项目中的实际应用,讲解一下线程池的配置和参数理解。
前言:最近项目中与融360项目中接口对接,有反馈接口(也就是我们接收到请求,需要立即响应,并且还要有一个接口推送给他们其他计算结果),推送过程耗时.或者说两个接口不能是同时返回,有先后顺序. 这时我想 ...
- 理解JavaWeb项目中的路径问题——相对路径与绝对路径
背景: 在刚开始学习javaweb,使用servlet和jsp开发web项目的过程中,一直有一个问题困扰着我:servlet 和 jsp 之间相互跳转,跳转的路径应该如何书写,才能正确的访问到相应的s ...
随机推荐
- [BZOJ1042]AOI2008]硬币购物
题目描述 Description 硬币购物一共有4种硬币.面值分别为\(c_1\) ,\(c_2\) ,\(c_3\) ,\(c_4\) .某人去商店买东西,去了\(tot\) 次.每次带\(d_i\ ...
- Java连载51-super关键字
一.super关键字 我们先看一个例子 package com.bjpowernode.java_learning; public class D51_ { public static void ...
- 【STM32H7教程】第18章 STM32H7的GPIO应用之跑马灯
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第18章 STM32H7的GPIO应用之跑马灯 本 ...
- git分支合并创建切换
1. 场景描述 介绍下Git最新内容合并到主干.从主干创建最新分支.idea下切换最新分支,能在2分钟内完成git合并.分支创建以及在idea中完成切换,希望能帮到一些朋友. 2. 解决方案 从以下三 ...
- 【编译系统01】编译器 - 词法分析器(lexial)的设计思路
时间:2019/11/29 首先,词法分析器由一个扫描器与状态机组成. 一. 词法分析器整体设计流程 二.设计细节 1. code.txt: 我们假设读取下面文本 2.符号类型的设计 我们使用 enu ...
- Zabbix 系列文章
Zabbix 所有文章目录 本系列文章都基于 Zabbix 4.0 , Zabbix 4.0 是属于长期支持版本,其它的长期支持版本有 3.0 .2.2 . 官方已经有中文文档, 官方文档链接: Za ...
- MongoDB 修改数据Cannot change the size of a document in a capped collection: * != *"
MongoDB修改数据库数据的时候报错 原因: 集合被设置成了 固定集合 .固定集合的数据不能被修改.只能查找-删除-再插入,也就是创建集合的时候设置了capped参数为true 解决: 创建集合的时 ...
- MVC过滤器:自定义异常过滤器使用案例
在上一篇文章中讲解了自定义异常过滤器,这篇文章会结合工作中的真实案例讲解一下如何使用自定义异常过滤器. 一.需求 本案例要实现的功能需求:在发生异常时记录日志,日志内容包括发生异常的Controlle ...
- PLSQL 12 安装、连接Oracle
点击下载PLSQL,本次安装的PLSQL版本为12.0.7,建议安装64位. 下载PLSQL时,版本旁边会有个“Language pack”的链接,点击后左侧选择“Chinese”即可下载汉化包. 注 ...
- ECAMScript中的let和const
let与const命令都是用来在js中声明变量的,在使用上与var相似,但存在一些区别,下面先讲let同var的区别 let 怎么使用呢,同var一样,let 变量名 就可以声明了 区别一:其作 ...