ES6的新特性(2)——let 与 const 增强变量声明
let 与 const 增强变量声明
ES6 新增了let命令,用来声明局部变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。
先看个var的常见变量提升的面试题目:
题目1:
var a = 99; // 全局变量a
f(); // f是函数,虽然定义在调用的后面,但是函数声明会提升到作用域的顶部。
console.log(a); // a=>99, 此时是全局变量的a
function f() {
console.log(a); // 当前的a变量是下面变量a声明提升后,默认值undefined
var a = 10;
console.log(a); // a => 10
} // 输出结果:
undefined
10
99
ES6 可以用 let 定义块级作用域变量
在 ES6 之前,我们都是用 var 来声明变量,而且 JS 只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了 var 声明变量的访问范围。 例如:
{
  var i = 9;
}
console.log(i); //
ES6 新增的let,可以声明块级作用域的变量。
{
  let i = 9; // i变量只在 花括号内有效!!!
}
console.log(i); // Uncaught ReferenceError: i is not defined
let 配合 for 循环的独特应用
let非常适合用于 for循环内部的块级作用域。JS 中的 for 循环体比较特殊,每次执行都是一个全新的独立的块作用域,用 let 声明的变量传入到 for 循环体的作用域后,不会发生改变,不受外界的影响。看一个常见的面试题目:
for (var i = 0; i <10; i++) {
  setTimeout(function() {  // 同步注册回调函数到 异步的 宏任务队列。
    console.log(i);        // 执行此代码时,同步代码for循环已经执行完成
  }, 0);
}
// 输出结果
10   共10个
// 这里面的知识点: JS的事件循环机制,setTimeout的机制等
// 解决以上问题
for (var i = 0; i < 10; i++) {
((index) => {
setTimeout(() => {
console.log(index);
}, 4);
})(i);
}
// 输出结果:
0 1 2 3 4 5 6 7 8 9
如果把 var改成 let声明: // i虽然在全局作用域声明,但是在for循环体局部作用域中使用的时候,变量会被固定,不受外界干扰。
for (let i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i); // i 是循环体内局部作用域,不受外界影响。
}, 0);
}
// 输出结果:
0 1 2 3 4 5 6 7 8 9
let 没有变量提升与暂时性死区
用let声明的变量,不存在变量提升。而且要求必须 等let声明语句执行完之后,变量才能使用,不然会报Uncaught ReferenceError错误。 例如:
console.log(aicoder); // 错误:Uncaught ReferenceError ...
let aicoder = 'aicoder.com';
// 这里就可以安全使用aicoder
ES6 明确规定,如果区块中存在 let 和 const 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。 总之,在代码块内,使用 let 命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
let 变量不能重复声明
let 不允许在相同作用域内,重复声明同一个变量。否则报错:Uncaught SyntaxError: Identifier 'XXX' has already been declared
例如:
let a = 0;
let a = 'sss';
// Uncaught SyntaxError: Identifier 'a' has already been declared
块接作用域嵌套
// 块接作用域嵌套
{
let k = 9;
{
console.log(k); // => 9
let m = 10;
console.log(m); // => 10
}
console.log(m); //ReferenceError: m is not defined
}
这样原先我们的立即执行函数就可以被块级作用域取代了。
let 小结
ES6 的 let 让 js 真正拥有了块级作用域,也是向这更安全更规范的路走,虽然加了很多约束,但是都是为了让我们更安全的使用和写代码。
const 常量声明
const 声明一个只读的常量。一旦声明,常量的值就不能改变,并且一旦声明常量,就必须立即初始化,不能留到以后赋值。。
对于一般的简单类型的常量我们一般用大写的字符组成的单词来做名字,比如:
const SITE_URL = 'http://aicoder.com'; // 修改常量会报错。
SITE_URL = 'hamkd.com'; // TypeError: Assignment to constant variable. const PI; // SyntaxError: Missing initializer in const declaration
PI = 3.1415926; // 不允许声明后改动
const 与 let 同样都属于块级作用域
const 的作用域与 let 命令相同:只在声明所在的块级作用域内有效。
{
  const S_URL = 'http://aicoder.com';
}
console.log(S_URL); // ReferenceError: S_URL is not defined
const 也存在暂时性死区
console.log(M_URL); // ReferenceError: M_URL is not defined
{
const M_URL = 'http://aicoder.com';
}
const 与复杂类型
const 能确保简单类型的值不能被修改。 如果用 const 声明的复杂类型的变量,那么此复杂类型的变量指向内存地址的指针就不能修改了,但是指向的那块内存地址的内容是可以修改的。
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop; //
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
let 和 const 声明的变量不属于顶层对象的属性
为了保持兼容性,var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性;let 命令、const 命令、class 命令声明的全局变量,不属于顶层对象的属性。
const a = 9;
window.a; // => undefined
let c = 10;
window.c; // => undefined
var b = 9;
window.b; // => 9
总结
es6 的语法的确简单方便
ES6的新特性(2)——let 与 const 增强变量声明的更多相关文章
- ES6常用新特性
		
https://segmentfault.com/a/1190000011976770?share_user=1030000010776722 该文章为转载文章!仅个人喜好收藏文章! 1.前言 前几天 ...
 - ES6 && ECMAScript2015 新特性
		
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES201 ...
 - Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27
		
Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27 1. 修改历史2 2. 适用语言::几乎所有编程语言.语言提升的三个渠道::语法,类库,框架,ide2 2.1. 单根继承 ...
 - ES6新特性:let和const的使用
		
(声明, 本文的所有代码均在node的最新稳定版本v4.4.3中执行的, 如果在浏览器中执行请把JS的运行环境提升为ES6) 以前一直用var定义变量, 现在有了两种新的定义变量的方式, 1: let ...
 - ES6新特性之 let 、const
		
在 ES6之前,ES5中js只有全局作用域和函数作用域,作用域是一个独立的地盘,让变量不外泄出去,但是上例中的变量就外泄了出去,所以此时 JS 没有块级作用域的概念. 全局作用域就是最外层的作用域,如 ...
 - ES6:JavaScript 新特性
		
我相信,在ECMAScript.next到来的时候,我们现在每天都在写的JavaScript代码将会发生巨大的变化.接下来的一年将会是令JavaScript开发者们兴奋的一年,越来越多的特性提案将被最 ...
 - ES6相关新特性介绍
		
你可能已经听说过 ECMAScript 6 (简称 ES6)了.ES6 是 Javascript 的下一个版本,它有很多很棒的新特性.这些特性复杂程度各不相同,但对于简单的脚本和复杂的应用都很有用.在 ...
 - ECMAScript6新特性之let、const
		
第一次在博客园写博客,想把自己每一天学习到的知识点记录下来,心里有点紧张(PS:不知道自己能不能写好......嘿嘿).言归正传,咱们先来说说"ECMAScript"这到底是啥玩意 ...
 - H5、C3、ES6的新特性
		
H5的新特性 1.语义化标签 有利于SEO,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各个关键字的权重. 语义化的HTML在没有CSS的情况下也能呈现较好的内容结构与代码结构 方便其 ...
 
随机推荐
- (Les16 执行数据库恢复)-控制文件恢复
			
测试丢失所有控制文件恢复[20180517] rman target / show all; configure channel 1 device type disk format ' ...
 - 用JavaScript获取URL参数的方法之一
			
若地址栏URL为:abc.html?m=tomms&c=allsearchlist&pageNo=1&pageNum=20&text=1 <script> ...
 - jQuery属性操作之.val()函数
			
目录 .val()实例方法的三种用法 .val()函数源码 调用形式:$('xxx').val(); 调用形式:$('xxx').val(value); 调用形式:$('xxx').val(funct ...
 - 日期插件rolldate.js的使用
			
日期插件rolldate.js的使用 下载地址:http://www.jq22.com/jquery-info19834 效果: 代码: <!DOCTYPE html> <html ...
 - 偏前端-HTML5 sessionStorage-会话存储
			
sessionStorage 是HTML5新增的一个会话存储对象,用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据.本篇主要介绍 sessionStorage(会话存储) ...
 - 一个没有成就而即将退赛的OIer的告别书
			
期末考试成绩出来了. 我也知道混在这个班的时间不长了. 尽管如此,我觉得父母的意见是正确的,我确实不适合OI.所以我会成为省三都没有的一个OIer. 我不后悔,因为曾经是我自己错了. 我感谢遇到了好的 ...
 - 图 ADT接口 遍历运算 常规运算 邻接矩阵实现
			
Graph.h (图的结构, 遍历, 常规操作接口) /*定义图的最大定点数, 它要大于等于具体图的顶点树n*/ #define MaxVertexNum 12 /*定义图的最大边数,它要大于等于 ...
 - android studio 插件开发(自动生成框架代码插件)
			
android studio 插件开发 起因 去年公司开始上新项目,正好android在架构这方面的讨论也开始多了起来,于是mvp架构模型就进入我们技术选择方案里面,mvp有很多好处,但是有一个非常麻 ...
 - IDEA新建Web项目
			
file->New project->输入项目名(例如这里输入HelloWeb) 选择JDK为合适版本->next ->finish即可 在新建的项目HelloWorld上右击 ...
 - 20155212 实验三 敏捷开发与XP实践
			
20155212 实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器&g ...