es6重点笔记:let,const
一,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的更多相关文章
- es6重点笔记:Symbol,Set,Map,Proxy,Reflect
一,Symbol 原始数据类型,不是对象,它是JavaScript第七种数据类型,表示独一无二的值.Symbol是通过Symbol函数生成的: let s = Symbol(); typeof s / ...
- es6重点笔记:数值,函数和数组
本篇全是重点,捡常用的怼,数值的扩展比较少,所以和函数放一起: 一,数值 1,Number.EPSILON:用来检测浮点数的计算,如果误差小于这个,就无误 2,Math.trunc():取整,去除小数 ...
- ES6重点--笔记(转)
最常用的ES6特性 let, const, class, extends, super, arrow functions, template string, destructuring, defaul ...
- es6重点笔记:对象
1,Object.is():比较两个值是否严格相等,es5的'===',不能判断+0和-0,还有NaN,但是es6的Object.is()可以区分 Object.is(+0, -0); // fals ...
- ES6学习笔记<一> let const class extends super
学习参考地址1 学习参考地址2 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015:也 ...
- ES6入门笔记
ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...
- C++编程思想重点笔记(下)
上篇请看:C++编程思想重点笔记(上) 宏的好处与坏处 宏的好处:#与##的使用 三个有用的特征:字符串定义.字符串串联和标志粘贴. 字符串定义的完成是用#指示,它容许设一个标识符并把它转化为字符串, ...
- es6学习笔记-class之一概念
前段时间复习了面向对象这一部分,其中提到在es6之前,Javasript是没有类的概念的,只从es6之后出现了类的概念和继承.于是乎,花时间学习一下class. 简介 JavaScript 语言中,生 ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
随机推荐
- SQL Server CPU
解决数据库系统的性能问题可能是一项艰巨的任务.了解如何找到问题很重要,但是了解系统对特定请求作出特定反应的原因更加重要.影响数据库服务器上的 CPU 利用率 的因素有很多:SQL 语句的编译和重新编译 ...
- Django资源
官网地址:https://www.djangoproject.com/ 最新发布版本是:1.11.7 官网提供不同版本的文档:1.7.1.8.1.9.1.10.1.11.2.0.dev 安装不同的版本 ...
- [js高手之路]html5 canvas动画教程 - 跟着鼠标移动消失的一堆炫彩小球
综合利用前面所学,实现一个绚丽的小球动画,这个实例用到的知识点,在我的博客全部都有,可以去这里查看所有的canvas教程 <head> <meta charset='utf-8' / ...
- HTML + CSS短标题(二,三,四文字长度)两端对齐的方式
今天切图碰到了一个看似好弄,却并不好弄的文本两端对齐问题.如图1-1
- IIFF(立即执行函数表达式)
立即执行函数表达式(Immediately-invoked function expression,IIFF) 在javascript(ES5)中,是没有块级作用域的概念的 for (var i = ...
- vue2.0 配置sass
一.配置sass依赖 npm install node-sass --save-dev npm install sass-loader --save-dev 二.打开build文件夹下的webpack ...
- 又趟一个坑,IO卡信号DI和DO的信号类型
工控IO卡可以感应到各种电信号,传感器的状态变化. DI信号包括数字开关信号(ture,false\0,1),光信号的变化(上升沿,下降沿). DO信号包括脉宽和数字开关信号(ture,false\0 ...
- eml企业通讯录管理系统v5.0 存在sql注入
0x00 前言 上周五的时候想练练手,随便找了个系统下载下来看看. 然后发现还有VIP版本,但是VIP要钱,看了一下演示站,貌似也没有什么改变,多了个导入功能?没细看. 搜了一下发现这个系统,压根就没 ...
- c/c++ console(控制台)编程详解
前言: 控制台文本窗口的控制是基于win32 api(win32 api可理解为微软给我们提供的一系列函数的集合)实现的; 例1: #include <stdio.h>int main() ...
- 豹哥嵌入式讲堂:ARM开发之文件详解(4)- relocatable文件(object, library)
大家好,我是豹哥,猎豹的豹,犀利哥的哥.今天豹哥给大家讲的是嵌入式开发里的relocatable文件(object, library). 前三节课里,豹哥都是在给大家介绍嵌入式开发中的input文件. ...