一、let命令

用于声明变量。

1) 所声明的变量只在let命令所在代码块内有效。(块级作用域

{let a=10;var b=1;
}
a // ReferenceError: a is not defined
b // 1

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"; // ReferenceErrorconsole.log(temp); // ReferenceError
    let temp;  // TDZ结束console.log(temp); // undefined
    temp=123;console.log(temp); // 123
}

有些死区比较隐蔽,不太容易发现。

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); // 5
}

上面的函数有两个代码块,都声明了变量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);  // 1
console.log(constants.B);  // 3// test2.js
import {A,B} from './constants';
console.log(A); // 1
console.log(B); // 3

四、全局对象的属性

全局对象是最顶层的对象,在浏览器环境指的是window对象,在Node.js中指的是global对象。

ES6规定var 命令和function命令声明的全局变量依旧是全局对象的属性let命令、const命令和class命令声明的全局变量不属于全局对象的属性

window.a=1;
a; //1

a=2;
window.a //2

let b=1;
window.b // undefined

转载于:https://www.cnblogs.com/YangqinCao/p/6082819.html

let const 命令相关推荐

  1. ES6 let和const 命令

    ES6 let 和 const 命令 1. 变量声明 2. 变量提升问题 3. 暂时性死区(TDZ) 4. 块级作用域 4.1 为什么需要块级作用域? 4.2 ES6的块级作用域 4.3 块级作用域和 ...

  2. ES6之let(理解闭包)和const命令

    ES6之let(理解闭包)和const命令 最近做项目的过程中,使用到了ES6,因为之前很少接触,所以使用起来还不够熟悉.因此购买了阮一峰老师的ES6标准入门,在此感谢阮一峰老师的著作. 我们知道,E ...

  3. 2.let和const命令

    1.let命令 let声明的变量,只在let命令所在的代码块内有效. {let a = 10;var b = 1; }a // ReferenceError: a is not defined. b ...

  4. ES6-let和const命令

    let 1.ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. 2.不存在变量提升 var命令会发生"变量提升"现象 ...

  5. ES6新特性之let和const命令

    let 和 const 命令 var 之前,我们写js定义变量的时候,只有一个关键字: var var 有一个问题,就是定义的变量有时会莫名奇妙的成为全局变量. 例如这样的一段代码: for(var ...

  6. es6 var、let、const命令

    1.let和var <1>let声明的变量仅在块级作用域内有效: var声明的变量在全局有效: <2> var变量乐意在声明之前使用,输出undefined; let 不可以, ...

  7. 《02》let 和 const 命令

    目录 1.let命令 基本用法 暂时性死区 不允许重复声明 2.块级作用域 3.const 命令 基本用法 本质 1.let命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于var ...

  8. “睡服”面试官系列第一篇之let和const命令(建议收藏学习)

    目录 1let命令 1.1基本用法 1.2for循环小案例 1.3不存在变量提升 1.4暂时性死区 1.5不允许重复声明 2块级作用域 2.1为什么需要块级作用域? 2.2ES6 的块级作用域 2.3 ...

  9. 阮一峰 《ECMAScript 6 入门》:let 和 const 命令

    以下内容全文出自 阮一峰的书: <ECMAScript 6 入门> 电子版地址:ES 6标准入门(第3版) let 命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于v ...

最新文章

  1. IT 巡检内容、方法大全
  2. CodeForces - 979D Kuro and GCD and XOR and SUM(字典树+暴力+模拟)
  3. python小学生口算题生成器_小学数学题出题神器
  4. vs2005常用的调试方法
  5. bzoj 4094: [Usaco2013 Dec]Optimal Milking
  6. 网络_检测公网端口是否开启
  7. 比较万能的匹配邮箱的正则表达式
  8. python中merge函数_Python Merge函数原理及用法解析
  9. windows 开启安全中心的方法
  10. ubuntu更换清华镜像源
  11. c语言水仙花数pow,c语言如何解水仙花数
  12. Error creating bean with name ‘serverEndpointExporter‘ defined in class path resource
  13. 远程入侵原装乘用车(上)
  14. LeetCode:387(Python)—— 字符串中的第一个唯一字符(简单)
  15. 2019最新Java实战开发今日头条资讯网站
  16. 电磁场常见名词整理(不断更新中)
  17. 传统激光条纹中心提取算法研究现状
  18. Spark任务调度概述_大数据培训
  19. 中文书籍对《人月神话》的引用(2021.10.18更新共120本):告别失控、重构极限编程……
  20. linux下进入bios设置u盘启动项,u盘启动g4l_u盘启动快捷键_bios设置u盘启动

热门文章

  1. oracle pl sql示例,oracle PL SQL学习案例(一)
  2. 写得太好了!树莓派安装docker
  3. 【好文推荐】springmvc教程下载
  4. 我们究竟还要学习哪些Android知识?面试真题解析
  5. 【深度学习】讲一个深度分离卷积结构和空洞卷积的应用
  6. python【数据结构与算法】二分模板
  7. python【数据结构与算法】动态规划详解从背包到最长公共子序列(看不懂你来打我)
  8. mysql服务器的启动方式有哪几种_Mysql启动的方式(四种)
  9. linux 退出服务器_Vue实战091:Vue项目部署到nginx服务器
  10. java从磁盘读取图片_java 怎样从磁盘读取图片文件