ES6——let、const

ES6中新添加了两种声明变量的方式:let、const。对比原有的变量声明方式 var,它们有以下区别:

一、let与var的区别

1、let声明的变量,不会提升,var反之。

function foo(){

     console.log( a ); //Uncaught ReferenceError: a is not defined  未定义

     let a = 2;

    }

function foo(){

     console.log( a ); //undefined 未赋值

     var a = 2;

    }

2、let不允许在相同的作用域内,重复声明同一个变量,var可以。

//错误一

{

let a=1;

let a=2;  //Identifier 'a' has already been declared 标识符“a”已被声明 

console.log(a);

}

//错误二

{

let a=1;

var a=2;  //Identifier 'a' has already been declared 标识符“a”已被声明 

console.log(a);

}

//var 重复声明时,后声明的值覆盖前声明的值

{

var a=1;

var a=2;

console.log(a);//输出2

}

注意:

(1)for循环中,小括号里的部分与花括号里的部分不是一个作用域,可以理解为他们是嵌套关系,小括号是父作用域,花括号是子作用域,所以,下面这段代码不算是重复定义变量:

for(let a=0;a<5;a++){

        let a=6;//不报错

}

(2)注意区别函数与for循环,函数参数默认已经定义了,不能使用let、const声明:

function my(b='小杨'){

let b='小张';

console.log(b);//Uncaught SyntaxError: Identifier 'b' has already been declared

}

my();

3、let实际上是JavaScript增加的块级作用域。所声明的变量只在let命令所在的代码块内有效。

function foo(){

    let a=1;

    if (true){

        let a=2;

    }

console.log(a);//输出1,外层代码块不受内层代码块的影响

}

function foo(){

    var a=1;

    if (true){

        var a=2;

    }

console.log(a);//输出2

}

再看下面这段代码:

var a = [];

    for(var i = 0; i < 10; i++) {

        var c = i;

        a[i] = function(){            

            console.log( c );

        };

    }

    a[6]();  //9 var定义的i是全局变量,每一次循环之后,i的结果会影响到之前循环后的结果,在这调用的函数输出的是for循环执行到最后的结果。

改成let声明:

var a = [];

for (var i = 0; i < 10; i++) {

        let c = i;

        a[i] = function(){            

            console.log( c );

        };

}

a[6]();  //6 let定义的i只在块级作用域中起作用,每一次循环,都是一个新的块级作用域,每次循环产生的块级作用域之间互不影响。

4、关于全局对象属性

在ES5中,全局对象的属性和全局变量是等价的。ES6规定,使用var, function声明的全局变量依旧作为全局变量的属性存在,而使用let,const,class声明的全局变量则不属于全局变量的属性。

var foo = 'foo';

let bar = 'bar';

foo === window.foo; // =>true

bar === window.bar; // => false

二、const与var的区别

1、const与let的特性基本相同,但顾名思义,const用于声明常量,一旦声明,必须立即赋值,且以后不可更改。

const a=1;

console.log(a);//输出1

 a=2;

console.log(a);//报错

const a=3;

console.log(a);//报错

2、const定义的对象是可以修改的,比如:

const a=['qqq','wwww'];

a.push('nnn');

console.log(a);//输出["qqq", "wwww", "nnn"],是不报错的

要想定义的对象不能修改,可以这样做:

const a=Object.freeze(['qqq','wwww']);

a.push('nnn');

console.log(a);//报错,被冻结的对象不能修改

三、小结

ES5中只有两种声明变量的方式:var、function,ES6种添加了四种声明变量的方式:let、const、class、import(后续会进行介绍)。

let可以完全取代var,因为二者作用几乎相同,且let没有任何副作用。在let和const之间,优先使用const,尤其是只应该设置常量的全局环境。大部分的函数一旦定义就不会改变(除了使用初始化分支的方式覆写函数的时候),所以,我们一般推荐使用const来声明一个函数。最后,V8只在严格模式下支持let和const的声明方式。

最后再对let/const和var的区别进行一下汇总,使用let声明的变量:

隶属于块级作用域,块级作用域外不可见

不存在“变量提升”

同一作用域内不得存在名称相同的变量

当声明为全局变量时不会作为全局对象的属性

你可能感兴趣的:(ES6——let、const)