es6学习笔记--let和const

es6学习笔记--let和const


今天学习了es6中的let和const命令,借此整理一下笔记。


let :


  let 和 var 的声明方式一样,但有 var 比不上的优点。下面用 var 和 let 的例子来加深对 let 的理解。


1 let 只作用与当前作用域中
  在声明var时,在无特别情况下,代码块里的var外部也可以访问到的,但是let声明之后,外部是访问不到的,会报错。


{
  var a = 123
  let b = 456
}
console.log(a)  // 123
console.log(b)  // ReferenceError: b is not defined
以前面试经常出现的一道题,下面会打印出什么


复制代码
var a = [];
for (var i = 0; i < 10; i++) {
   a[i] = function (www.huachengjpt.com) {
        console.log(i);
    };
}
a[5](); 
复制代码
结果是 10 ,这就是 var i 没有指定块级作用域,指向了全局。变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i,数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。


如果使用let,利用它的具有块级作用域的特性,我们可以获取数组a[5]的值。


复制代码
var a = [];
for (let i = 0; i < 10; i++) {
   a[i] = function (www.huaxinyul.com) {
        console.log(i);
   };
}
a[5]();   // 5
复制代码
为何是5,而不是10 了,因为变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是5。 


另外 let 为javascript添加了块级作用域,使声明的变量只作用与当前的代码块。


复制代码
function fn(www.huayyule.com) {
  let n = 1;
  if (true) {
    let n = 2;
    console.log(n)    // 2
  }
  console.log(n)    // 1
}
fn()
复制代码
而 var 则不会,因为根据var变量声明的原则,if代码块的n重复使用,后面的覆盖前面的。


复制代码
function fn() {
  var n = 1;
  if (true) {
    var n = 2;
    console.log(n)    // 2
  }
  console.log(n); // 2
}
fn()
 


复制代码
2 let 不存在变量提升


var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined。这是javascript在预编译过程中,把var声明的变量提升到当前作用域的最上端,变量的值不变。但是let不存在变量提升,如果未声明就使用或者声明在使用之后会报错 ReferenceError。


console.log(a)
var a = 1    // undefined 
console.log(b)
let b = 2    // Uncaught ReferenceError: b is not defined
3 let 具有暂时性死区


只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
复制代码
{
    a = 123
    b = 456
    let a
    var b
    console.log(a)    // Uncaught ReferenceError: a is not defined
    console.log(b)    // 456
}
复制代码
上面的例子的情况就是说明了let的暂时性死区,let a在使用之后,触发了暂时性死区,就报错。而var因为在声明时发生变量提升提到最顶端,所以能打印出456。


4 let 不允许重复变量


let不允许在相同作用域内,重复声明同一个变量,否则会报错。
{
    let a = 1   
    let a = 2    // Uncaught SyntaxError: Identifier 'a' has already been declared
}
{
    var a = 1   // Uncaught SyntaxError: Identifier 'a' has already been declared
    let a = 2   
}
5 let 使变量不再是默认的全局变量。


var a = 1
console.log(window.a)   // 1
let b = 2
console.log(window.b) www.tygj178.com   // undefined
ES6规定:为了保持兼容性,又不利于模块化变成,所以var命令和function命令声明的全局变量,依旧是顶层对象的属性;let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。
 
const:


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


const a = 1
a = 2   // Uncaught TypeError: Assignment to constant variable.
console.log(a)
其本质就是:const一旦声明变量,就必须立即初始化,不能留到以后赋值。


const 的特点和 let 的一样:
  1 只作用与当前的块级作用域
  2 不存在变量提升
  3 也存在暂时性死区
  4 不允许重复声明同一个变量
  5 使变量不再是全局属性


ps:const 的本质:不是变量的值不得改动,而是变量指向的那个内存地址不得改动。


简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。
复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,里面的内容可以改变
复制代码
const a = 'string'
a = 'String'  // Uncaught TypeError: Assignment to constant variable.
console.log(a)
const b = {
    name: 'peter'
}
b.name = 'Bob'
console.log(b)    // {name: "Bob"}
b = {}    //error
console.log(b)
复制代码
a 是字符串,值就保存在地址,不可变,一变就报错
b 是个对象,对象保存的是个地址,是个指针,只要地址不变,里面的内容可以捣鼓,但是如果要把这个对象b初始化等等就相当于改变了地址。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值