2.let、const和var关键字如何在JavaScript中工作

119 阅读5分钟

在JavaScript的旧的、前ES6时代,开发人员过去常常使用关键字var​或不使用任何关键字来声明变量。但是时代变了!

随着ES6(EcmaScript 2015)的来临,JavaScript现代时代的开始,该语言有两个新关键字来帮助我们声明变量。它们是let​和const​。

在本文中,我们将通过示例了解所有这些关键字(包括var​),我们将看到何时使用它们,何时不使用它们。

如何在JavaScript中声明变量

在JavaScript中,我们可以通过三种不同的方式声明变量,如下所示:

//没有关键字。它本质上与var相同 并且在“strict”模式下不允许。
name = 'Jack'; 

// Using var
var price = 100;

// Using let
let isPermanent = false; 

// Using const
const PUBLICATION = 'camp' 

最好理解var、let和const这三个概念:

  • 作用域
  • 重新分配一个新值
  • 当在声明变量之前访问它时

这些关键字在这些概念的用法上有所不同。让我们看看如何

JavaScript中的可变作用域

在JavaScript中,我们使用作用域作为识别我们可以在何处以及是否可以使用变量的一种方式。变量可能存在于块内、函数内或函数和块外。

那么,什么是块?块(即代码块)是我们使用一对花括号({…})定义的代码的一部分。类似这样的东西:

{
  let name = "alex";
}

另一方面,函数是要在逻辑上放置在一起的一堆代码指令。

通常,您使用function​关键字和名称定义函数。请注意,您可以定义没有名称的函数,我们称之为匿名函数​。

这是一个名称为test的函数。

function test() {
  let name = "alex";
}

我们称之为全局​的块或函数之外的任何东西。因此,当我们声明变量时,它们可以存在于块内、函数内或块/函数之外——也就是说,它们具有全局作用域。

作用域主要有三种:

  • 区块作用域
  • 函数作用域
  • 全局作用域

三个关键字var​、let​ 和const​ 围绕这些作用域工作。所以让我们了解事物是如何结合在一起的。

如何在块作用域内使用JavaScript变量

如果您不希望在{}​块内声明的变量在块外被访问,则需要使用let​或const​关键字声明它们。在{}​块内使用var​关键字声明的变量也可以在块外访问。所以,要小心。

举个例子:

{
    let f_name  = 'Alex';
    const ZIP = 500067;
    var age = 25;
}

console.log(f_name); // Uncaught ReferenceError: f_name is not defined
console.log(ZIP);  // Uncaught ReferenceError: ZIP is not defined
console.log(age);  // 25

如你所见,age变量的值可能会在不知不觉中被覆盖,并最终引入bug。所以,这个故事的寓意是,

不要在块(块作用域)内使用var​关键字。始终使用let​和const​代替。

如何在函数作用域内使用JavaScript变量

在函数内部使用这些关键字声明的变量无法在函数外部访问。

无论您使用var、let还是const,这都是正确的。在函数内部,它们在管理变量作用域方面非常相似。

再举一个例子:

// f1() is a function

function f1() {
 let f_name = "Alex";
 const ZIP = 560089;
 var age = 25;   
}

f1();

console.log(f_name); // Uncaught ReferenceError: f_name is not defined
console.log(ZIP);  // Uncaught ReferenceError: ZIP is not defined
console.log(age);  // Uncaught ReferenceError: age is not defined

正如上面看到的,没有一个变量可以在函数之外访问,甚至没有使用var​声明的age​。所以,结论是

在函数内部使用var​声明的变量在函数外部无法访问。关键字var​具有函数作用域。

如何在全局作用域内使用JavaScript变量

在任何函数和块之外声明的变量是全局的,据说具有全局作用域​ 。这意味着您可以从当前JavaScript程序的任何部分访问它们。

您可以使用var​、let​和const​来声明全局变量。但是你不应该经常这样做。

let f_name = "Alex";
 const ZIP = 560089;
 var age = 25;  

// f1() is a function
function f1() {
  console.log(f_name); // Alex
  console.log(ZIP);  // 560089
  console.log(age);  // 25
}

f1();

console.log(f_name); // Alex
console.log(ZIP);  // 560089
console.log(age);  // 25

如您所见,变量随处可访问。

因此,要使用var​、let​和const​关键字限制变量的作用域,以下是作用域内可访问性的顺序,从最低开始:

  • var​:函数作用域级别
  • let​:块作用域级别
  • const​:块作用域级别

下图显示了这三个关键字的思维导图,参考了不同的作用域。

如何在JavaScript中将新值重新分配给变量

使用var​或let​声明变量后,您可以在编程流程中将新值重新分配给变量。如果变量可以访问以分配值,则可以。但是使用const​,您根本不能重新分配新值。

// 声明具有初始值的变量
let f_name = "Alex";
const ZIP = 560089;
var age = 25;

// 重新赋值
f_name = "Bob"; // the f_name value is 'Bob"
ZIP = 65457; // Uncaught TypeError: Assignment to constant variable.
age = 78; // the age value is 78

const​有一个棘手的部分,你必须知道。当一个对象被声明并分配一个const​值时,您仍然可以更改其属性​的值。但是你不能将另一个对象值重新分配给同一个变量。这是许多开发人员经常犯的错误。

示例:

const blog = {
    'url': 'https://baidu.com'
}

blog.url = 'https://blog.baidu.info"; //Allowed

blog = {}; // Uncaught TypeError: Assignment to constant variable.

这是一个思维导图,可帮助您了解重新分配对使用这三个关键字声明的变量的工作原理。

在JavaScript中声明变量之前访问变量会发生什么

永远不应该在不声明变量的情况下尝试访问它。但是万一发生这种情况,让我们看看变量的行为。

在非严格模式下使用var​,变量将具有undefined​的值。这意味着变量已声明但未赋值。

在严格模式下,您将得到一个未声明变量的RecontceError​。

使用let​和const​,如果您在声明之前尝试访问变量,您将始终得到一个RecontceError​。

规则是这样的:

  • 不要再使用var​了。
  • 使用let​或const​。
  • 经常地使用​const​。当您需要将另一个值重新分配给变量时,请使用​let​。
  • 不要试图在不声明变量的情况下访问它