ES6学习之路(一) let与const

来源:互联网 发布:孙鑫java视频教程下载 编辑:程序博客网 时间:2024/06/05 14:55

let and const

相同点:
let与const用来声明变量,用法与var类似,但是let与const声明的变量只在它们命令所在的代码块中有效;

let与const声明的变量不存在变量提升,所以必须在声明后使用,否则会报错,没有赋值会输出undefined;

//变量声明前调用会报错console.log(a)//报错let a=0;console.log(a)//0
//变量声明未赋值返回Undefinedlet a;console.log(a)//undefined

如果在块级作用域中存在用 let和const声明的变量,那么这些变量必须在let和const声明后执行,否则就会报错;阮一峰老师称之为“暂时性死区”

let tmp=0;if(true){    //在本作用域中已有tmp的声明,需要在声明后使用,否则报错;    tmp=5;//报错    let tmp;    console.log(tmp)//undefined    tmp=123;    console.log(tmp)//123}

let和const不允许在同一作用域中,重复声明同一个变量

{    //重复声明会报错    let a=0;    var a=5;//Identifier 'a' has already been declared    let b=0;    b=5;//Identifier 'a' has already been declared}

不同点:
const声明一个只读的常量,一旦声明常量值不能改变;用const声明必须马上赋值 否则报错;

    //const 必须声明后必须马上赋值 不然会报错    const a;//Missing initializer in const declaration    //声明后对于简单数据类型来说,值是不能改变的(常量),否则就会报错;    const a=10;    a=20;//Assignment to constant variable.

const所声明的变量对于简单的数据类型(数值,字符串,布尔值)来说算是固定的常量,但是对于复合类型的数据(对象,数组)来说,const只能保证这个变量指向的内存地址不变,对象的值与数组的值还是可以修改的。

    const foo={};    foo.prop=123;    console.log(foo.prop)//123

上面代码就是修改了foo这个变量的prop属性的值,因为prop属性属于foo这个对象,使用的是foo的内存地址,所以const不会报错;

但是,如果试图去修改foo对象的话就会报错;

const foo={};foo={};//TypeError: Assignment to constant variable.

数组同理

//调用属性不会报错const arr=[];arr.push('hello');arr.length=0;
    //想要修改对象就会报错    const arr=[];    arr=[];//TypeError: Assignment to constant variable.

let&for循环

for循环中 如果用var来初始化i的值,声明的是一个全局的变量i;
用let来声明i,每次循环都会创建一个新的变量i;

//使用var初始化变量var arr=[];for(var i=0;i<10;i++){    arr[i]=function (){    console.log(i)    }}arr[6]()//10

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

如果使用let,声明的变量仅在块级作用域内有效,最后输出的是6。

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

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

另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

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

上面代码正确运行,输出了3次abc。这表明函数内部的变量i与循环变量i不在同一个作用域,有各自单独的作用域。
(上面是学习阮一峰老师的ES6入门记录下来的)

原创粉丝点击