JS基础:let、var、const 的区别

576 阅读4分钟

众所周知在ES5 中我们声明变量只能使用 var 关键字。在ES6中新增了 let 和const。使用他们声明的变量和var是有一些区别的,下面详细介绍写具体都有那些不同。

varlet/const 的区别主要有以下几个方面

varlet/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变量
}

暂时性死区和不能变量提升存在的意义在于:为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为

不允许重复声明变量

letconst不允许在相同作用域内,重复声明同一个变量

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

上面详细介绍了 varlet/const 的区别,那么 letconst 又有什么区别呢?

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 的主要区别的介绍了,你掌握了没?😁