ES6系列之let/const及块级作用域
本系列是在平时阅读、学习、实际项目中有关于es6中的新特性、用发的简单总结,目的是记录以备日后温习;本系列预计包含let/const、箭头函数、解构、常用新增方法、Symbol、Set&Map、Proxy、reflect、Class、Module、Iterator、Promise、Generator、async/await
let/const为我们带来了什么?
let
- 约束变量提升
(function foo() {console.log(a);let a = 1;})();// Uncaught ReferenceError: a is not defined
总结下来就是一句: 在变量使用之前,必须先要声明,变量声明永远在使用之前。
- 带来了块级作用域
// es5(function(){if(false) {var temp = 1;}console.log(temp); // undefined })();// es6(function(){if(false) {let temp = 1;}console.log(temp); // Uncaught ReferenceError: temp is not defined})();
从代码中我们可以很清晰看到es6的let的块级作用域,那么块级作用域有什么应用呢?举个例子:
var fnArr = [];for(var i = 0; i < 5; i++) {fnArr.push(function() {console.log(i);});}fnArr[0](); // 5fnArr[1](); // 5fnArr[2](); // 5fnArr[3](); // 5fnArr[4](); // 5console.log(i); // 5
如果没有仔细分析,执行的结果是不是有些出乎意料呢? 是的,我们本意在for循环内部使用的变量i被泄露成了全局变量,而且在for循环的每一次循环,变量i并没有被重新声明,实际上数组fnArr中保存的每一个函数中引用的都是同一个变量i,所以才导致了现在的结果,那怎么让代码按照我们最初的想法运行呢?来看es5中常用的解法
var fnArr1 = [];for(var i = 0; i < 5; i++) {(function(j) {fnArr1.push(function() {console.log(j);});})(i)}fnArr1[0](); // 0fnArr1[1](); // 1fnArr1[2](); // 2fnArr1[3](); // 3fnArr1[4](); // 4console.log(i); // 5
看起来是解决了,这里实际上用到了闭包的方法,fnArr1中每一项函数引用的j都是当前循环时i的一个副本,这样就解决了前面的问题,但是还有一个问题: 变量i仍然隐式得泄露到了全局
var fnArr1 = [];for(let i = 0; i < 5; i++) {fnArr1.push(function() {console.log(i);});}fnArr1[0](); // 0fnArr1[1](); // 1fnArr1[2](); // 2fnArr1[3](); // 3fnArr1[4](); // 4console.log(i); // Uncaught ReferenceError: i is not defined
OK,问题解决了,仅仅是将’var‘替换成了let,这就是let带来的便利。
- 产生暂时性死区&禁止重复声明
// 什么是禁止重复声明呢? 先不给书面解释,来看一个es5中经常的写法 (function() {var temp = 1;var temp = 2;var temp = function() {return 1;};})();
上面这段代码执行没有任何问题,最终temp被赋值为一个函数
(function() {let temp = 1;var temp = 2; // Uncaught SyntaxError: Identifier 'temp' has already been declaredvar temp = function() {return 1;};})();
在第三行时就抛出了一个错误:temp已经被声明,是的,let声明过的变量,是不允许再次被声明的,再给几个例子巩固一下:
(function() {var temp = 2;var temp = function() {return 1;};let temp = 1; // Uncaught SyntaxError: Identifier 'temp' has already been declared })();(function() {if(true) {let temp = 1;var temp = 2; // Uncaught SyntaxError: Identifier 'temp' has already been declared }})();(function() {if(true) {let temp = 1;function temp() { // Uncaught SyntaxError: Identifier 'temp' has already been declaredreturn 1;}}})();
看出来了吗?只要是在let声明所在的作用域,就不允许再次声明同名变量(包括函数声明)
var foo = 1;if(true) {foo = 2; // Uncaught ReferenceError: foo is not defined let foo;}
看到let的’霸道‘了吧?只要在let所在的作用域,同名的变量就会被let占有,不允许重复声明,同时也要遵守let的规则
- 全局变量不再作为window对象的属性
var foo = 1;(function() {bar = 2;})();window.foo; // 1window.bar; // 2
是的,es5中,全局变量(包括意外泄露的)都将自动被添加为window对象的属性
let foo = 1;window.foo; // undefined
一切尽在不言中。。。
const
- let所拥有的特性,const都有,同时const还有一条:const声明的变量必须进行初始化,并且不能再被重新赋值
const temp = 1;temp = 2; // Uncaught TypeError: Assignment to constant variable.
注意是不能被重新赋值,这样是比较准确的,其实const声明的变量是可以被修改的,当const声明的变量被初始化为复杂数据类型时,const声明的变量就是可变的,至于为什么,自己理解喽(变量标识符中保存的只是复杂数据类型内存地址而已。。。)
const temp = {};temp.foo = 'aa'; // 这里没问题temp = {foo: 'aa'}; // 这里就会抛出异常
for循环中的变量声明
前面在记录let块级作用域的时候,我们使用了一个for循环的例子,这里我们不妨试着解析一下for循环的执行过程
var fnArr = [];for(var i = 0; i < 3; i++) {fnArr.push(function() {console.log(i);});}// 伪代码var fnArr;fnArr = [];{var i;i = 0;if(i < 3) {fnArr.push(function() {console.log(i);})}i++;if(i < 3) {fnArr.push(function() {console.log(i);});}i++;...}
这里可惜清晰得看到所有的i都是一个i。。。那使用了let以后呢?
var fnArr = [];for(let i = 0; i < 3; i++) {fnArr.push(function() {console.log(i);});}// 伪代码var fnArr;fnArr = [];{let i;i = 0;if(i < 3) {let i = i;fnArr.push(function() {console.log(i);})}i++;if(i < 3) {let i = i;fnArr.push(function() {console.log(i);});}i++;...}
是不是看出点名堂?其实我们完全可以这样理解,在每一次循环中都重新声明了i,并且被赋值为外层i的当前值。(注意啊,这里只是伪代码,便于理解,实际中let i = i是会抛出异常的)
转载于:https://www.cnblogs.com/innooo/p/10438947.html
ES6系列之let/const及块级作用域相关推荐
- ES6(一)——字面量的增强、解构、let/const、块级作用域、暂时性死区
一.字面量的增强 ES6中对 对象字面量 进行了增强,称之为 Enhanced object literals(增强对象字面量). 字面量的增强主要包括下面几部分: 属性的简写:Property Sh ...
- var/let/const、块级作用域、TDZ、变量提升
概览 ES6 新增了两个定义变量的关键字:let 与 const,它们几乎取代了 ES5 定义变量的方式:var.let是新的var,const简单的常量声明. function f() {{let ...
- java区块作用域_ES6-let、const和块级作用域
1.介绍 总的来说,ES6是在ES2015的基础上改变了一些书写方式,开放了更多API,这样做的目的最终还是为了贴合实际开发的需要.如果说一门编程语言的诞生是天才的构思和实现,那它的发展无疑就是不断填 ...
- 详解var、let、const关键词声明变量的区别,以及变量提升、块级作用域的认识等。
首先回顾一下JavaScript中var声明变量的基础知识: • 在使用var关键词声明变量时,变量在函数外则是全局变量,有全局作用域,全局变量在页面关闭后销毁:变量在函数内则是局部变量,作用局部作用 ...
- let、const和var的区别(涉及块级作用域)
let .const和var的区别 let.const.var在js中都是用于声明变量的,在没有进行ES6的学习前,我基本只会使用到var关键字进行变量的声明,但在了解了ES6之后就涉及到了块级作用域 ...
- ES6规范前后块级作用域与函数声明的缠缠绵绵
今天我们就以上面的这个例子来说一下,块级作用域与函数声明在ES6前后的纠葛,当然在ES6之前是没有块级作用域的,但为了与ES6统一,使文章更简明,所以把这对'{}'统一称为块级作用域. 开正题之前,还 ...
- ECMAScript6(1):块级作用域
let.const和块级作用域 块级作用于对于强类型语言经验的人应该非常好理解, 一言以蔽之:ES5对变量作用于分隔使用了函数(词法作用域), 而ES6使用花括号(块作用域). 对于词法作用域在 ja ...
- 搭建Babel运行环境,Traceur ES6模板,块级作用域,let和const命令
搭建Babel运行环境 Babel(http://babeljs.io/)可用于将使用ES6语法的脚本转化为ES5语法的脚本,基本功能的安装步骤如下: 1.安装node解释器和npm包管理工具 2.安 ...
- ES6基础2(块级作用域、数组对象解构)-学习笔记
文章目录 ES6基础2(块级作用域.数组对象解构)-学习笔记 块级作用域 数组解构 对象解构 字符串解构 函数的参数解构 ES6基础2(块级作用域.数组对象解构)-学习笔记 块级作用域 //let c ...
- ES6中块级作用域下的函数声明
背景 因为ES5的时候没有块级作用域,所以ES5规定不能再if这样的块中声明函数,但是为了兼容各大浏览器并没有严格遵守这条规定. ES6的时候引入了块级作用域,规定在块级作用域中声明函数就相当于使用l ...
最新文章
- 号外! 大维度机器学习也有计算框架了
- ELS多种方式集群部署
- 如何定位“Operating system error 32(failed to retrieve text for this error. Reason: 15105)”错误中被占用的文件...
- Web前端就业薪资是多少?Web前端要学什么?
- Where is number of opportunities not displayed message poped up
- mysql在linux下的安装_mysql在linux下的安装
- 埃及分数(信息学奥赛一本通-T1444)
- php开发手册pdf版,TP5.0手册下载
- 最大流(Maximum Flow)
- 小米、搜狗、TW等机器学习算法工程师面试总结
- Intelligent Reference Curation for Visual Place Recognition via Bayesian Selective Fusion 论文阅读及注解
- 在yandex投放广告的话,需要注册俄罗斯常用的域名吗?
- window10无法访问局域网共享文件夹
- Duilib corner属性
- C语言函数中的3个点 ...有什么作用
- Maximal Information Coefficient (MIC)最大互信息系数详解与实现
- Linux 进程管理之current
- 我国数字出版产业发展规模[中国新闻出版网]
- 李永乐复习全书概率论与数理统计 第一、二章 随机事件和概率、随机变量及其概率分布
- 中国移动苏州研发中心一面
热门文章
- 基于springboot的疫情网课教学平台
- 第八章(三)滑动窗口
- 计算机网络-应用层与传输层
- thinkphp5.x之数据库操作相关解析 Db类
- Java 控制 Windows 系统音量
- java socket php_Web架构(二)PHP Socket与Java ServerSocket交互
- 阶段5 3.微服务项目【学成在线】_day04 页面静态化_17-页面静态化-模板管理-GridFS研究-存文件...
- Can not find the tag library descriptor for http://java.sun.com/jsp/jst1/core
- Centos 7.x 安装配置tomcat-8过程梳理
- 美化博客园 添加网易云音乐及生成文章目录