存储所需信息 — 变量

阅读了前几篇文章后,您现在应该知道 JavaScript 是什么,它能为您做什么,如何将其与其他 Web 技术一起使用,以及其主要功能的高级概述。在本文中,我们将深入探讨真正的基础知识,了解如何使用 JavaScript 最基本的构建块 — 变量。

预备知识 了解 HTMLCSS 基础知识
学习成果
  • 什么是变量以及它们为何如此重要。
  • 使用 let 声明变量,使用值初始化它们,以及使用新值重新赋值。
  • 使用 const 创建常量。
  • 变量和常量之间的区别,以及何时使用它们。
  • 变量命名最佳实践。
  • 可以存储在变量中的不同类型的值 — 字符串、数字、布尔值、数组和对象。

所需工具

在本文中,您将被要求输入代码行以测试您对内容的理解。如果您使用的是桌面浏览器,输入示例代码的最佳位置是浏览器的 JavaScript 控制台(有关如何访问此工具的更多信息,请参阅什么是浏览器开发工具)。

什么是变量?

变量是值的容器,例如我们可能在求和中使用的数字,或者我们可能用作句子一部分的字符串。

变量示例

我们来看一个例子

html
<button id="button_A">Press me</button>
<h3 id="heading_A"></h3>
js
const buttonA = document.querySelector("#button_A");
const headingA = document.querySelector("#heading_A");

let count = 1;

buttonA.onclick = () => {
  buttonA.textContent = "Try again!";
  headingA.textContent = `${count} clicks so far`;
  count += 1;
};

在此示例中,按下按钮会运行一些代码。首先,它会更改按钮本身的文本。其次,它会显示按钮被按下次数的消息。该数字存储在一个变量中。每次用户按下按钮时,变量中的数字将递增一。

没有变量

为了理解为什么这如此有用,让我们思考一下如何在不使用变量存储计数的情况下编写此示例。它最终会是这样的

html
<button id="button_B">Press me</button>
<h3 id="heading_B"></h3>
js
const buttonB = document.querySelector("#button_B");
const headingB = document.querySelector("#heading_B");

buttonB.onclick = () => {
  buttonB.textContent = "Try again!";
  headingB.textContent = "1 click so far";
};

您可能尚未完全理解我们正在使用的语法(!)但是您应该能够理解。没有变量,我们就无法知道按钮被点击了多少次。当无法记住任何信息时,给用户的消息将很快变得无关紧要。

变量很有意义,随着您对 JavaScript 的了解越来越多,它们将开始变得驾轻就熟。

变量的一个特殊之处在于它们几乎可以包含任何东西——不仅仅是字符串和数字。变量还可以包含复杂数据甚至整个函数来完成惊人的事情。您会随着学习的深入了解更多信息。

注意:我们说变量包含值。这是一个重要的区别。变量本身不是值;它们是值的容器。您可以将它们想象成可以存放物品的小纸箱。

A screenshot of three 3-dimensional cardboard boxes demonstrating examples of JavaScript variables. Each box contains hypothetical values that represent various JavaScript data types. The sample values are "Bob", true and 35 respectively.

声明变量

要使用变量,您首先必须创建它——更准确地说,我们称之为声明变量。为此,我们输入关键字 let,后跟您想要给变量命名的名称

js
let myName;
let myAge;

这里我们创建了两个变量,名为 myNamemyAge。尝试将这些行输入到您的 Web 浏览器控制台中。之后,尝试使用您自己的名称选择创建一个或两个变量。

注意:在 JavaScript 中,所有代码指令都应以分号 (;) 结尾——您的代码可能在单行上正确运行,但当您将多行代码一起编写时,可能不会正确运行。尽量养成包含它的习惯。

您可以通过仅输入变量名称来测试这些值现在是否存在于执行环境中,例如

js
myName;
myAge;

它们目前没有值;它们是空容器。当您输入变量名时,您应该会得到一个返回值为 undefined。如果它们不存在,您将收到错误消息——尝试输入

js
scoobyDoo;

注意:不要混淆存在但没有定义值的变量和根本不存在的变量——它们是非常不同的事物。在您上面看到的盒子类比中,不存在意味着没有盒子(变量)可以存放值。没有定义值意味着有一个盒子,但里面没有值。

初始化变量

声明变量后,您可以使用值对其进行初始化。您可以通过输入变量名称,后跟等号 (=),再后跟您想要赋予它的值来完成此操作。例如

js
myName = "Chris";
myAge = 37;

现在尝试回到控制台并输入这些行。在每种情况下,您都应该在控制台中看到您分配给变量的值,以确认它。同样,您可以通过在控制台中输入变量名称来返回变量值——再次尝试这些操作

js
myName;
myAge;

您可以同时声明和初始化变量,如下所示

js
let myDog = "Rover";

这可能是您大部分时间都会做的事情,因为它比在两个单独的行上执行两个操作更快。

关于 var 的说明

您可能还会看到另一种声明变量的方式,使用 var 关键字

js
var myName;
var myAge;

早在 JavaScript 最初创建时,这是声明变量的唯一方法。var 的设计令人困惑且容易出错。因此,在现代 JavaScript 版本中创建了 let,这是一个用于创建变量的新关键字,其工作方式与 var 有些不同,从而在此过程中解决了 var 的问题。

下面解释了一些简单的区别。我们现在不会深入探讨所有区别,但随着您对 JavaScript 的了解越来越多,您将开始发现它们(如果您现在真的想阅读它们,请随时查看我们的let 参考页面)。

首先,如果您编写一个声明和初始化变量的多行 JavaScript 程序,您实际上可以在初始化变量后使用 var 声明变量,并且它仍然可以工作。例如

js
myName = "Chris";

function logName() {
  console.log(myName);
}

logName();

var myName;

注意:这在将单行输入 JavaScript 控制台时不起作用,仅在 Web 文档中运行多行 JavaScript 时才起作用。

这之所以有效,是因为变量提升——请阅读var 变量提升以获取更多详细信息。

变量提升不再适用于 let。如果我们在上面的示例中将 var 更改为 let,它将因错误而失败。这是一件好事——在初始化变量后声明变量会导致代码混乱,难以理解。

其次,当您使用 var 时,您可以根据需要多次声明同一个变量,但使用 let 则不能。以下代码可以工作

js
var myName = "Chris";
var myName = "Bob";

但以下代码将在第二行抛出错误

js
let myName = "Chris";
let myName = "Bob";

您必须这样做

js
let myName = "Chris";
myName = "Bob";

同样,这是一个明智的语言决定。没有理由重新声明变量——这只会让事情变得更加混乱。

由于这些原因以及更多原因,我们建议您在代码中使用 let,而不是 var。除非您明确为旧版浏览器提供支持,否则不再有理由使用 var,因为所有现代浏览器自 2015 年以来都支持 let

注意:如果您正在浏览器的控制台中尝试此代码,请 предпочте将这里的每个代码块作为一个整体复制并粘贴。Chrome 的控制台中有一个功能,允许使用 letconst 重新声明变量

> let myName = "Chris";
  let myName = "Bob";
// As one input: SyntaxError: Identifier 'myName' has already been declared

> let myName = "Chris";
> let myName = "Bob";
// As two inputs: both succeed

更新变量

一旦变量用值初始化,您就可以通过赋予它不同的值来更改(或更新)该值。尝试在控制台中输入以下行

js
myName = "Bob";
myAge = 40;

关于变量命名规则的题外话

您可以随意命名变量,但也有一些限制。通常,您应该只使用拉丁字符(0-9、a-z、A-Z)和下划线字符。

  • 您不应该使用其他字符,因为它们可能会导致错误或难以被国际受众理解。
  • 不要在变量名开头使用下划线——这在某些 JavaScript 结构中用于表示特定含义,因此可能会令人困惑。
  • 不要在变量开头使用数字。这是不允许的,会导致错误。
  • 一个安全的约定是坚持使用小驼峰命名法,即您将多个单词连在一起,第一个单词全部小写,然后后续单词首字母大写。到目前为止,我们一直在文章中使用这种命名法来命名变量。
  • 使变量名直观,以便它们描述所包含的数据。不要只使用单个字母/数字或冗长的短语。
  • 变量区分大小写——因此 myagemyAge 是不同的变量。
  • 最后一点:您还需要避免使用 JavaScript 保留字作为变量名——我们的意思是构成 JavaScript 实际语法的词!因此,您不能使用像 varfunctionletfor 这样的词作为变量名。浏览器会将它们识别为不同的代码项,因此您将收到错误。

注意:您可以在词法语法——关键字中找到一个相当完整的保留关键字列表,以避免使用。

好的命名示例

age
myAge
init
initialColor
finalOutputValue
audio1
audio2

不好的命名示例

1
a
_12
myage
MYAGE
var
Document
skjfndskjfnbdskjfb
thisisareallylongvariablenameman

现在,请牢记以上指导,尝试创建更多变量。

变量类型

我们可以将几种不同类型的数据存储在变量中。在本节中,我们将简要描述这些类型,然后在未来的文章中,您将更详细地了解它们。

数字

您可以在变量中存储数字,可以是像 30 这样的整数(也称为整型),也可以是像 2.456 这样的小数(也称为浮点数)。与某些其他编程语言不同,您不需要在 JavaScript 中声明变量类型。当您为变量赋予数字值时,您不需要包含引号

js
let myAge = 17;

字符串

字符串是文本片段。当您给变量一个字符串值时,您需要将其用单引号或双引号括起来;否则,JavaScript 会尝试将其解释为另一个变量名。

js
let dolphinGoodbye = "So long and thanks for all the fish";

布尔值

布尔值是真/假值——它们可以有两个值,truefalse。它们通常用于测试条件,之后根据情况运行代码。例如,一个简单的用例是

js
let iAmAlive = true;

而实际上它会更像这样使用

js
let test = 6 < 3;

这使用了“小于”运算符(<)来测试 6 是否小于 3。正如您可能预期的那样,它返回 false,因为 6 不小于 3!您将在本课程的稍后部分学习更多关于此类运算符的知识。

数组

数组是一个单一对象,包含多个用方括号括起来并用逗号分隔的值。尝试在控制台中输入以下行

js
let myNameArray = ["Chris", "Bob", "Jim"];
let myNumberArray = [10, 15, 40];

一旦定义了这些数组,您就可以通过它们在数组中的位置访问每个值。尝试以下行

js
myNameArray[0]; // should return 'Chris'
myNumberArray[2]; // should return 40

方括号指定一个索引值,该值对应于您想要返回的值的位置。您可能已经注意到 JavaScript 中的数组是零索引的:第一个元素位于索引 0。

对象

在编程中,对象是一种模拟现实世界对象的代码结构。您可以有一个表示盒子并包含其宽度、长度和高度信息的对象,或者您可以有一个表示人并包含其姓名、身高、体重、所说语言、问候方式等数据的对象。

尝试在控制台中输入以下行

js
let dog = { name: "Spot", breed: "Dalmatian" };

要检索存储在对象中的信息,您可以使用以下语法

js
dog.name;

动态类型

JavaScript 是一种“动态类型语言”,这意味着,与某些其他语言不同,您无需指定变量将包含什么数据类型(数字、字符串、数组等)。

例如,如果您声明一个变量并为其赋予一个用引号括起来的值,浏览器会将该变量视为字符串

js
let myString = "Hello";

即使引号中的值只是数字,它仍然是字符串——而不是数字——所以要小心

js
let myNumber = "500"; // oops, this is still a string
typeof myNumber;
myNumber = 500; // much better — now this is a number
typeof myNumber;

尝试将上面的四行逐一输入到控制台中,看看结果是什么。您会注意到我们正在使用一个名为typeof的特殊运算符——它返回您在其后输入的变量的数据类型。第一次调用时,它应该返回string,因为那时myNumber变量包含字符串'500'。看看您第二次调用它时它返回什么。

JavaScript 中的常量

除了变量,您还可以声明常量。它们类似于变量,只是

  • 您必须在声明它们时初始化它们。
  • 初始化后,您不能为它们分配新值。

例如,使用 let,您可以声明一个变量而不对其进行初始化

js
let count;

如果您尝试使用 const 执行此操作,您将看到错误

js
const count;

同样,使用 let,您可以初始化一个变量,然后为其分配一个新值(这也称为重新赋值变量)

js
let count = 1;
count = 2;

如果您尝试使用 const 执行此操作,您将看到错误

js
const count = 1;
count = 2;

请注意,尽管 JavaScript 中的常量必须始终命名相同的值,但您可以更改它所命名值的内容。这对于数字或布尔值等简单类型来说不是一个有用的区别,但考虑一个对象

js
const bird = { species: "Kestrel" };
console.log(bird.species); // "Kestrel"

您可以更新、添加或删除使用 const 声明的对象的属性,因为即使对象的内容已更改,常量仍然指向同一个对象

js
bird.species = "Striated Caracara";
console.log(bird.species); // "Striated Caracara"

何时使用 const,何时使用 let

如果使用 const 能做的事情不如 let 多,为什么还要优先使用它而不是 let 呢?实际上 const 非常有用。如果您使用 const 来命名一个值,它会告诉任何查看您代码的人,这个名称永远不会被赋给不同的值。无论何时他们看到这个名称,他们都会知道它指的是什么。

在本课程中,我们遵循以下关于何时使用 let 和何时使用 const 的原则

能用 const 就用 const,需要时才用 let

这意味着,如果您可以在声明变量时初始化它,并且以后不需要重新赋值,那么就将其设为常量。

总结

到目前为止,您应该对 JavaScript 变量以及如何创建它们有了相当多的了解。在下一篇文章中,我们将为您提供一些测试,您可以用来检查您对这些信息的理解和掌握程度。