let & const 命令
一、let命令
用于声明变量。
1) 所声明的变量只在let命令所在代码块内有效。(块级作用域)
{
let a=10;
var b=1;
}
a // ReferenceError: a is not defined
b //
var li=document.getElementsByTagName("li");
for(let i=0;i<li.length;i++){
li[i].addEventListener("click",function(){
console.log(i+1);
})
}
在上面的代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i都是一个新变量,于是最后输出的是6。这样每个li元素输出的都是不一样的值,比如第一个li单击会输出1,第二个li单击会输出2,第三个li单击会输出3...
2) 不存在变量提升
let不像var那样会发生“变量提升”现象。所以变量一定要在声明后使用,否则报错。
console.log(foo); // ReferenceError
let foo=2; console.log(bar); // undefined
var bar=2;
所以typeof不再是一个百分之百安全的操作了。
typeof x; // ReferenceError
let x;
3) 暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”到这个区域,不再受外部的影响。ES6明确规定,如果区块中存在let和const命令,则这个区块对这些命令声明的变量从一开始就形成封闭作用域。只要在声明之前就使用这些变量,就会报错。在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上称为“暂时性死区”(TDZ)。
if(true){
// TDZ开始
temp="abc"; // ReferenceError
console.log(temp); // ReferenceError
let temp; // TDZ结束
console.log(temp); // undefined
temp=123;
console.log(temp); //
}
有些死区比较隐蔽,不太容易发现。
function bar(x=y,y=2){
return [x,y];
}
bar(); // 报错
调用bar函数报错,是因为参数x的默认值等于另一个参数y,而此时y还没有声明,属于死区。
总之,暂时性死区的本质就是,只要已进入当前作用域,所要使用的变量就已存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
4) 不允许重复声明
let不允许在相同的作用域内重复声明同一个变量。
function func(){ // 报错重复声明变量
let a=10;
var a=1;
}
function func(arg){
let arg; // 报错,重复声明变量
}
function func(arg){ // 不报错
{
let arg;
}
}
二、块级作用域
let实际上为javascript新增了块级作用域。
function f1(){
let n=5;
if(true){
let n=10;
}
console.log(n); //
}
上面的函数有两个代码块,都声明了变量n,运行后输出5.这表示外层代码块不受内层代码块的影响。
ES6允许块级作用域任意嵌套。外层作用域无法读取内层作用域的变量。内层作用域可以定义外层作用域的同名变量。
函数本身的作用域在其所在的块级作用域内。
function f(){console.log('I am outside');}
(function(){
if(false){
function f(){console.log('I am inside');}
}
f();
}());
上面的代码在ES5中运行,会得到I am inside(函数变量提升)。但是在ES6中运行会得到I am outside。不管会不会进入if代码块,其内部声明的函数皆不会影响到作用域的外部。
{
let a='secret';
function f(){
return a;
}
}
f() // 报错
块级作用域外部无法调用块级作用域内部定义的函数。如果确实需要调用,则要像下面这样处理
let f;
{
let a='secret';
f=function(){
return a;
}
}
f() // secret
如果在严格模式下,函数只能在顶层作用域和函数内声明,其他情况(比如if代码块,循环代码块)下的声明都会报错。
三、const命令
const用来声明常量。一旦声明,其值就不能改变。const一旦声明常量,就必须立即初始化,不能留到以后赋值,只声明不赋值就会报错。
const PI=3.14;
PI // 3.14
PI=3; // TypeError:"PI" is read-only
const作用域与let命令相同:只在声明所在的块级作用域内有效。const命令声明的常量也不能提升,同样存在暂时性死区,只能在声明后使用。并且不能重复声明常量。
对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址。const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个对象声明为常量必须非常小心。
const foo={};
foo.prop=123;
foo={} // TypeError:"foo" is read-only
上面的代码中,常量foo储存的是一个地址,指向一个对象。不可变的只是这个地址,既不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。
const a=[];
a.push("Hello"); // 可执行
a.length=0; // 可执行
a=["Dave"]; // 报错
如果真的想将对象冻结,应该使用Object.freeze方法。
const foo=Object.freeze({});
foo.prop=123; // 不起作用
上面的代码中,常量foo指向一个冻结的对象,所以添加新属性不起作用。除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。
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
跨模块常量
上面说过,const声明的常量只在当前代码块有效。如果想设置跨模块的常量,可以采用下面的写法:
// constants.js 模块
export const A=1;
export const B=3;
export const C=4; // test1.js
import * as constants from './constants';
console.log(constants.A); //
console.log(constants.B); // // test2.js
import {A,B} from './constants';
console.log(A); //
console.log(B); //
四、全局对象的属性
全局对象是最顶层的对象,在浏览器环境指的是window对象,在Node.js中指的是global对象。
ES6规定var 命令和function命令声明的全局变量依旧是全局对象的属性;let命令、const命令和class命令声明的全局变量不属于全局对象的属性。
window.a=1;
a; // a=2;
window.a // let b=1;
window.b // undefined
let & const 命令的更多相关文章
- es6学习笔记(1) let和const命令详解
let和const命令: Es6新增了let命令,声明变量,但与var不一样的,只在let命令所在的代码块内有效(如for循环之外let声明的变量就不再有效).并且let不像var那样会发生" ...
- let和const命令//////////////////////z
let和const命令 let命令 块级作用域 const命令 全局对象的属性 let命令 基本用法 ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的 ...
- ES6之let(理解闭包)和const命令
ES6之let(理解闭包)和const命令 最近做项目的过程中,使用到了ES6,因为之前很少接触,所以使用起来还不够熟悉.因此购买了阮一峰老师的ES6标准入门,在此感谢阮一峰老师的著作. 我们知道,E ...
- ECMAScript 6入门 - let和const命令
详细学习链接: http://es6.ruanyifeng.com/#docs/let let命令 基本用法 ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命 ...
- ES6 入门系列 - let 和 const 命令
let命令 基本用法 ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a = ; ; } a // ReferenceEr ...
- ES6 之 let和const命令 Symbol Promise对象
ECMAScript 6入门 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了. (2016年6月,发布了小幅修订的<ECMASc ...
- ECMAScript6-let和const命令
▓▓▓▓▓▓ 大致介绍 ES6是下一代的JavaScript语言的标准,目标是让JavaScript可以用来编写大型的复杂程序,成为企业级开发语言,要查看浏览器对ES6的支持程度可以用阮一峰大佬写的工 ...
- ECMAScript6-let与const命令详解
前言 <ECMAScript入门>是一本开源的JavaScript语言教程,全面介绍ECMAScript6新引入的语法特性. let和const命令,是第一章开始介绍,也是比较基础的知识. ...
- let和const命令
let命令 1.let用来声明变量,类似于var,但只在代码块内有效. { let a = 1; var b = 2; } console.log(a); //a is not defined con ...
- ECMAScript 6 第一天 let和const命令
ES6新增声明变量的方法let命令,const命令. (ES5只有两种声明变量的方法:var 命令和 function 命令.) let命令,用来声明变量. 与var声明变量不同于: 1. let声 ...
随机推荐
- sar-CPU统计数据
sar -u输出显示CPU信息.-u选项是sar的默认选项.该输出以百分比显示CPU的使用情况.表3-2解释该输出. 表3-2 ...
- C++ std::vector指定位置插入
使用vector,必须加上:#include <vector> 1.初始化vector,一般有这几种方式: std::vector<std::wstring> v1; //创建 ...
- Postgresql 正则表达式【转】
原文:http://blog.csdn.net/wugewuge/article/details/7704996 postgresql支持POSIX 风格的正则表达式,在postgresql中使用正则 ...
- 常用css3属性
总结一下在工作用常用到的属性设置 1.设置文本的可选择性 -webkit-user-select:none/text 2.设置背景的绘制区域 background-clip:border-box/pa ...
- PCL配置即常见问题
1 下载 把与VS版本对应PCL的AllInOne包下载下来.要下对安装包,需要了解安装包的命名的含义,以下面的一个AllInOne包的名字为例. PCL-1.8.0-AllInOne-msvc ...
- tcpdump抓取udp报文
使用tcpdump命令抓取UDP 2000端口报文,并将报文保存到当前目录下的udp.cap文件,命令如下: tcpdump -i 网络接口名称 udp port 2000 -w ./udp.cap ...
- 【水滴石穿】mobx-todos
我觉得代码在有些程序员手里,就好像是画笔,可以创造很多东西 不要觉得创意少就叫没有创意,每天进步一点点,世界更美好 首先源码地址为:https://github.com/byk04712/mobx-t ...
- 【风马一族_php】
原文来自:http://www.cnblogs.com/sows/p/6054383.html (博客园的)风马一族 侵犯版本,后果自负 2016-11-11 15:13:51 回顾 数组:分配 ...
- 实现手机网页调起原生微信朋友圈分享的工具nativeShare.js
http://www.liaoxiansheng.cn/?p=294 我们知道现在我们无法直接通过js直接跳转到微信和QQ等软件进行分享,但是现在像UC浏览器和QQ浏览器这样的主流浏览器自带一个分享工 ...
- PostgreSQL 给数组排序
PostgreSQL 支持数组,可是没有对数据内部元素进行排序的一个函数. 今天我分别用PLPGSQL和PLPYTHONU写了一个.演示样例表结构: t_girl=# \d test_array; ...