大多数情况下,JavaScript 应用都是在处理信息。举两个例子:
- 网上商城——包括一些要出售的商品和购物车的信息。
- 聊天程序——包括用户、消息等一些信息。
变量就是用来储存这些信息的。
变量
变量是数据的“命名存储”。我们可以使用变量来存储商品、访客或其他一些数据。
译注:这里讲的“命名存储”,是指在内存中开辟了一小块区域用于存储数据,这块区域用变量名标识,之后我们可以使用这个变量名来读到这块特定区域里存储的数据。
在 JavaScript 中创建变量使用关键字 let
。
下面的语句创建(或者称声明或定义)了一个名为“message”的变量:
let message;
我们可以通过赋值运算符 =
来给这个变量赋一个值:
let message;
message = 'Hello'; // 变量中存储了一个字符串
字符串现在被保存到与该变量相关联的内存区域中,我们可以使用变量名来访问它:
let message;
message = 'Hello!';
alert(message); // 显示变量内容
简单起见,我们可以将变量声明和赋值合并成一行:
let message = 'Hello!'; // 定义变量并赋值
alert(message); // Hello!
也可以在一行中同时声明多个变量:
let user = 'John', age = 25, message = 'Hello';
这种写法更加简短,但不推荐。为了提高可读性,应该每一个变量声明独处一行。
多行变量声明写法稍微长一点,但更容易阅读:
let user = 'John';
let age = 25;
let message = 'Hello';
有些人也会这样写:
let user = 'John',
age = 25,
message = 'Hello';
甚至是写成“逗号优先”风格:
let user = 'John'
, age = 25
, message = 'Hello';
从技术上讲,所有这些变体效果一样。所以,这是一个关于个人品味和美学的问题。
⚠️旧脚本变量声明 var
在旧脚本中,您还可以找到另一个关键字:var 而不是 let。
var message = 'Hello';
var 关键字几乎等同于 let。也用于声明变量,但有一点不同——“旧式”的行为表现。
var 和 let 之间有些细微的差别,但以后变得不再重要,我们稍后会在《“旧式”var 声明》一章里详细介绍。
真实类比
如果把变量想象成装数据的“盒子”,会更容易理解。
举个例子,可以把变量 message 可以想象成是一个标记 “message” 的盒子,它装有一个值 “Hello!”:
我们可以在盒子里放入任何值。
一个值也可以根据需要多次修改:
let message;
message = 'Hello!';
message = 'World!'; // 值发生了变化
alert(message);
当值发生变化时,旧值将从变量中删除:
我们也可以声明两个变量,并将数据从一个变量复制到另一个。
let hello = 'Hello world!';
let message;
// 将变量 hello 的值 'Hello world' 复制到 message
message = hello;
// 现在两个变量的值一样
alert(hello); // Hello world!
alert(message); // Hello world!
⚠️函数式语言
有趣的是,还存在一些 函数式 编程语言,它们禁止改变变量值。比如 Scala 和 Erlang。
在这种语言中,一旦值被存储在“盒子”中,它就永远存在。如果我们需要存储其他值,语言会强制创建一个新盒子(声明一个新变量),不能再用旧的了。
虽然乍一看可能有点奇怪,但这些语言都有很强的发展能力。更重要的是,在一些领域,比如并行计算,这种限制带来了一定的好处。研究这样一种语言(即使不打算很快使用它)也能帮助我们扩展下思维。
变量命名
在 JavaScript 中,变量名有两个限制:
- 变量名仅能包含字母、数字和符号
$
、_
- 第一个字符不能是数字
下面列举了一些有效的变量名:
let userName;
let test123;
当一个变量名中包含多个单词时,一般使用驼峰命名(camelCase)法。也就是说,名称中每个单词的首字母大写(除第一个),比如 myVeryLongName
。
有趣的是,美元符号 "$"
和下划线 "_"
也可以用在变量名中。它们是普通的符号,就像字母一样,没有任何特殊的意义。
这些名字是有效的:
let $ = 1; // 声明一个变量 "$"
let _ = 2; // 声明一个变量 "_"
alert($ + _); // 3
错误的变量命名:
let 1a; // 不能以数字开头
let my-name; // 中划线 '-' 也是不允许的
⚠️大小写敏感
变量名 apple 和 Apple 是两个不同的变量名。
⚠️非英语字母是允许的,但不推荐
可以使用任何语言的字符,包括西里尔字母、甚至是象形文字:
let имя = '...';
let 我 = '...';
技术上讲,并没错,这样的命名是允许的,但使用英文命名变量是国际上约定的习惯。即使我们在写一个小脚本,它也可能有很长的寿命,来自其他国家的人可能需要花一些时间才能读懂。
⚠️保留字
有一个保留字的清单,是不能用作变量名的,因为它们被语言本身使用了。
例如,单词 let
、class
、return
、function
这些都是保留字。
下面的代码会抛出一个语法错误:
let let = 5; // 不能将变量名声明为 "let", 会出错!
let return = 5; // 也不能将变量名起为 "return", 会出错!
⚠️不带 use strict 的赋值
通常,我们需要在使用变量之前定义一个变量。但是在旧时代,仅通过赋值就能创建一个变量,当然,这是在未启用严格模式的情况下。这种行为是为了兼容旧脚本而保留的。
// note: no "use strict" in this example
num = 5; // the variable "num" is created if didn't exist
alert(num); // 5
这是一个不好的做法,严格模式下会抛出错误:
"use strict";
num = 5; // error: num is not defined
常量
声明一个常量(不变的)变量,要使用 const
而不是 let
:
const myBirthday = '18.04.1982';
使用 const
声明的变量称为“常量”,它们不能被改变。尝试修改会产生错误:
const myBirthday = '18.04.1982';
myBirthday = '01.01.2001'; // error, can't reassign the constant!
当开发人员确定这个变量不会再改变时,可以使用 const,并且别人也能清晰地知道。
大写形式的常量
有一种普遍的做法是使用常量作为难以记住的值的别名,这些值在代码运行前就已知。
这些常量用大写字母 + 下划线来命名。
const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";
// ...当需要获取一个颜色的时候
let color = COLOR_ORANGE;
alert(color); // #FF7F00
好处:
- COLOR_ORANGE 比 “#FF7F00” 更好记
- “#FF7F00” 比 COLOR_ORANGE 更容易录入错误。
- COLOR_ORANGE 比 “#FF7F00” 更有可读性。
我们什么时候应该用大写字母来表示一个常量,什么时候使用常量?
“常量”意味着它的值永远不会改变。但是在运行之前就已知的常量,还有一些是在运行时计算出来的,分配之后不会改变。
例如:
const pageLoadTime = /* 网页加载耗时 */;
页面加载之前不知道 pageLoadTime 的值,所以它的命名是正常的。但它仍然是一个常数,因为它在赋值后不会改变。
换句话说,大写的常量只作为“硬编码”值的别名。
正确命名
说到变量,还有一个非常重要的东西——请合理地命名变量。如果需要的话,花点时间思考。
变量命名是编程中最重要和最复杂的技能之一。快速浏览一下变量名就可以发现哪些代码是由初学者编写的,哪些代码是由经验丰富的开发人员编写的。
在一个真实的项目中,大多数时间都花在修改和扩展现有的代码库上,而不是从头开始编写完全独立的代码。当我们在做其他事情再回来看代码时,理解有意义的命名要容易得多。
请在声明之前花些时间考虑变量的合适名称,会让你事半功倍。
一些好的习惯是:
- 使用可读名称,比如
username
或shoppingCart
- 远离缩写词或短名称,像
a
、b
、c
,除非你知道你在做什么 - 使这个名字最大化地描述和简洁。坏的例子是 data,value。这样的名字什么也没说。如果从数据或值的上下文来看,使用它们是可以的
- 在你的团队和你自己的思维里达成一致。如果一个站点访问者被称为“user”那么我们应该将相关变量像命名成
currentUser
或newUser
,而不是currentVisitor
或者是newManInTown
。
听起来很简单?确实如此,但在实践中创造出好的、具有描性格并且简洁的名称并没那么容易。现在就开始这么做吧。
⚠️重用已有变量还是创建常量?
最后一有个要注意的地方,有些懒惰的程序员,他们不喜欢声明新变量,而是倾向于重用现有的变量。
因此,这个变量就像一个潘多拉盒子,里面是什么?谁也不知道,需要人工去确认。
虽然在声明变量的功夫上节省了一点时间和精力,但在调试代码时却要付出十倍的代价。
额外的变量声明是好的,而不是邪恶的。
现代的 JavaScript 代码压缩工具以及浏览器自身对运行代码的优化,已经很大部分的减少了性能问题。为不同的值使用不同的变量甚至可以帮助引擎优化。
总结
我们使用 var
、 let
和 const
关键字声明变量、存储数据。
let
:新式变量声明方式。var
:旧式变量声明方式。正常情况下不会使用它,我们会在《旧式变量声明方式“var”》一章中介绍它与let
的区别,帮助你辨别不得已使用它的场景。const
:类似let
,但使用它声明的变量,值是不能修改的。
还有,给变量命名的时候,应该起一个大家都能看懂的名字。
(完)
📄 文档信息
🕘 更新时间:2021/09/18
🔗 原文链接:https://javascript.info/variables