一,let

先看代码:

var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i)
};
}
a[6](); // 10  

我先花点时间来拆分一下这个for循环,我就写第一个循环过程,后面依次类推:

{
var i = 0;
if (i<10) {
a[i] = function(){
console.log(i)
}
};
i++;
}
// 第一个循环 {
i = 1;
...;
i++;
}
// 第二个循环 。。。

每一次for循环都是一个代码块,上面用大括号区分开来,es5没有块级作用域的概念,所以等同于没有大括号,i就是全局作用域下的变量,if句里面的代码块是子作用域,因此能访问到它的父作用域,就是for循环的设置循环条件的部分,所以i的值是同一个,就是全局环境下的i,因此for循环执行完成后,i就是10,你不管怎么访问,i都是10;

上面的代码要想实现我们预期的效果很简单,把var换成let就可以了,里面的原理是:由于es6有了块级作用域的概念,let声明的i只对它本轮(也就是大括号里的)循环有效,也就是说每一次循环都相当于重新声明了i,所以每次循环(代码块内)都互不干涉,因此能够依次输出不同的i,但是问题来了:如果不是同一个i,为什么i还会叠加呢?每次循环的时候它是访问不到上一轮的i的,因为是不同的块级作用域啊(不同的大括号里)。重点来了:因为JavaScript引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。

这才是考察的重点!

暂时性死区:在let命令声明变量之前,该变量都是不可用的。

typeof一定百分之百安全吗?es5是这样,es6不是了,因为存在暂时性死区。

关于暂时性死区有一个很有趣的例子,挺绕的:

var x = 1;
fucntion f(y=x){};
f();
// 不报错 var x = 1;
function f(x=x){};
f();
// 报错,注意这里的错误不是x已经被定义了,而是x未定义

为什么第一个不报错,第二个报错呢?x不应该是取的外面全局下的值吗?

其实第二个里面隐藏了一个暂时性死区:

函数声明时,参数部分实际上就是一个块级作用域,y=x,实际上等同于let y = x,x在块级作用域里找不到定义,所以到外部全局下去找,找到了,所以不报错,x=x,实际上等同于let x = x,但此时x不会去块级作用域外面找,为什么,因为块级作用域内部有定义let x,所以它没有找到对应的值,因此报错not defined。

块级作用域:

首先,有哪些作用域:全局作用域,块级作用域,还有函数作用域(这个最容易忘,面试的坑)

为什么要块级作用域:1,内层变量可能会覆盖外层变量;2,用来计数的循环变量泄露为全局变量,造成内存泄漏,污染环境。(面试的坑)

es5规定,函数只能在顶层作用域和函数作用域中声明,不能在块级作用域中声明。就比如在if句中声明一个function函数,这就会报错,但在es6中不会。

function f(){ console.log(1); }

(function (){
if (false) {
function f(){ console.log(2); }
}
f();
}());

上面的代码,如果在es5中运行,if条件中的function会直接跑到if外面去,然后执行,最后输出2。但如果在es6中,允许在块级作用域中声明函数,所以函数不会跑到if条件句外面,那么f()应该调用的是外面的函数声明,理论上应该会输出1,但实际上会报错,为什么?有人解释说也是因为块级作用域里不能声明函数,那把f()放在if语句中并不会报错,说明是可以在块级作用域中声明的。

重点来了:es6的浏览器有自己的行为方式:

1,允许在块级作用域内声明函数;

2,函数声明类似于var,会提升到全局作用域下或函数作用域的头部;

3,函数声明会提升到所在的块级作用域的头部;

有了上面三条,刚刚的代码就等同于下面:

function a(){ console.log(1); }

(function (){
var f = undefined;
if (false) {
function a(){ console.log(2); }
}
f();
}());

所以f还没有定义是一个function,因此不能执行。

二,const

const大部分的注意点都和let差不多。但是要注意下面的

es6重点笔记:let,const的更多相关文章

  1. es6重点笔记:Symbol,Set,Map,Proxy,Reflect

    一,Symbol 原始数据类型,不是对象,它是JavaScript第七种数据类型,表示独一无二的值.Symbol是通过Symbol函数生成的: let s = Symbol(); typeof s / ...

  2. es6重点笔记:数值,函数和数组

    本篇全是重点,捡常用的怼,数值的扩展比较少,所以和函数放一起: 一,数值 1,Number.EPSILON:用来检测浮点数的计算,如果误差小于这个,就无误 2,Math.trunc():取整,去除小数 ...

  3. ES6重点--笔记(转)

    最常用的ES6特性 let, const, class, extends, super, arrow functions, template string, destructuring, defaul ...

  4. es6重点笔记:对象

    1,Object.is():比较两个值是否严格相等,es5的'===',不能判断+0和-0,还有NaN,但是es6的Object.is()可以区分 Object.is(+0, -0); // fals ...

  5. ES6学习笔记<一> let const class extends super

    学习参考地址1  学习参考地址2 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015:也 ...

  6. ES6入门笔记

    ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...

  7. C++编程思想重点笔记(下)

    上篇请看:C++编程思想重点笔记(上) 宏的好处与坏处 宏的好处:#与##的使用 三个有用的特征:字符串定义.字符串串联和标志粘贴. 字符串定义的完成是用#指示,它容许设一个标识符并把它转化为字符串, ...

  8. es6学习笔记-class之一概念

    前段时间复习了面向对象这一部分,其中提到在es6之前,Javasript是没有类的概念的,只从es6之后出现了类的概念和继承.于是乎,花时间学习一下class. 简介 JavaScript 语言中,生 ...

  9. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

随机推荐

  1. Sublime Text3注册码,亲测可用

    将以下复制在输入框即可 ,亲测可用 . 不过还是希望大家多多支持正版 . -– BEGIN LICENSE -– TwitterInc 200 User License EA7E-890007 1D7 ...

  2. 从mysql数据库取一条记录里的某个字段的值

    <?php $link = mysqli_connect("localhost","root","root","dbname ...

  3. 【转载】mysql binlog日志自动清理及手动删除

    说明:当开启mysql数据库主从时,会产生大量如mysql-bin.00000* log的文件,这会大量耗费您的硬盘空间.mysql-bin.000001mysql-bin.000002mysql-b ...

  4. 001_JS基础_JavaScript简介

    1.1 历史 JS的发展历史: http://www.w3school.com.cn/js/pro_js_history.asp 1.2 JavaScript简介 以下摘自维基百科对javascrip ...

  5. vue 设计日历表

    日历的功能,我们会经常用到,且逻辑比较复杂,小算法较多,花了半天时间写了个,特此详记. 先贴图 功能阐述:返回本月不多说,设置工作日和节假日是为了公司制度需要,后台会有假日表来记录. 为了适应于vue ...

  6. HDFS中namenode启动失败

    1.环境配置: -1.core-site.xml文件 <configuration> <property> <name>fs.defaultFS</name& ...

  7. Sql的基础知识技巧(三)

    三.技巧 1.1=1,1=2 的使用,在 SQL 语句组合时用的较多 "where 1=1" 是表示选择全部 "where 1=2"全部不选, 如:if @st ...

  8. RED_HAWK:基于PHP实现的信息收集与SQL注入漏洞扫描工具

    无事早上就去逛freebuf看到一款不错的工具,打算介绍给大家 RED_HAWK:基于PHP实现的信息收集与SQL注入漏洞扫描工具 RED HAWK 最新版本:v1.0.0[2017年6月11日] 下 ...

  9. AtCoder Grand Contest 016

    在雅礼和衡水的dalao们打了一场atcoder 然而窝好菜啊…… A - Shrinking 题意:定义一次操作为将长度为n的字符串变成长度n-1的字符串,且变化后第i个字母为变化前第i 或 i+1 ...

  10. 关于int *a[常量]与int (*a)[常量]的分析与区分(详解)

    前言: 小伙伴私信我说,int *a[常量]与int (*a)[常量]这个区分不开,C指针,确实是C中最难的部分,也是学C++,JAVA,包括你以后上岗用的非常频繁的东西,在这里我就简单论述一下吧,具 ...