博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ES6初体验——(1)let和const命令
阅读量:5051 次
发布时间:2019-06-12

本文共 2675 字,大约阅读时间需要 8 分钟。

  前言:

  参考书籍:ECMAScript 6 入门    链接: http://es6.ruanyifeng.com/  阮一峰老师,书中示例详尽,此处只做简单梳理和理解,仅作督促自己学习使用

  1、let命令,用来声明变量。用法类似于 var,但是所声明的变量,只在let命令所在的代码块内有效。而ES5中,是没有块级作用域的概念的。

var a = [];for (var i = 0; i < 10; i++) {
//i由var定义,属于全局变量,i只定义了一次,每次循环,i的值递增,for循环执行完毕,i的值变成10,所以输出10 a[i] = function () { console.log(i); };}a[6](); // 10
var a = [];for (let i = 0; i < 10; i++) {
//i由let定义,只在当轮循环有效,即每一轮循环的i都是重新声明的, a[i] = function () { //由于JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算 console.log(i); };}a[6](); // 6a[3](); // 3

  for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

for (let i = 0; i < 3; i++) {  let i = 'abc';  console.log(i);}// abc// abc// abc

  var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined,(这是因为预解析的缘故)。但是由let声明的变量则不存在变量提升现象,即不被预解析,它要求变量必须在声明语句之后才可以使用,否则会抛出错误。

console.log(foo); // Uncaught ReferenceError: foo is not defined    始终没有声明过就直接使用会报错
console.log(foo); // 输出undefined         先使用再声明,输出undefined(由var定义的变量)var foo = 2;
foo = 2;console.log(foo); //2     此处没有报错,反而输出了2,是因为此处的foo没有由var声明,则被默认为window下的一个属性console.log(window.foo);//2

  暂时性死区:只要块级作用域内存在let命令(不管它的位置在前在后),它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响(外部是否定义过这个变量已经和这个区域无关了)。一旦在这个区域内,let声明不是在最前面,即先使用后才由let声明,则会报错。

if (true) {  // TDZ开始  tmp = 'abc'; // ReferenceError  console.log(tmp); // ReferenceError      //事实上,在代码执行的时候,如果报错了,会阻塞后面的语句执行,所以,把这两句注释掉,后面的语句才会正常执行  let tmp; // TDZ结束  console.log(tmp); // undefined  tmp = 123;  console.log(tmp); // 123}

  let不允许在相同作用域内,重复声明同一个变量。因此,不能在函数内部重新声明参数。

  2、块级作用域

  ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

  第一种场景,内层变量可能会覆盖外层变量。

  第二种场景,用来计数的循环变量泄露为全局变量,循环变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。

  ES6 允许块级作用域的任意嵌套。

  外层作用域无法读取内层作用域的变量。

  内层作用域可以定义外层作用域的同名变量。

  块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)(即匿名函数自执行)不再必要了。(原意是为了不定义全局变量,所以放在一个匿名函数自执行里面)。

// IIFE 写法(function () {  var tmp = ...;  ...}());// 块级作用域写法{  let tmp = ...;  ...}

  3、const命令

  const声明一个只读的常量,在声明时,要立即初始化该变量,即给该变量赋值,否则会报错。由const声明的变量,一旦声明,其值就不能改变。

  在刚刚探讨的其他方面,const与let是相同的。

  本质:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针。如果真的想将对象冻结,应该使用Object.freeze方法。

const foo = {};// 为 foo 添加一个属性,可以成功foo.prop = 123;foo.prop // 123// 将 foo 指向另一个对象,就会报错foo = {}; // TypeError: "foo" is read-only

  4、顶层对象的属性

  顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象。ES5 之中,顶层对象的属性与全局变量是等价的。ES6 为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。

 

var a = 1;// 如果在 Node 的 REPL 环境,可以写成 global.a// 或者采用通用方法,写成 this.awindow.a // 1let b = 1;window.b // undefined

  

  

  

  

  

转载于:https://www.cnblogs.com/chaoyueqi/p/7896426.html

你可能感兴趣的文章
洛咕 P2480 [SDOI2010]古代猪文
查看>>
js-创建对象的几种方式
查看>>
JDK JRE Java虚拟机的关系
查看>>
2018.11.20
查看>>
word20161215
查看>>
12th week blog
查看>>
dijkstra (模板)
查看>>
编译Linux驱动程序 遇到的问题
查看>>
大型分布式网站架构技术总结
查看>>
HDU 1017[A Mathematical Curiosity]暴力,格式
查看>>
[算法之美] KMP算法的直观理解
查看>>
EntityFramework 性能优化
查看>>
【ASP.NET开发】菜鸟时期的ADO.NET使用笔记
查看>>
android圆角View实现及不同版本号这间的兼容
查看>>
OA项目设计的能力③
查看>>
Cocos2d-x3.0 文件处理
查看>>
全面整理的C++面试题
查看>>
Activity和Fragment生命周期对比
查看>>
android 分辨率自适应
查看>>
查找 EXC_BAD_ACCESS 问题根源的方法
查看>>