ES6笔记之var、let、const和块作用域

一、什么是块作用域
特点1:let,const声明的变量拥有块作用域,通常以{}作为作用域的分隔符,外层作用域无法读取内层作用域的变量

//错误
function f1() {
  if (true) {
    let n = 10;
  }
  console.log(n); // Uncaught ReferenceError: n is not defined
}

f1()

//正确
function f1() {
  if (true) {
    let n = 3;
    console.log(n); // 3
  }
}

f1()

因为n的作用域在if语句的{}中,外层作用域不可调用。

特点2:不存在“变量提升”,可能“暂时性死区”

//错误
function f1() {
  console.log(a); // undefined
  console.log(b); // Uncaught ReferenceError: b is not defined
  var a = 1;
  let b = 2;
}

f1()

//等于
function f1() {
  var a;
  console.log(a); // undefined
  console.log(b); // Uncaught ReferenceError: b is not defined
  a = 1;
  let b = 2;
}

f1()

//正确
function f1() {
  var a;
  let b = 2;
  console.log(a); // undefined
  console.log(b); // 2
  a = 1;
  console.log(a); // 1
}

f1()

var 声明的变量,会提升到最近的非块作用域首行(变量提升),但是let变量并不具备该特性。

特点3:不允许在同一个作用域重复声明

//错误
{
    let a = 2;
    let a = 2;
}
//正确
let a = 2;
if (true)
{
    let a = 2;
}

二、块作用域的作用

1、防止数据泄露

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

//等于

var i;
var a = [];
for (i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

var 声明的变量会发生变量提升,容易造成数据泄露,i因为“变量提升”,作用域变成“全局作用域”或“函数作用域”,改成如下代码即可。

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

注:for语句的{}是()的子作用域

2、不同块作用域声明的let变量,变量拥有独立性

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

不同的块作用域上let声明了两个i,两个i是独立的,以下代码i仅在for中let声明过一次,因此是同一个i。

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

若是var声明的变量,则数据会发生“变量提升”,实际上是同一个变量。

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

//等于

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

猜你喜欢

转载自blog.csdn.net/qq_36470086/article/details/82357233