Skip to content

JavaScript中var、let和const的区别

在声明变量时,通常会使用var,因为它是大家熟知的方法。然而,自从ECMAScript 6以来,JavaScript中引入了两个新的关键字来声明变量,它们是letconst。为了理解使用这些关键字的必要性,让我们先来看看var是如何工作的。

使用var声明的变量会在运行时被添加到代码的开头,所以它们是全局变量。

例如,我们有这样一个函数,其中声明了一个变量:

javascript
function myFunction(number, compare) {
  var status;
  if (number < compare) {
    status = '这个数字更小';
  } else if (number > compare) {
    status = '这个数字更大';
  } else {
    status = '这个数字相等';
  }
  return status;
}

myFunction(1, 2); // 这个数字更小

实际发生的情况如下:

javascript
var status; // 'status'被全局化

function myFunction(number, compare) {  
  if (number < compare) {
    status = '这个数字更小';
  } else if (number > compare) {
    status = '这个数字更大'; 
  } else {
    status = '这个数字相等';
  }
  return status;
}

myFunction(1, 2); // 这个数字更小

// 所以如果我们在函数外部使用status变量,它是存在的,只是未定义
console.log(status); // undefined

即使这样也不会有问题(尽管这是一个不好的做法):

javascript
function myFunction(number, compare) {
  if (number < compare) {
    status = '这个数字更小';
  } else if (number > compare) {
    status = '这个数字更大';
  } else { 
    status = '这个数字相等';
  }
  var status; // 不要这样做
  return status;
}

myFunction(1, 2); // 这个数字更小

这种行为称为提升,无论我们是否希望如此,它都会发生。

然而,letconst的工作方式不同。与var不同的是,这些关键字在代码块级别上工作,在运行时不会转换为全局变量。这使我们能够更好地控制在哪里声明变量以及在哪些地方可以操作它们。

const关键字,顾名思义,与let的不同之处在于它的值一旦初始化就不能修改,所以它必须用一个值进行初始化。这很好,因为我们永远不会有未定义的常量变量。

使用let的相同示例:

javascript
function myFunction(number, compare) {
  let status;
  if (number < compare) {
    status = '这个数字更小';
  } else if (number > compare) {
    status = '这个数字更大';
  } else {
    status = '这个数字相等';
  }
  return status;
}

myFunction(1, 2); // 这个数字更小

// 在这种情况下,status变量在'myFunction'函数外部不存在
// 所以会抛出一个错误
console.log(status); // ReferenceError: status is not defined

现在使用const的相同示例:

javascript
function myFunction(number, compare) {
  const status
  if (number < compare) {
    status = '这个数字更小' // TypeError: Assignment to constant variable.
  } else if (number > compare) {
    status = '这个数字更大' // TypeError: Assignment to constant variable.
  } else {
    status = '这个数字相等' // TypeError: Assignment to constant variable.
  }
  return status
}

myFunction(1, 2) // TypeError: Assignment to constant variable.

虽然const给了我们声明常量的能力,但需要注意的一点是,当常量的值是一个引用,也就是一个object时,不能给常量重新分配另一个对象,但可以修改它已有的对象。这是因为对象的引用被维护,即使它的属性被修改。

示例:

javascript
// 有效
const person = {
  name: '',
  surname: '',
  age: '',
};
const car = {
  wheels: '',
  color: '',
  doors: '',
};

// 不会抛出错误,因为没有修改'person'的引用
person.name = 'Carlos';

// TypeError: Assignment to constant variable
// 错误,因为试图将'person'对象的引用改为'car'对象的引用
person = car;

因此,强烈建议使用let而不是var。另外在声明常量时,使用const。这样我们可以避免不良做法,并更好地控制应用程序的工作方式。