在javascript中,我们都知道使用var来声明变量。javascript是函数级作用域,函数内可以访问函数外的变量,函数外不能访问函数内的变量。

函数级作用域会导致一些问题就是某些代码块内的变量会在全局范围内有效,这我们是非常熟悉的:

 for (var i = 0; i < 10; i++) {
console.log(i); // 0,1,2...,9
}
console.log(i); // if(true){
var s = 20;
}
console.log(s); //

在es6中增加了let(变量)和const(常量)来声明变量,使用的是块级作用域,变量声明只在代码块内有效:

 for (let i = 0; i < 10; i++) {
console.log(i); // 0,1,2...,9
}
console.log(i); //ReferenceError: i is not defined if(true){
let s = 20;
}
console.log(s); //ReferenceError: s is not defined

我们最常遇到的循环事件绑定i产生的闭包问题,是因为i绑定在全局,每次访问都会取到全局的i的值,所以访问哪个元素,得到的i都是循环体最后一轮的i。我们通常的解决办法是借助IIFE。在es6中let定义的i只在循环体内有效,所以每次循环i都是一个新的变量,于是会产生正常的输出:

 //使用var
var arr1 = [];
for (var i = 0; i < 10; i++) {
arr1[i] = function() {
console.log(i);
}
} arr1[5](); //
arr1[8](); // //使用let
var arr2 = [];
for (let i = 0; i < 10; i++) {
arr2[i] = function() {
console.log(i);
}
} arr2[5](); //
arr2[8](); //

变量提升:

在es5中var定义的变量存在变量提升,es6中使用的let不存在变量提升:

 console.log(i);
var i = 10; // console.log(s);
let s = 20; //ReferenceError: can't access lexical declaration `s' before initialization

函数提升:

es5中无论if语句是否执行,在if语句内的函数声明都会提升到当前的作用域的顶部而得到执行,es6支持块级作用域,无论是否进入if,内部的函数都不会影响到外部的函数

严格模式下函数声明只能在顶层环境和函数体内,不能if或者循环体内进行函数声明

 //es5环境
function f(){
console.log('outside');
}
if(true){
function f(){
console.log('inside');
}
} f(); //inside //es6环境
function d(){
console.log('outside');
}
if(true){
function d(){
console.log('inside');
}
} d(); //outside

每个代码块中即同一个作用域中,每个变量只能使用let定义一次,使用var重复定义会进行覆盖,但是使用let重复定义会报错,不同代码块可以重复定义:

 let i = 10;

 if(true){
let i = 20;
console.log(i); //
let i = 50; //redeclaration of let i
console.log(i);
}

暂时性死区:

在代码块内,使用let声明变量之前,该变量都不可用,即是变量在使用赋值之前需要先进行声明,每个代码块会进行变量绑定,以确定变量属于哪个环境,在绑定之前进行变量的操作都是非法的:

 let i = 10;

 if(true){
i = 50; //ReferenceError
let i = 20;
console.log(i);
}
//因为在if中声明了i,i绑定了if的环境,所以在if的i声明之前,i都不可用,导致i=50报错

IIFE有一个重要的作用是封装变量,避免变量泄漏到全局,块级作用域的出现,其实就使得IIFE不再必要了:

 ~function(){
if(true){
var i = 10;
}
}()
console.log(i); //ReferenceError: i is not defined if(true){
let s = 20;
} console.log(s); //ReferenceError: s is not defined

let和const的区别:

let声明变量,值可以改变。const声明常量,值不可改变(使用const时,常量最好使用大写)

其他的属性let与const一致

 let a = 10;
a = 20;
console.log(a); // const B = 30;
B = 40; //TypeError: invalid assignment to const `b'
console.log(B);

const只保证常量名指向的地址不变,并不能保证地址的数据不变,如果想吧对象冻结数据不可改变,可使用Object.freeze(obj)

 const a = {};
a.name = 'gary';
console.log(a.name); //gary const b = Object.freeze({});
b.name = 'bob';
console.log(b.name); //undefined

在es5中我们都知道,在全局定义变量其实就是等于在全局对象设置属性,全局对象属性与全局变量是等价的。全局变量的赋值和全局属性的赋值是同一件事

在es6中修改可这一规定,使用let和const和class声明的全局变量与全局对象不等价

 var a = 10;
console.log(a === window.a); //true let b = 20;
console.log(b === window.b); //false

es6之let和const的更多相关文章

  1. es6(一):es6介绍以及let,const

    es是js的规范,而js是具体实现 将es6转化为es5代码工具:运用的多的是babel 在线转换地址:babel,traceur(属于谷歌)   1.let申明变量:let其实可以完全取代var,并 ...

  2. ES6(let 和 const)

    一项新技术的出现肯定是为了解决一些问题,那么ES6的出现主要是解决了哪些问题?它的出现给我们带来了什么便利?当它没有出现的时候,某些问题怎么处理?ES6的方法和以前的方法比较又有什么不同呢?根据提出的 ...

  3. ES6 之 let和const命令 Symbol Promise对象

    ECMAScript 6入门 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了. (2016年6月,发布了小幅修订的<ECMASc ...

  4. es6之let和const命令的一些笔记

    let和const命令 let命令 基本用法 let命令用来声明变量,声明的变量只在命令所在的代码块内有效.for循环中很适合使用let命令. 有必要理解的例子: var a = []; for (v ...

  5. JavaScript ES6 的let和const

    1 作用域和提升 1.1 作用域(Scope) 某个变量名或者函数名,在某个程序片段中是否可见或者可访问,如果是,那么这个程序片段就是这个变量名或者函数名的作用域.比如: var name = &qu ...

  6. ES6中var/let/const的区别

    let的含义及let与var的区别: let 声明的变量只在它所在的代码块有效: 如下: for (let i = 0; i < 10; i++) { console.log(i); } con ...

  7. ES6系列之let/const及块级作用域

    本系列是在平时阅读.学习.实际项目中有关于es6中的新特性.用发的简单总结,目的是记录以备日后温习:本系列预计包含let/const.箭头函数.解构.常用新增方法.Symbol.Set&Map ...

  8. ES6 中 let and const

    let 和 const 命令 let 命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a = 10; v ...

  9. ES6中let与const命令详解

    阮一峰ES6入门 let 作用域 let命令用来声明变量,但声明的变量只在let命令所在的代码块内有效. { let a = 10; var b = 1; } a // ReferenceError: ...

随机推荐

  1. Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)

    本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...

  2. C语言 · 整数平均值

    编写函数,求包含n个元素的整数数组中元素的平均值.要求在函数内部使用指针操纵数组元素,其中n个整数从键盘输入,输出为其平均值. 样例输入: (输入格式说明:5为输入数据的个数,3 4 0 0 2 是以 ...

  3. HTML 事件(二) 事件的注册与注销

    本篇主要介绍HTML元素事件的注册.注销的方式. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流.事件委托 4. ...

  4. iOS系列文章

    本博客全为原创,如果借鉴了其他文章会在博文的下面进行说明.欢迎转载,但要在文章中给出原文链接,谢谢. 有链接的说明已经发布,没有链接的说明还没有发布. 并不是所有的博文都在这里罗列,有兴趣的可以看博客 ...

  5. OVS local network 连通性分析 - 每天5分钟玩转 OpenStack(132)

    前面已经创建了两个 OVS local network,今天详细分析它们之间的连通性. launch 新的 instance "cirros-vm3",网络选择 second_lo ...

  6. Django

    一.Django 简介 Django 是一个由 Python 写成的开放源代码的 Web 应用框架.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统) ...

  7. golang语言构造函数

    1.构造函数定义 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中.特别的一个类可以有多个构造函数 ,可根据其参数个 ...

  8. linux拷贝命令,移动命令

    http://blog.sina.com.cn/s/blog_7479f7990101089d.html

  9. Extjs 让combobox写起来更简单

    也已经写了很久时间的extjs ,每次都用到很多的combobox,配置很多东西觉得实在是太麻烦,所以根据常用到的情况写了一个简便的combobox,再次记录下来,以免放在某个地方忘记了找不到了. 定 ...

  10. Flexible 弹性盒子模型之CSS flex-basis 属性

    实例 设置第二个弹性盒元素的初始长度为 80 像素: div:nth-of-type(2){flex-basis:80px;}   效果预览 浏览器支持 表格中的数字表示支持该属性的第一个浏览器的版本 ...