es6之let和const命令的一些笔记
let和const命令
let命令
基本用法
let命令用来声明变量,声明的变量只在命令所在的代码块内有效。for循环中很适合使用let命令。
有必要理解的例子:
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
这里使用的var声明变量i,导致全局只有一个变量i,所以数组a的所有函数内部的console.log(i)里的i是最后一轮循环中i的值。也就是10,用let声明变量i能避免这个问题,使程序结果符合预期。
不存在变量提升
let不存在变量提升。使用var命令声明变量会发生变量提升,变量在声明前可以被使用,并且值为undefined。用let更符合我们的逻辑,用let声明的变量,要在声明之后才能使用,否则报错。
TDZ
在代码块内,使用let(或const)命令声明变量之前,该变量都是不可用的,在语法上,这称为"暂时性死区"(temporal dead zone)。
有必要理解的例子:
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
未声明的变量,使用typeof不会报错,返回undefined。若是在let声明之前使用typeof则会报错。
关于TDZ,还有一些难以被发现的例子:
unction bar(x = y, y = 2) {
return [x, y];
}
bar(); // 报错
//因为用y赋值给x,但此时y还没有声明,如果交换顺序则不会报错
function bar(x = 2, y = x) {
return [x, y];
}
bar(); // [2, 2]
//···························
// 不报错
var x = x;
// 报错
let x = x;
// ReferenceError: x is not defined
这提示我们,我们应该避免在变量完成声明之前使用它,养成良好的编程习惯。
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
不允许重复声明
在相同作用域内,let不允许重复声明一个对象。
块级作用域
如果没有块级作用域
ES5只有全局作用域和函数作用域,没有块级作用域。这会遇到一些问题。主要问题有2种:
- 内层变量覆盖外层变量。这是由于var声明的变量会发生变量提升,会导致一些容易忽视的问题。
- 在全局声明的变量在for循环之后依然存在。
//1.
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
//2.
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
ES6的块级作用域
let实际上就是ES6对块级作用域的实现。块级作用域的出现,使广泛应用的立即执行函数表达式(IIFE)不再必要了,用let就行了。
块级作用域与函数声明
避免在块级作用域内声明函数,因为环境的差异很大,会造出意想不到的效果。
es6的块级作用域允许声明函数的规则,只在使用大括号的情况下成立。否则报错。
do表达式
这个是提案中的语法。
const命令
基本用法
const用于声明只读的常量,不允许更改其的值。
同时意味着,用const声明变量需要在声明时初始化,后则报错。
const的作用域与let相同,只在声明的块级作用域中有效。
const声明的变量不发生变量提升,存在暂时性死区。
const和let都不可重复声明同一个变量。
本质
const保证变量指向的内存地址不得改动,而不是变量的值不得改动。所以对于复合类型的数据(如对象和数组),const变量保存的是指针,不能保证它指向的数据结构是不是可变的。
所以,我们声明一个对象为常量,仍然可以为它添加属性,不过不能让它指向另外一个对象。
如果真的想将对象冻结,应该使用Object.freeze方法。
严格模式下不能添加属性,会报错;非严格模式下,添加属性的语句不起作用。
ES6声明变量的6种方法
分别是var, function, let, const, import, class。
顶层对象的属性
在es6之前。顶层变量和全局变量是等价的。
例子:
window.a = 1;
a // 1
a = 2;
window.a // 2
es6为了改变这一设计缺陷,规定var和function声明的全局变量,依旧是顶层对象的属性。let, const, class命令声明的全局变量,不属于顶层对象的属性。
例子:
var a = 1;
// 如果在 Node 的 REPL 环境,可以写成 global.a
// 或者采用通用方法,写成 this.a
window.a // 1
let b = 1;
window.b // undefined
global对象
不同运行环境下,JavaScript的global对象是不一致的。
我们可以使用this变量在取到顶层对象,但是也存在一些问题。
- 全局环境中,this会返回顶层对象。node模块和es6模块中,this返回当前模块。
- 函数里面的this,如果函数不是作为对象的方法允许,而是单独作为函数运行,this会指向顶层对象。但,严格模式下,this是undefined。
- 如果浏览器用了CSP,new Function('return this')()无法使用。
es6之let和const命令的一些笔记的更多相关文章
- ES6 之 let和const命令 Symbol Promise对象
ECMAScript 6入门 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了. (2016年6月,发布了小幅修订的<ECMASc ...
- ES6中let与const命令详解
阮一峰ES6入门 let 作用域 let命令用来声明变量,但声明的变量只在let命令所在的代码块内有效. { let a = 10; var b = 1; } a // ReferenceError: ...
- ES6入门——let和const命令
let和const命令 1.let命令 用法:类似于var,用来声明一个变量,区别是所声明的变量只在let命令所在的代码块内有效. let命令很适合用在for循环的计数器中,因为let声明的变量仅在作 ...
- ES6的let和const命令
刚开始学习es6,心里有点方,因为看了前言,感觉要用什么bebal来翻译成es5的代码,才能在各个平台上兼容运行,还有node各种运行环境. 不过自己也去百度了一些,发现还是有一丢丢的困难. 言归正传 ...
- 2. ES6基础-let和const命令
目录 1. let命令 1.1 用法 1. 2 不存在变量提升 1.3 区域绑定 1.4 不允许重复声明 2. const命令 2.1 用法 2.2 与let类似的特性 2.3 const本质 2.4 ...
- ES6的let和const命令(一)
2019独角兽企业重金招聘Python工程师标准>>> ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变 量,只在let命令所在的代码块内有效. let ...
- ES6 let和const命令(3)
const 用来声明常量.一旦声明,就不能改变. const在声明必须初始化,只声明不赋值会出错 const的作用域与let一样,只在声明的块级作用域有效. const命令声明的常量也不提升,同样存在 ...
- ES6简介之let和const命令解说
一.var申明变量 学习过JavaScript的同学都应该知道,ES5中申明变量使用var,ES5中的var可以说是无所不能的,所有类型的变量都是由var来申明,但往往很多使用者不知道var申明的变量 ...
- ES6之新增const命令使用方法
hi,我又回来了,今天学习一下const命令. 声明一个常量 const声明一个只读常量,一旦声明,常量的值便不可改变. 例子如下: const food = 12; food = 23; // Un ...
随机推荐
- PHP判断变量是否为空的几种方法小结
1. isset功能:判断变量是否被初始化 说明:它并不会判断变量是否为空,并且可以用来判断数组中元素是否被定义过注意:当使用isset来判断数组元素是否被初始化过时,它的效率比array_key_e ...
- shell参数传递
应用实例: #!/bin/bash #运行:bash para_tran.bash text1.txt text2.txt #"set $1"设置存储传入的第一参数 #" ...
- traffic server文件目录
功能: Trafficserver的主要功能是缓存,当然你也可以用它来做纯粹的反向代理(像通常用nginx那样).通常切入一个庞大的系统的最好方式是看如何使用,使用traffic server的主要入 ...
- centos配置单网卡为Trunk模式
单网卡配置多IP(trunk模式)操作标准 1.linux的单网卡配置多IP的操作 下面为linux系统单网卡配置多IP(trunk模式)的操作步骤,系统平台为centos5.5.全部操作完成后,将实 ...
- ABP官方文档翻译 6.6 Javascript API
JavaScript API AJAX 通知 消息 UI Block和Busy 事件总线 日志 其他实用功能 ABP提供了一套对象和函数,用来简化.标准化javascript的开发. 这里是ABP提供 ...
- 浏览器通过file://访问文件和通过http://访问文件有什么区别
1.file协议用于访问本地计算机中的文件,就如同在Windows资源管理器中打开文件一样,注意它是针对本地(本机)的,简单来说,file协议是访问你本机的文件资源.http访问本地HTML,是在本地 ...
- BZOJ 3698: XWW的难题 [有源汇上下界最大流]
3698: XWW的难题 题意:(1)A[N][N]=0:(2)矩阵中每行的最后一个元素等于该行前N-1个数的和:(3)矩阵中每列的最后一个元素等于该列前N-1个数的和.给A中的数进行取整操作(可以是 ...
- POJ3155 Hard Life [最大密度子图]
题意:最大密度子图 #include<iostream> #include<cstdio> #include<cstring> #include<algo ...
- DNA序列组装(贪婪算法)
生物信息学原理作业第四弹:DNA序列组装(贪婪算法) 原理:生物信息学(孙啸) 大致思想: 1. 找到权值最大的边: 2. 除去以最大权值边的起始顶点为起始顶点的边: 3. 除去以最大权值边为终点为终 ...
- IT连创业系列:年终回顾录!
一年不过一转眼,一光阴的青春又逝去了! 还有不到几天,就要进入新年快乐的祝福包围圈了. 在这归家之际,留文一篇,为这忙碌的一年创业留点回忆! IT连创业这一年走来: 大大小小的深坑,小小大大的困难,一 ...