es6中 let 和 const 命令

一、let 的使用

ES6中新增了一种变量声明方式  let  ,let 用来声明变量,用法和 var 相似,但是 let 声明的变量只在代码块内有效。

与 var 相比,let 大概有下面几种特殊之处

1.块级作用域

2.不存在变量提升

3.暂时性死区

4.不允许重复声明

 

1.1块级作用域

在es5中是没有块级作用域的,es5只有全局作用域和函数作用域,es6新增了块级作用域

{
    let a = 6;
    var b = 9;
}

console.log(a);  // 报错
console.log(b);  // 9

上面代码中 var在大括号中声明的变量在括号外面还是可以取到值,let声明的变量不能,let声明的变量会形成块级作用域,防止变量全局污染

1.1.1块级作用域的作用

块级作用域一个很好的用处是 for ,比如

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


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

上面第一段代码中,变量ivar命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。

第二段代码中,变量ilet声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。

此外 for 循环还有一个要注意的地方,for 循环里面循环变量设置和循环体是两个作用域

循环变量设置是父作用域   循环体是子作用域

for(let i = 0; i <=10; i++){
    let i = 10;
    console.log(i);
}
// 输出 11 个  10 

1.2不存在变量提升

var声明的变量都可以变量提升,let 声明的变量不可以

例如:

console.log(a); // undefined
var a = 2;

console.log(b); // 报错
let b = 2; 

javascript引擎在执行代码是会将 var 声明的变量放到代码最前面,即声明会提升到最前面,变量赋值没有提升,所以变量初始化为 undefined,故第一段代码输出为 undefined 

1.3暂时性死区

暂时性死区是在一个块级区域声明了 let 变量,则在这个块级区域中,let声明前的任何区域使用该变量都会报错

{
   a = a + 1; //报错
   let a = 2;
}

{
   a = 3;     //报错
   let a = 2;
}

1.4不允许重复声明

let不允许在相同作用域内,重复声明同一个变量。

// 报错
function func() {
  let b= 10;
  var b = 1;
}

// 报错
function func() {
  let b = 10;
  let b = 1;
}

二、const常量

1.基本用法

const声明一个只读的常量。一旦声明,常量的值就不能改变。

1.1声明基本类型

用 const 声明基本数据类型值,声明之后不能再改变

const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

1.2引用类型

const foo = {};

foo.prop = 123;
foo.prop // 123

foo = {}; // TypeError: "foo" is read-only

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。

你可能感兴趣的:(ES6)