ES6
ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。
ES6 实际上是一个泛指,泛指 ES2015 及后续的版本。
为什么使用 ES6?
每一次标准的诞生都意味着语言的完善,功能的加强。JavaScript语言本身也有一些令人不满意的地方。
- 变量提升特性增加了程序运行时的不可预测性
- 语法过于松散,实现相同的功能,不同的人可能会写出不同的代码
ES6 的新增语法
let
ES6中新增了用于声明变量的关键字
let声明的变量只在所处于的块级有效
if (true) {
// 大括号可以形成块级作用域
let a = 10;
}
console.log(a) //报错: a is not defined
注意:使用let
关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。
好处 : 可以防止循环变量变成全局变量 : (使用var就不会报错)
for (let i = 0; i < 2; i++) {
}
console.log(i);//报错: i is not defined
不存在变量提升
console.log(a); // a is not defined
let a = 20;
暂时性死区
利用let
声明的变量会绑定在这个块级作用域,不会受外界的影响
var tmp = 123;
if (true) {
//因为在此块级作用域中,使用了let声明了tmp变量,那么tmp会与此块级作用域进行绑定,形成死区,不受外界影响(无法访问外部的tmp)
tmp = 'abc';//这里会报错,变量未声明,不能赋值
let tmp;
}
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用let关键字声明变量</title>
</head>
<body>
<script type="text/javascript">
/*
let关键字就是用来声明变量的
使用let关键字声明的变量具有块级作用域
在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的
防止循环变量变成全局变量
使用let关键字声明的变量没有变量提升
使用let关键字声明的变量具有暂时性死区特性
*/
/* --------let关键字就是用来声明变量的-------- */
// let a = 10;
// console.log(a);
/* --------使用let关键字声明的变量具有块级作用域-------- */
// if (true) {
// let b = 20;
// console.log(b)
// if (true) {
// let c = 30;
// }
// console.log(c);
// }
// console.log(b)
/* -------在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的--------- */
// if (true) {
// let num = 100;
// var abc = 200;
// }
// console.log(abc);
// console.log(num)
/* -------防止循环变量变成全局变量--------- */
// for (let i = 0; i < 2; i++) {}
// console.log(i);
/*-----使用let关键字声明的变量没有变量提升------*/
// console.log(a);
// let a = 100;
/* -------使用let关键字声明的变量具有暂时性死区特性------- */
var num = 10
if (true) {
console.log(num);
let num = 20;
}
</script>
</body>
</html>
经典面试题
面试题1:此题没有用到let
var arr = [];
for (var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0](); //2
arr[1](); //2
经典面试题图解:此题的关键点在于变量i是全局的,函数执行时输出的都是全局作用域下的i值。
面试题2:此题用到let关键字
let arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();//0
arr[1]();//1
经典面试题图解:
- 此题的关键点在于每次循环都会产生一个块级作用域,
- 每个块级作用域中的变量都是不同的,
- 函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的i值.
小结
- let关键字就是用来声明变量的
- 使用let关键字声明的变量具有块级作用域
- 在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的
- 防止循环变量变成全局变量
- 循环中的i,使用var声明的话是全局变量,但是这样不合理,而使用let就是局部变量
- 使用let关键字声明的变量没有变量提升
- 使用let关键字声明的变量具有暂时性死区特性
- 死区:不受外界影响
const
作用:声明常量,常量就是值(内存地址)不能变化的量
常量:常态的量,值是常态的量,值无法改变
const:constant常量
具有块级作用域
if (true) {
const a = 10;
}
console.log(a) // a is not defined
声明常量时必须赋值
const PI; // Missing initializer in const declaration,声明常量时丢失初始化
常量赋值后,值不能修改 (栈中存储的内容无法修改)
- 如果是简单数据类型,则不允许修改值。
- 如果是复杂数据类型,不能改变地址,只能改变内部的值
const PI = 3.14;
PI = 100; // Assignment to constant variable. //给常量重新指定值
const ary = [100, 200];
ary[0] = 'a';//复杂数据类型内部的值,是可以改变的
ary[1] = 'b';
console.log(ary); // ['a', 'b'];
ary = ['a', 'b']; // Assignment to constant variable.//但是复杂数据类型变量本身无法改变
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用const关键字声明常量</title>
</head>
<body>
<script type="text/javascript">
// 使用const关键字声明的常量具有块级作用域
// if (true) {
// const a = 10;
// if (true) {
// const a = 20;
// console.log(a);
// }
// console.log(a);
// }
// console.log(a);
// 使用const关键字声明的常量必须赋初始值
// const PI = 3.14;
// 常量声明后值不可更改
const PI = 3.14;
// PI = 100;
const ary = [100, 200];
ary[0] = 123;
ary = [1, 2]
console.log(ary);
</script>
</body>
</html>
小结
-
具有块级作用域
-
声明常量时必须赋值
-
const声明的变量是一个常量
-
既然是常量不能重新进行赋值,如果是基本数据类型,不能更改值,如果是复杂数据类型,不能更