• let命令

1)let声明的变量只在let命令所在的代码块内有效,如:
 
 {
let a = ;
var b = ;} a // ReferenceError: a is not defined.
b //
对于for循环计数器,如果使用var声明,
 
 var a = [];for (var i = ; i < ; i++) {
a[i] = function () {
console.log(i);
};}
a[](); //
a[]的结果是最后一轮的i值,而使用let时a[]的值则为6
var a = [];for (let i = ; i < ; i++) {
a[i] = function () {
console.log(i);
};}
a[](); //
2)let不像var那样会发生“变量提升”现象,所以,变量一点要在声明之后使用。
3)暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”这个区域,不在受外部的影响。
在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称TDZ)。
 
ES6规定暂时性死区和不存在变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。
 
4)不允许重复声明
let不允许在相同作用域内重复声明同一个变量。
 
// 报错
function () {
let a = ;
var a = ;}
// 报错
function () {
let a = ;
let a = ;}
  • 块级作用域

ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
第一种场景,内层变量可能会覆盖外层变量。
 
 var tmp = new Date();

 function f() {
console.log(tmp);
if (false) {
var tmp = "hello world";
}} f(); // undefined
上面代码中,函数f执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。
第二种场景,用来计数的循环变量泄漏为全局变量。

 var s = 'hello';

 for (var i = 0; i < s.length; i++) {
console.log(s[i]);} console.log(i); //
上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。
而let实际上为JavaScript新增了块级作用域。
 
 function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); //
}
上面的函数有两个代码块,都声明了变量n,运行后输出5。这表示外层代码块不受内层代码块的影响。如果使用var定义变量n,最后输出的值就是10。
  • ES6允许块级作用域的任意嵌套
  • 内层作用域可以定义外层作用域的同名变量
  • 块级作用域的出现,实际上使得立即执行匿名函数(IIFE)不再必要了。
 // IIFE写法
(function () {
var tmp = ...;
...}());
// 块级作用域写法
{
let tmp = ...;
...}
  • 块级作用域与函数声明

ES6引入了块级作用域,明确允许在块级作
用域之中声明函数,并且在块级作用域中函数声明的语句类似于let,在块级作用域之外不可引用。
ES6的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
 
 // 不报错
'use strict';if (true) {
function f() {}}
// 报错
'use strict';if (true)
function f() {}
  • const命令

const声明一个只读的常量。一旦声明,常量值就不能改变。这样意味着,const一旦声明变量就必须立即初始化,不能留到以后赋值。
 const foo;
// SyntaxError: Missing initializer in const declaration

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

const声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const也不可重复声明。
对于符合类型的变量,变量名不指向数据,而是指向数据所在的地址。const命令指示保证变量名指向的地址不变,并不保证改地址的数据不变,所以将一个对象声明为常量必须非常小心。
 const foo = {};
foo.prop = 123; foo.prop
// foo = {}; // TypeError: "foo" is read-only
如果想将对象冻结,应该使用Object.freeze方法 const foo = Object.freeze({});
// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;

除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。

 
 var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, value) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
});};
ES6一共有6种声明变量的方法:var function let const import class
 
  • 全局对象的属性

全局对象是最顶层的对象,在浏览器环境中是指window对象,在Node.js中是global对象。在ES5中全局对象的属性与全局变量是等价的。
在ES6中,为了保持兼容性,var命令和function命令声明的全局变量依旧是全局对象的属性;另一方面:let和const以及class声明的全局变量不属于全局对象的属性。从ES6开始,全局变量将逐步与全局对象的属性脱钩。
 
 var a = 1;
// 如果在Node的REPL环境,可以写成global.a
// 或者采用通用方法,写成this.a
window.a //
let b = 1;
window.b // undefined
上面代码中,全局变量a由var命令声明,所以它是全局对象的属性;全局变量b由let命令声明,所以它不是全局对象的属性,返回undefined。
 

1 let和const的更多相关文章

  1. openssl 1.1.1 reference

    openssl 1.1.1 include/openssl aes.h: # define HEADER_AES_H aes.h: # define AES_ENCRYPT 1 aes.h: # de ...

  2. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  3. C++中的const

    一,C++中const的基本知识 1.C++中const的基本概念 1.const是定义常量的关键字,表示只读,不可以修改. 2.const在定义常量的时候必须要初始化,否则报错,因为常量无法修改,只 ...

  4. const extern static 终极指南

    const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...

  5. const let,console.log('a',a)跟console.log('a'+a)的区别

    const 创建一个只读的常量 let块级作用域 const let重复赋值都会报错 console.log('a',a) a console.log('a'+a) a2 逗号的值会有空格:用加号的值 ...

  6. es6之let和const

    在javascript中,我们都知道使用var来声明变量.javascript是函数级作用域,函数内可以访问函数外的变量,函数外不能访问函数内的变量. 函数级作用域会导致一些问题就是某些代码块内的变量 ...

  7. construction const parameter问题 构造函数const引用参数问题

    工程在window下编译没有任何问题, 但是在linux(CentOS6)下编译就老是报错 C++ 编译器已升级到最新版 6.1.0 错误如下: In file included /bits/stl_ ...

  8. Error:const char* 类型的实参和LPCWSTR类型的形参不兼容的解决方法。

    在C++的Windows 应用程序中经常碰到这种情况. 解决方法: 加入如下转换函数: LPCWSTR stringToLPCWSTR(std::string orig) { size_t origs ...

  9. C#基础知识七之const和readonly关键字

    前言 不知道大家对const和readonly关键字两者的区别了解多少,如果你也不是很清楚的话,那就一起来探讨吧!探讨之前我们先来了解静态常量和动态常量. 静态常量 所谓静态常量就是在编译期间会对变量 ...

  10. const 与 readonly知多少

    原文地址: http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 尽管你写了很多年的C#的代码,但是可能当别人问到你cons ...

随机推荐

  1. TensorBoard的使用(结合线性模型)

    TensorBoard是TensorFlow 的可视化工具.主要为了更方便用户理解 TensorFlow 程序.调试与优化,用户可以用 TensorBoard 来展现 TensorFlow 图像,绘制 ...

  2. C#中的异步学习

    C#中的异步 C#5.0版本发布有一个"主题那就是异步编程. 我们先创建一个windowForm窗体,实现下面效果,然后我们通过简单的案例对比同步和异步: 首先我们编写一个耗时方法: /// ...

  3. C语言中不同变量的访问方式

    C语言中的变量大致可以分为全局变量,局部变量,堆变量和静态局部变量,这些不同的变量存储在不同的位置,有不同的生命周期.一般程序将内存分为数据段.代码段.栈段.堆段,这几类变量存储在不同的段中,造成了它 ...

  4. 基于FPGA驱动VGA显示图片的小问题

    学习VGA显示图片的过程中,遇到了一个小问题,我在显示屏上开了一个60x60的框,放了一张图片进去显示,但是最终的结果如下图所示. 出现了一个竖黑边,看了看代码,分析了一下逻辑没问题,然而看这个显示那 ...

  5. centos6.x升级protobuf操作流程.

    1.首先卸载protobuf,使用命令如下: sudo yum remove protobuf 2.下载protobuf源,依据自己的需要下载: 2.1下载地址:https://github.com/ ...

  6. C/C++中__builtin_popcount()的使用及原理

    __builtin_popcount()用于计算一个 32 位无符号整数有多少个位为1 Counting out the bits     可以很容易的判断一个数是不是2的幂次:清除最低的1位(见上面 ...

  7. Codeforces 834E The Bakery【枚举+数位dp】

    E. Ever-Hungry Krakozyabra time limit per test:1 second memory limit per test:256 megabytes input:st ...

  8. 并查集-HDU1232-畅通工程

    转的其他人的.不知道谁的. 来看一个实例,杭电1232畅通工程 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比如随意 ...

  9. hdu_1006 Tick and Tick(暴力模拟)

    hdu1006 标签(空格分隔): 暴力枚举 好久没有打题了,退队了有好几个月了,从心底不依赖那个人了,原来以为的爱情戏原来都只是我的独角戏.之前的我有时候好希望有个人出现,告诉自己去哪里,做什么,哪 ...

  10. linux 操作系统/xxx目录下都是什么文件?

    /bin:存放最常用命令: /dev:设备文件: /etc:存放各种配置文件: /home:用户主目录: /lib:系统最基本的动态链接共享库: /mnt:一般是空的,用来临时挂载别的文件系统: /b ...