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 增强变量声明的更多相关文章

  1. ES6常用新特性

    https://segmentfault.com/a/1190000011976770?share_user=1030000010776722 该文章为转载文章!仅个人喜好收藏文章! 1.前言 前几天 ...

  2. ES6 && ECMAScript2015 新特性

      ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES201 ...

  3. Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27

    Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27 1. 修改历史2 2. 适用语言::几乎所有编程语言.语言提升的三个渠道::语法,类库,框架,ide2 2.1. 单根继承  ...

  4. ES6新特性:let和const的使用

    (声明, 本文的所有代码均在node的最新稳定版本v4.4.3中执行的, 如果在浏览器中执行请把JS的运行环境提升为ES6) 以前一直用var定义变量, 现在有了两种新的定义变量的方式, 1: let ...

  5. ES6新特性之 let 、const

    在 ES6之前,ES5中js只有全局作用域和函数作用域,作用域是一个独立的地盘,让变量不外泄出去,但是上例中的变量就外泄了出去,所以此时 JS 没有块级作用域的概念. 全局作用域就是最外层的作用域,如 ...

  6. ES6:JavaScript 新特性

    我相信,在ECMAScript.next到来的时候,我们现在每天都在写的JavaScript代码将会发生巨大的变化.接下来的一年将会是令JavaScript开发者们兴奋的一年,越来越多的特性提案将被最 ...

  7. ES6相关新特性介绍

    你可能已经听说过 ECMAScript 6 (简称 ES6)了.ES6 是 Javascript 的下一个版本,它有很多很棒的新特性.这些特性复杂程度各不相同,但对于简单的脚本和复杂的应用都很有用.在 ...

  8. ECMAScript6新特性之let、const

    第一次在博客园写博客,想把自己每一天学习到的知识点记录下来,心里有点紧张(PS:不知道自己能不能写好......嘿嘿).言归正传,咱们先来说说"ECMAScript"这到底是啥玩意 ...

  9. H5、C3、ES6的新特性

    H5的新特性 1.语义化标签 有利于SEO,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各个关键字的权重. 语义化的HTML在没有CSS的情况下也能呈现较好的内容结构与代码结构 方便其 ...

随机推荐

  1. Leetcode名企之路

    微信扫码关注,每天推送一道面试题! 公众号:Leetcode名企之路 作者简介 知乎ID: 码蹄疾 码蹄疾,毕业于哈尔滨工业大学. 小米广告第三代广告引擎的设计者.开发者: 负责小米应用商店.日历.开 ...

  2. 腾讯云的对象存储COS

    什么是对象存储COS Clound Object Storage,COS,专门为企业和开发者们提供能够存储海量的分布式存储服务,用户可以随时通过互联网对大量数据进行批量存储和处理,在任意位置存储和检索 ...

  3. PhpStorm中实现代码自动换行

    方法一: 随便打开一个页面,在显示行号(最左边)这里鼠标右击,勾选"Use Soft Wraps". 方法二: 选择"File-->>Settings--&g ...

  4. C语言进阶——基本数据类型01

    刚开始人们还没有数据类型这个概念,但是人们经常要使用到固定内存大小的内存,这个时候那时的程序员就要记录一段信息在内存中的起始位置和终止位置,很不方便,演变到后来就出现了数据类型这个概念 什莫是数据类型 ...

  5. linux——高级文本处理命令之wc、cut、sort

    1.  wc :Word Count 命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出 1.1 命令格式: wc [选项]文件... 1.2 命令参数: -c 统计字节数. -l  ...

  6. 138. Subarray Sum【Lintcode,by java】

    Description Given an integer array, find a subarray where the sum of numbers is zero. Your code shou ...

  7. 最近公共祖先 lca (施工ing)

    声明 咳咳,进入重难点的图论算法之一(敲黑板): 题目: 洛谷 P3379 先放标程,施工ing,以后补坑!!!(实在太难,一个模板这么长 [ 不过好像还是没有 AC自动机 长哎 ],注释都打半天,思 ...

  8. 《Java核心技术36讲》阅读笔记:谈谈对Java平台的理解笔记

    1. 谈谈你对Java平台的理解. Java是一种面向对象的语言,最显著的特性有两个方面: 一个就是一次编译,到处运行(Write once, run anywhere),能够非常容易的获得跨平台能力 ...

  9. 对Prolog的感想和我写的一些教程

    我第一次见到Prolog这门独特的编程语言是在<七周七语言(Seven Languages in Seven Weeks)>中看到的.<七周七语言>名字看起来与市面上什么< ...

  10. 20155211 2016-2017-2 《Java程序设计》第四周学习总结

    20155211 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 这周的内容感觉较上周相比难度增加 教材学习中的问题和解决过程 刚开始学习第六章的时候的时候敲 ...