众所周知在ES5 中我们声明变量只能使用 var 关键字。在ES6中新增了 let 和const。使用他们声明的变量和var是有一些区别的,下面详细介绍写具体都有那些不同。
var 和 let/const 的区别主要有以下几个方面
var 和 let/const 区别
块级作用域
在 ES5 中只有全局作用域和函数作用域,并没有块级作用域。因此给我们的开发带来了一些不便。例如
1.内层变量会覆盖外层变量
下面我们分别用let 和 var 声明变量看下最终输出的结果是什么。
// 用 var声明变量
var name = 'lxm'
function getName() {
console.log(name);// 想打印外层的lxm
if(false){
var name = 'lxm love'
}
}
getName(); // 输出 undefined
// 用 let 声明变量
let name = 'lxm'
function getName() {
console.log(name);// 想打印外层的lxm
if(false){
let name = 'lxm love'
}
}
getName(); // 输出 lxm
2.计数的循环变量会被泄漏为全局变量
var list = ['l', 'x', 'm', 'love', 'js'];
for (var i = 0; i < list.length; i++) {
console.log(list[i]);
}
console.log(i); // 输出 5 i 在全局范围都可以读到
// 上面代码改成 for 循环中将 var 改成 let
var list = ['l', 'x', 'm', 'love', 'js'];
for (let i = 0; i < list.length; i++) {
console.log(list[i]);
}
console.log(i); //报错 Uncaught ReferenceError: i is not defined
有了块级作用域我们再也不必担心变量重名,如下我们可以在不同的代码块中声明同名的变量而不会相互影响
{
let name = ‘lxm’;
// 其他
}
{
let name = ‘lxm love js’;
// 其他
}
对于在块级作用域声明函数需要注意,在块级作用域声明函数,最好使用匿名函数的形式。
if(true){
let fun = function () {}; // 作用域为块级 声明的函数作用域更清晰
}
同时,ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
'use strict';
if (true)
function f() {} // 报错 需要给if加个{}
变量提升
什么是变量提升呢?即 在同一作用域下,变量可以在声明之前使用,值为 undefined
在 ES5 中使用var声明变量,会出现变量提升的现象。注意一点,对于函数,函数声明可以提升,但是函数表达式不存在变量提升。
// 使用 var
console.log(name); // 输出undefined
var name = 'lxm';
// 使用 let
console.log(name); // 报错ReferenceError
let name ='lxm';
暂时性死区
let和const声明的变量存在暂时性死区,什么又是暂时性死区呢?即 只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。例如可以执行下面这段代码看下效果
var name = 'lxm'; // 声明
if (true) {
name = 'lxm love js'; // 报错 Uncaught ReferenceError: Cannot access 'name' before initialization
let name; // 绑定了if这个块级的作用域 导致不能出现name变量
}
暂时性死区和不能变量提升存在的意义在于:为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。
不允许重复声明变量
let、const不允许在相同作用域内,重复声明同一个变量
function func() {
let name = 'lxm';
let name = 'lxm love js'; // 报错 Uncaught SyntaxError: Identifier 'name' has already been declared
}
func();
let、const声明的全局变量不会被挂在顶层对象下
浏览器环境顶层对象是: window,node环境顶层对象是: global,var声明的全局变量会挂在顶层对象下面,而let、const不会挂在顶层对象下面。如下
// 如果在 Node环境,可以写成 global.name 或者写成 this.name
var name = 'lxm';
window.name // lxm
let name1 = 1;
window.name1 // 输出 undefined
上面详细介绍了 var 和 let/const 的区别,那么 let 和 const 又有什么区别呢?
const
const一旦声明值就不能改变
const prop = '哈哈';
prop = '嘻嘻' // 报错 Uncaught TypeError: Assignment to constant variable.
对于简单对象来说,内存地址就是值,即常量(一变就报错)。但是对于对象而言,对象本身不能重复赋值(变量指向的那个内存地址所保存的数据不得改动),但是可以给对象的属性重新赋值
const obj = {name: 'lxm'}
obj = {name: 'lxm love js'} // 报错 Uncaught TypeError: Assignment to constant variable.
obj['name'] = 'lxm love js' // 不报错
一旦声明,必须马上赋值
let prop1; var prop2; // 不报错
const prop3 = '哈哈'
const prop4; // 报错 Uncaught SyntaxError: Missing initializer in const declaration
以上就是 对 let、var、const 的主要区别的介绍了,你掌握了没?😁