ES6学习笔记之let和const
Posted BennuCTech
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6学习笔记之let和const相关的知识,希望对你有一定的参考价值。
let
ES6 新增了let命令,不同于var,只在let命令所在的代码块内有效。比如:
let a = 10;
var b = 1;
a // ReferenceError: a is not defined.
b // 1
在代码块外a就是未声明的。
所以for循环计数器就很适合使用let。
不存在变量提升
var命令会发生“变量提升”,即变量可以在声明之前使用,值为undefined。
console.log(foo); // 输出undefined
var foo = 2;
这其实很奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
为了纠正这种现象,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
console.log(bar); // 报错ReferenceError
let bar = 2;
在let声明前变量是不存在的,所以使用就会报错。
暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。如
var tmp = 123;
if (true)
tmp = 'abc'; // ReferenceError
let tmp;
因为在语句块中let又声明了一个tmp,导致后者绑定这个块作用域,所以在let之前使用tmp就会报错。
这种情况,即在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
“暂时性死区”也意味着typeof不再是一个百分之百安全的操作。
typeof x; // ReferenceError
let x;
而如果一个变量根本没有被声明,那么typeof反而不会报错。
typeof undeclared_variable // "undefined"
undeclared_variable变量就是不存在,结果是undefined。
注意一些隐藏性的死区,如:
function bar(x = y, y = 2)
...
因为参数y在后面,所以x=y的时候还未声明,另外一个情况是:
let x = x;
同样x还未声明完就去获取x的值,这时候x是未定义的,但是用var就不会用报错
var x = x;
不允许重复声明
let不允许在相同作用域内,重复声明同一个变量。
function func()
let a = 10;
let a = 1;
这样就会报错,因此,也不能在函数内部重新声明参数。
function func(arg)
let arg;
func() // 报错
const
const声明的是常量,所以声明的同时必须初始化。与let相同只在块级作用域中有效,同样不能提升、存在暂时性死区、不可重复声明。
const如果声明的是对象,那么地址指向不会变,但是对象本身是可变的,比如添加属性。如果想将对象冻结,则需要使用Object.freeze
,如下:
const foo = Object.freeze();
// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;
如果想将对象的属性也冻结,下面是一个将对象彻底冻结的函数。
var constantize = (obj) =>
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) =>
if ( typeof obj[key] === 'object' )
constantize( obj[key] );
);
;
顶层对象
ES5 之中,顶层对象的属性与全局变量是等价的。
window.a = 1;
a = 2;
window.a // 2
这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误;其次,很容易不知不觉地就创建了全局变量;最后,顶层对象的属性是到处可以读写的,不利于模块化编程。
ES6改变这一点,同时为了保持兼容性,var和function声明的全局变量,依旧是顶层对象的属性;而let、const、class声明的全局变量,不属于顶层对象的属性。
var a = 1;
window.a // 1
let b = 1;
window.b // undefined
顶层对象还有一个问题,就是在各种实现中是不统一的,比如在浏览器中是window、在node中是global等等。有一个方法是使用this变量,但是也有局限性,比如在node和ES6环境中this返回的是当前模块。针对很难找到一种方法在所有情况下都获取到顶层对象,ES2020在语言标准的层面,引入globalThis作为顶层对象。也就是说,任何环境下,globalThis都是存在的,都可以从它拿到顶层对象,指向全局环境下的this。
关注公众号:BennuCTech,获取更多干货!
以上是关于ES6学习笔记之let和const的主要内容,如果未能解决你的问题,请参考以下文章
ECMAScript 6 入门学习笔记——let和const