let const 命令
一、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 命令相关推荐
- ES6 let和const 命令
ES6 let 和 const 命令 1. 变量声明 2. 变量提升问题 3. 暂时性死区(TDZ) 4. 块级作用域 4.1 为什么需要块级作用域? 4.2 ES6的块级作用域 4.3 块级作用域和 ...
- ES6之let(理解闭包)和const命令
ES6之let(理解闭包)和const命令 最近做项目的过程中,使用到了ES6,因为之前很少接触,所以使用起来还不够熟悉.因此购买了阮一峰老师的ES6标准入门,在此感谢阮一峰老师的著作. 我们知道,E ...
- 2.let和const命令
1.let命令 let声明的变量,只在let命令所在的代码块内有效. {let a = 10;var b = 1; }a // ReferenceError: a is not defined. b ...
- ES6-let和const命令
let 1.ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. 2.不存在变量提升 var命令会发生"变量提升"现象 ...
- ES6新特性之let和const命令
let 和 const 命令 var 之前,我们写js定义变量的时候,只有一个关键字: var var 有一个问题,就是定义的变量有时会莫名奇妙的成为全局变量. 例如这样的一段代码: for(var ...
- es6 var、let、const命令
1.let和var <1>let声明的变量仅在块级作用域内有效: var声明的变量在全局有效: <2> var变量乐意在声明之前使用,输出undefined; let 不可以, ...
- 《02》let 和 const 命令
目录 1.let命令 基本用法 暂时性死区 不允许重复声明 2.块级作用域 3.const 命令 基本用法 本质 1.let命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于var ...
- “睡服”面试官系列第一篇之let和const命令(建议收藏学习)
目录 1let命令 1.1基本用法 1.2for循环小案例 1.3不存在变量提升 1.4暂时性死区 1.5不允许重复声明 2块级作用域 2.1为什么需要块级作用域? 2.2ES6 的块级作用域 2.3 ...
- 阮一峰 《ECMAScript 6 入门》:let 和 const 命令
以下内容全文出自 阮一峰的书: <ECMAScript 6 入门> 电子版地址:ES 6标准入门(第3版) let 命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于v ...
最新文章
- IT 巡检内容、方法大全
- CodeForces - 979D Kuro and GCD and XOR and SUM(字典树+暴力+模拟)
- python小学生口算题生成器_小学数学题出题神器
- vs2005常用的调试方法
- bzoj 4094: [Usaco2013 Dec]Optimal Milking
- 网络_检测公网端口是否开启
- 比较万能的匹配邮箱的正则表达式
- python中merge函数_Python Merge函数原理及用法解析
- windows 开启安全中心的方法
- ubuntu更换清华镜像源
- c语言水仙花数pow,c语言如何解水仙花数
- Error creating bean with name ‘serverEndpointExporter‘ defined in class path resource
- 远程入侵原装乘用车(上)
- LeetCode:387(Python)—— 字符串中的第一个唯一字符(简单)
- 2019最新Java实战开发今日头条资讯网站
- 电磁场常见名词整理(不断更新中)
- 传统激光条纹中心提取算法研究现状
- Spark任务调度概述_大数据培训
- 中文书籍对《人月神话》的引用(2021.10.18更新共120本):告别失控、重构极限编程……
- linux下进入bios设置u盘启动项,u盘启动g4l_u盘启动快捷键_bios设置u盘启动
热门文章
- oracle pl sql示例,oracle PL SQL学习案例(一)
- 写得太好了!树莓派安装docker
- 【好文推荐】springmvc教程下载
- 我们究竟还要学习哪些Android知识?面试真题解析
- 【深度学习】讲一个深度分离卷积结构和空洞卷积的应用
- python【数据结构与算法】二分模板
- python【数据结构与算法】动态规划详解从背包到最长公共子序列(看不懂你来打我)
- mysql服务器的启动方式有哪几种_Mysql启动的方式(四种)
- linux 退出服务器_Vue实战091:Vue项目部署到nginx服务器
- java从磁盘读取图片_java 怎样从磁盘读取图片文件