let:声明的是变量
1、不存在变量提升

// var 的情况
console.log(foo); // 输出undefined
var foo = 2; // let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

上面代码中,变量foo用var声明,会发生变量提升,即脚本开始运行时,变量foo已经存在了,但是没有值,所以会输出undefined。变量用let声明,不会发生变量提升。这表示在声明它之前,变量bar是不存在的,这时如果用到他,就会抛出一个错误。

2、暂时性死区,先声明在使用

var tmp = 123;

if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}

上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值报错,先声明再使用。

3、不允许重复声明

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

// 报错
function func() {
let a = 10;
var a = 1;
} // 报错
function func() {
let a = 10;
let a = 1;
}

4、块级作用域

ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

第一种场景,内层变量可能会覆盖外层变量

var tmp = new Date();

function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
} f(); // undefined

上面代码,if代码块的外部使用外层的tmp变量,内部使用内层的tmp变量。但是,函数f指向后,结果输出undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。

第二种场景,用来计数的循环变量泄露为全局变量。

var s = 'hello';

for (var i = 0; i < s.length; i++) {
console.log(s[i]);
} console.log(i); // 5

上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄漏成了全部变量。

ES6的块级作用域,let实际上为javascript新增的块级作用域。

function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}

上边代码,有两个代码块,都声明了变量n,运行后输出5。这表示外层代码块不受内层代码块的影响。如果两次都使用var定义变量n,最后输出的值才是10。

ES6 允许块级作用域的任意嵌套。

{{{{{let insane = 'Hello World'}}}}};

const:常量

const声明一个只读的常量。一旦声明,常量的值就不能改变。

const的作用域与let命令相同:只在声明所在的块级作用域内有效

const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

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

const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123 // 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

上面代码中,常量foo储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性

ES6 声明变量的六种方法
ES5 只有两种声明变量的方法:var命令和function命令。ES6 除了添加let和const命令,后面章节还会提到,另外两种声明变量的方法:import命令和class命令。所以,ES6 一共有 6 种声明变量的方法。

let和const的相同点:
① 只在声明所在的块级作用域内有效。

② 不提升,同时存在暂时性死区,只能在声明的位置后面使用。

③ 不可重复声明。

let和const的不同点:
① let声明的变量可以改变,值和类型都可以改变;const声明的常量不可以改变,这意味着,const一旦声明,就必须立即初始化,不能以后再赋值

const i ; // 报错,一旦声明,就必须立即初始化
const j = 5;
j = 10; // 报错,常量不可以改变

② 数组和对象等复合类型的变量,变量名不指向数据,而是指向数据所在的地址。const只保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个复合类型的变量声明为常量必须非常小心。

const arr = [];
// 报错,[1,2,3]与[]不是同一个地址
arr = [1,2,3];
const arr = [];
// 不报错,变量名arr指向的地址不变,只是数据改变
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
console.log(arr.length); // 输出:3

若想让定义的对象或数组的数据也不能改变,可以使用object.freeze(arr)进行冻结。冻结指的是不能向这个对象或数组添加新的属性,不能修改已有属性的值,不能删除已有属性。

const arr = [];
Object.freeze(arr);
// 不报错,但数据改变无效
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
console.log(arr.length); // 输出:0

Let和Const区别,详细版本的更多相关文章

  1. C++中引用与指针的区别(详细介绍)

    C++中引用与指针的区别(详细介绍) C++中的引用与指针的区别   指向不同类型的指针的区别在于指针类型可以知道编译器解释某个特定地址(指针指向的地址)中的内存内容及大小,而void*指针则只表示一 ...

  2. bower 和 npm 的区别详细介绍

    摘要: 本文讲的是bower 和 npm 的区别详细介绍, 简单的说,npm是进行后端开发中,使用的模块安装工具,而bower,是前端的模块安装工具. 比如,在安装express,socket.io时 ...

  3. 2018/03/08 每日一学PHP 之 常量defind 和 const区别

    常量defind 和 const区别 什么是常量? 如字面理解的,在脚本执行期间不可改变的的量. 定义一个常量应该注意的事项? 1:常量默认大小写敏感,错误的大小写不会被识别为常量. 2:常量只能是标 ...

  4. let、var、const区别(表格比较)

    let.var.const区别(表格比较): 区别项 let var const 作用域 块级作用域 全局作用域或函数作用域 块级作用域 是否有变量提升 无 有 无 是否可重复声明 不可 可以 不可 ...

  5. (转)全局变量、extern/static/const区别与联系

    全局变量.extern/static/const区别与联系 编译单元(模块):     在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LIN ...

  6. MySQL与Oracle的语法区别详细对比

    MySQL与Oracle的语法区别详细对比 Oracle和mysql的一些简单命令对比在本文中将会涉及到很多的实例,感兴趣的你不妨学习一下,就当巩固自己的知识了   Oracle和mysql的一些简单 ...

  7. var、let和const区别

    var.let和const区别 变量提升问题 var声明的变量存在变量提升,而let与const声明的变量不存在变量提升,但存在暂时性死区 即在预编译阶段,js引擎扫描代码时,遇到变量声明,会把var ...

  8. RabbitMQ安装说明文档(超详细版本)

    RabbitMQ安装说明文档(超详细版本) 1. 安装依赖环境 在线安装依赖环境: yum install build-essential openssl openssl-devel unixODBC ...

  9. PHP中的Define和Const区别

    我们经常把不经常变的值定义成常量,常量一般用全部大写来表示,前面不加美元符号,那么define和const有什么区别呢? 常量是一个简单的标识符.在脚本执行期间该值不能改变(除了所谓的魔术常量,他们其 ...

  10. C/C++的const区别

    1.const基础知识(用法.含义.好处) int main() { const int a; //a为const,常数型数 int const b; //b为const,常数型数 const int ...

随机推荐

  1. Python基础数据类型-Tuple(元组)

    a = () b = (1) # 不是元组类型,是int型 c = (1,) # 只有一个元素的时候,要加逗号才能表示是元组 d = (1, 2, 3, 4, 5, 6, 1) print(type( ...

  2. Django基础篇 06-Django模板过滤器Filter和标签Tags

    一.Django模板的内置过滤器Filter 什么是模板(Template)? Django的Template是如何工作的 Django的模板是静态的html文件,它只决定了一个页面的样式或外观.它需 ...

  3. loadrunner 11

    1  环境windows server 2012  2019 的.net 时, 服务器管理器--仪表板--勾选.net后报错? 其中一个办法就是将服务器临时联网,就能安装成功. 2   联机时 提示如 ...

  4. c++学习2 基础关键词

    三 volatile强制访问内存 在一个变量的频繁使用中,系统为了提高效率,会自动将内存里面的数据放入CPU里的寄存器里.但在某些特殊场景下,放入寄存器这个操作反倒会导致CPU无法及时获取最新的一手数 ...

  5. IDEA 2018.3.*本地启动tomcat项目无法设置Application context localhost 404

    记录一个开发中遇到的坑,网上找了好久才找到一个能解决的办法,特此转载一下. 旧版的idea启动web项目,在tomcat配置环节,有设置Application content的功能.我们可以设置成&q ...

  6. uniapp中使用AntV F6 + table表格插件使用

    首先看页面效果: AntV官网下载F6文件到项目中与uViewUI插件 <template> <view class="page"> <!-- 导航栏 ...

  7. OSIDP-并发:互斥和同步-05

    进程和线程的管理 多道程序设计:管理单处理器系统中的多个进程. 多处理器技术:管理多处理器系统中的多个进程. 分布式处理器技术:管理分布式环境下的多个进程. 并发出现的三种环境 多应用程序:多个运行中 ...

  8. linux-usermod

    添加组成员 sudo usermod -aG <targetgroup> <selfuser>

  9. redis缓存lua脚本过多导致内存占用很多问题

    现象 生产某集群各节点已使用内存比较大,在清理了大量业务无用数据后,节点已使用内存却未下降. 排查与分析 通过info memory命令查看,内存碎片率略高,但是对某个主节点新添加的从节点内存使用依然 ...

  10. 记录一次HAWQ手工启动

    一.环境变量初始化 使用hawq的命令必须先进行环境变量的初始化 命令不能以 root 用户执行,应该以 gpadmin 用户执行 source /usr/local/apache-hawq/gree ...