ES6新特性-let/const的基本使用,以及let与var的区别

142 阅读3分钟

ES6中新增了let和const声明变量,那么let变量和var声明变量有什么区别呢?在实际开发中,应该选择哪一种声明变量的方式?

一、let不能重复声明变量

使用var重复声明变量时,后面的值会覆盖前面变量的值,比如:

var a= 10;
var a= 50;
console.log(a)//可以运行,输出为50。

使用let重复声明变量时,则代码会报错,比如:

let a= 10;
let a= 50;
console.log(a)//报错,没有输出

二、let不能在声明变量前使用变量

也就是说,在变量未声明之前是不能使用该变量的,但是在v8解析js代码时,函数调用栈创建代码执行上下文时,在词法环境还是会先创建变量,只是不能被访问。代码示例:

console.log(a);
let a = 10;//Uncaught ReferenceError: Cannot access 'a' before initialization

使用var时,则可以在声明变量前使用变量,var声明变量时,词法环境会先创建变量且可以访问。只不过会输出undefined.

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

三、let/const没有作用域提升

在ES6之前,只有全局作用域和函数作用域。在ES6的新特性中,增加了块级作用域代码快的概念,可以直接使用{代码快}创建块级作用域,该作用域对let/const/function/class声明的类型是有效的,这句话的意思即,对于作用域中使用let关键字声明的变量,外层是不可以访问的,而var声明的变量,外层可以访问。举个例子:

{
    let a = 10;
}
console.log(a);//Uncaught ReferenceError: a is not defined

而使用var在let中声明变量时,则块级作用域不生效,即有{}和没有{}是一样的,var在{}创建的变量相当于在全局作用域里。如下:

{
    var a = 10;
}
console.log(a);//输出10

四、const声明数组和对象,可以修改里面的内容

const声明单个数值或字符串时,如果后面重新对该变量进行赋值,则会报错。举个例子:

const a =5 ;
a=10;//moni.html:77 Uncaught TypeError: Assignment to constant variable.
const a = hello;
a=world;Uncaught ReferenceError: hello is not defined

但是对于数组和对象,则可以通过数组的push方法修改里面的内容。举个例子:

const arr= ['a','b','c']
  arr.push('d');
  console.log(arr);//输出['a', 'b', 'c', 'd']

可以使用push/pop等方法修改里面的内容,但是不能将另外一个数组赋值给该变量,举个例子:

const arr= ['a','b','c']
  arr = ['b','c','d'];//Uncaught TypeError: Assignment to constant variable.

对象同理:

const obj ={
    name : '蔡文姬',
    age : 18
}
obj.address='beijing';
console.log(obj);//输出{name: '蔡文姬', age: 18, address: 'beijing'}

五、案例分享:for循环中的点击事件

给四个按钮添加点击事件 使用var 声明时,

for (var i = 0; i < btns.length; i++) {
  
    btns[i].onclick = function() {
      console.log("第" + n + "个按钮被点击") 
  }
}//无论点击哪个按钮,都会输出第四个按钮被点击了,

使用let声明时:

for (let i = 0; i < btns.length; i++) {
  btns[i].onclick = function() {
    console.log("第" + i + "个按钮被点击")
  }
}//点击哪个按钮,输出哪个按钮。

为什么会出现以上现象呢,因为使用var声明时,i是一个全局变量,for没有形成块级作用域,i++最终是4,function执行时,会往上层作用域找i,此时会找到全局作用域i,也就是4,所以无论点击哪个按钮,都会输出第四个。 而使用let创建变量时,会在for循环中形成块级作用域,function会直接找到btns[i],则可以依次输出。

六、总结

在实际开发中,尽量使用let和const,不使用var如果确定后面会更改变量的值,则使用let,如果不确定会不会修改变量,都尽量使用const。