ES6知识点(一)

258 阅读4分钟

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

let 和 const

在原来的ES5时,定义变量,函数用的var会造成变量提升,于是ES6新增了letconst语法。接下来用代码说明

var a=[]
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]()
var b = [];
for (let j = 0; j < 10 ;j++){
  b[j] = function () {
    console.log(j)
  }
}
b[6]()
//输出:
10
6

上下仅有的不同是for循环里面的 i j 定义方式不同,上面定义的 i 为全局变量,for循环结束, i 为10。而下面定义的 j 为局部变量,只在for(){}的作用域内有效,于是形成了上面的结果。

另外for循环的的设置循环变量括号内部是父作用域,而循环体则是子作用域。---来自阮一峰老师的博客介绍

var的变量存在变量提升,什么意思呢,就是var定义的变量,在js运行时,会在运行开始的时候执行一条语句 var a 此时aundefined,如果在定义a变量之前调用a变量,会显示undefined。而现在ES6为了减少这种情况,同时规范代码,新提出了let指令,let定义的变量,只有在let的块作用域内有效,出了作用域调用就会报错// 报错ReferenceError

暂时性死区

ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。即在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。有了这个,typeof就会更加安全,如果let定义之前typeof,会报错,而如果没有定义,则会输出undefined。
还有一点: let 不允许重复定义,不能同时定义相同的变量两次。

块作用域

在ES5中只有全局作用域和局部作用域,带来了很多不合理的场景,所以如今ES6提出了块作用域,强调规范

第一种场景,内层变量可能会覆盖外层变量。 第二种场景,用来计数的循环变量泄露为全局变量。(上面开头例子) 详见阮一峰老师的博客阮一峰-let和const

关于函数声明

ES5中规定:函数只能在顶层作用域或者函数作用域中声明,不能在块级作用域申明。但是浏览器中还是支持在块级作用域中申明函数,不会报错。

而ES6引入了块级作用域,规定块级作用域外不可引用作用域内的函数

function fnc() { 
   console.log('I am outside!');
   }
(function () {
  if (0) {
    function f() { console.log('I am inside!'); }
  }

  f();
}());

上面的代码在ES5中会输出I am inside!,因为类似于var变量,函数会var声明提前,将if作用域内的function会提前至if之前,即 var f = undefined于是在ES6中回报错。

  test.js:10
  f();
  ^
TypeError: f is not a function

原因是ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。

  • 允许在块级作用域内声明函数。
  • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
  • 同时,函数声明还会提升到所在的块级作用域的头部。

const命令

const会声明一个只读的变量,不能更改,也不能再定义并且定义的同时要立即赋值。同时const也是存在暂时性死区和块级作用域。与之前let类似

const只是定义数据所在的内存地址不能变动,而不是数据不能改动,即如果const定义一个数组或者对象,数组的push(),push()方法依然有效,对象设置属性也正常,但是对const定义的数组或者对象等再次赋值,负责会报错。如果永久冻结,不能变动,有一个冻结方法是Object.freeze

如果有如下的定义:

const foo = Object.freeze({});
foo.prop = 123;

正常模式会无效,而严格模式会报错(具体没有尝试,还没有具体碰到两种模式,只是了解)

ES6申明变量6种方法

globalThis对象

ES6还引入了globalThis对象,用来表示顶层对象,比如浏览器的顶层对象是window,WebWorker的顶层对象是self,Node里面是global

本次文章主要参考自阮一峰的ECMAScript6入门(一)