ES6 --- 新的变量声明方式 let 与 const 解析

ES6 --- 新的变量声明方式 let 与 const 解析

let

  • let 声明的变量只在 let 命令所在的代码块内有效。
{
let tmp = 5;
console.log(tmp); // 5
}
console.log(tmp); // Uncaught ReferenceError: tmp is not defined

let 声明的变量只在 let 命令所在的代码块内有效, 在代码块之外无效

const

  • const 声明一个常量(所谓常量就是物理指针不可以更改的变量),声明之后不允许改变。意味着,一但声明必须初始化,否则会报错。
const MAX = 9999999;
console.log(MAX); // 9999999
const MIN;
console.log(MIN); // Uncaught SyntaxError: Missing initializer in const declaration
  • const 除了不能改变物理指针的特性,其他特性和 let 一样。

let const var 的区别

  • let 是在代码块内有效,var 是在全局范围内有效。
{
var temA = 'A';
let temB = 'B'
}
console.log(temA); // A
console.log(temB); // Uncaught ReferenceError: temB is not defined

temA和temB都声明在代码块里面,temA是由var声明,在外部可以直接访问,temB是由let声明,在外部不可直接访问,提示错误:temB is not defined

  • let 声明的变量不存在变量提升。
temA = 'A';
temB = 'B'; // Uncaught ReferenceError: temB is not defined
console.log(temA); // A
console.log(temB);

var temA;
let temB;

var 声明的变量存在变量提升,所以temA在赋值语句下面声明,没有问题;let 声明的变量不存在变量提升,所以temB在赋值语句下面声明,提示错误:temB is not defined

  • let 只能声明一次变量 var 可以声明多次变量。
var temA = 'A';
let temB = 'B';
console.log(temA); // A
console.log(temB); // B
var temA = 'C';
let temB = 'D'; // Uncaught SyntaxError: Identifier 'temB' has already been declared
console.log(temA); // C
console.log(temB);
  • let存在暂时性死区
var tem = 3;
if (true) {
tem = 5; // Uncaught ReferenceError: tem is not defined
let tem;
}

ES6规定如果块内存在let命令,那么这个块就会成为一个封闭的作用域,并要求let变量先声明才能使用,如果在声明之前就开始使用,它并不会引用外部的变量。

  • let 不会成为全局对象的一个属性
var temA = 'A';
console.log(window.temA); // A
let temB = 'B';
console.log(window.temB); // undefined

var全局声明后会作为全局对象window的一个属性,而let不会,所以提示undefined

  • const和var的区别,除了const是声明一个不可更改的常量外,和var的区别和let一致,也就是说上面几点let和var的区别,同样也是const和var的区别。

进阶用法

  • 在for循环中使用let定义变量,只在for循环内可以使用。

实现将for循环中的i变量,存入arr数组中,for循环结束后,依次输出。

// ES5的实现
var arr = [];
for(var i = 0; i < 3; i++){
arr.push(function (){
console.log(i);
})
}
arr[0]() // 3
arr[1]() // 3
arr[2]() // 3

为什么每次输入都是3,因为for循环每次做的事只是向数组中存入一个函数,但是函数并没有立刻执行。i是通过var来声明的。当for循环完,此时i的值是3。当你去执行函数的时候,自然输出3

// ES5的闭包实现
var arr = [];
for(var i = 0; i < 3; i++){
arr.push((function (arg){
return function (){
console.log(arg);
}
})(i))
}
arr[0]() // 0
arr[1]() // 1
arr[2]() // 2

利用ES5的闭包也可以实现,但是代码比较复杂,如果用ES6就比较简单了,看下面代码

// ES6的实现
let arr = [];
for(let i = 0; i < 5; i++){
arr.push(function (){
console.log(i);
})
}
arr[0]() // 0
arr[1]() // 1
arr[2]() // 2

为什么这样就能弹出 0,1,2? 其实需要注意个问题,就是这个let i=0;声明的位置,是在for的()内,那么你可以理解成,在for的内部就定义了一个i而且是使用let定义的。所以每次循环就相当于在当前循环的i值的前提下向数组push的。

总结:var let const 都是声明变量的关键字,var的作用域是函数作用域,在一个函数内利用var声明一个变量,则这个变量只在这个函数内有效。如果在函数外部声明一个变量,则这个变量全局有效,var存在变量提升。const一般用来声明常量,且声明的常量是不允许改变的,只读属性,因此就要在声明的同时赋值。const与let一样,都是块级作用域,存在暂时性死区,不存在变量声明提前,不允许重复定义,不会成为全局对象的一个属性。

(内容收集于网上,如有侵权请联系猪猪侠)


分享到:


相關文章: