大多数有用的程序都需要在程序运行整个过程中,追踪由于你的程序所意图的任务被调用的底层不同的操作而发生的值的变化。
要这样做的最简单的方法是将一个值赋予一个符号容器,称为一个 变量 —— 因为在这个容器中的值可以根据需要不时 变化 而得名。
在某些编程语言中,你可以声明一个变量(容器)来持有特定类型的值,比如number
或string
。因为防止了意外的类型转换,静态类型,也被称为 类型强制,通常被认为是对程序正确性有好处的。
另一些语言在值上强调类型而非在变量上。弱类型,也被称为 动态类型,允许变量在任意时刻持有任意类型的值。因为它允许一个变量在程序逻辑流程中代表一个值,而不论这个值在任意给定的时刻是什么类型,所以它被认为是对程序灵活性有好处的。
JavaScript使用的是后者,动态类型,这意味着变量可以持有任意 类型 的值而没有任何 类型 强制约束。
正如我们刚才提到的,我们使用var
语句来声明一个变量 —— 注意在这种声明中没有其他的 类型 信息。考虑这段简单的代码:
var amount = 99.99;
amount = amount * 2;
console.log( amount ); // 199.98
// 将 `amount` 转换为一个字符串,
// 并在开头加一个 "$"
amount = "$" + String( amount );
console.log( amount ); // "$199.98"
变量amount
开始时持有数字99.99
,然后持有amount * 2
的number
结果,也就是199.98
。
第一个console.log(..)
命令不得不 隐含地 将这个number
值强制转换为一个string
才能够打印出来。
然后语句amount = "$" + String(amount)
明确地 将值199.98
强制转换为一个string
并且在开头加入一个"$"
字符。这时,amount
现在就持有这个string
值$199.98
,所以第二个console.log(..)
语句无需强制转换就可以把它打印出来。
JavaScript开发者将会注意到为值99.99
,199.98
,和"$199.98"
都使用变量amount
的灵活性。静态类型的拥护者们将偏好于使用一个分离的变量,比如amountStr
来持有这个值最后的"$199.98"
表达形式,因为它是一个不同的类型。
不管哪种方式,你将会注意到amount
持有一个在程序运行过程中不断变化的值,这展示了变量的主要目地:管理程序 状态。
换句话说,在你程序运行的过程中 状态 追踪着值的改变。
变量的另一种常见用法是将值的设定集中化。当你为一个在程序中通篇不打算改变的值声明了一个变量时,它更一般地被称为 常量。
你经常会在程序的顶部声明这些 常量,这样提供了一种方便:如果你需要改变一个值时你可以到唯一的地方去寻找。根据惯例,用做常量的JavaScript变量通常是大写的,在多个单词之间使用下划线_
连接。
这里是一个呆萌的例子:
var TAX_RATE = 0.08; // 8% sales tax
var amount = 99.99;
amount = amount * 2;
amount = amount + (amount * TAX_RATE);
console.log( amount ); // 215.9784
console.log( amount.toFixed( 2 ) ); // "215.98"
注意: console.log(..)
是一个函数log(..)
作为一个在值console
上的对象属性被访问,与此类似,这里的toFixed(..)
是一个可以在值number
上被访问的函数。JavaScript number
不会被自动地格式化为美元 —— 引擎不知道你的意图,而且也没有通货类型。toFixed(..)
让我们指明四舍五入到小数点后多少位,而且它如我们需要的那样产生一个string
。
变量TAX_RATE
只是因为惯例才是一个 常量 —— 在这个程序中没有什么特殊的东西可以防止它被改变。但是如果这座城市将它的消费税增至9%,我们仍然可以很容地通过在一个地方将TAX_RATE
被赋予的值改为0.09
来更新我们的程序,而不是在程序通篇中寻找许多值0.08
出现的地方然后更新它们全部。
在写作本书时,最新版本的JavaScript(通常称为“ES6”)引入了一个声明常量的新方法,用const
代替var
:
// 在ES6中:
const TAX_RATE = 0.08;
var amount = 99.99;
// ..
常量就像带有不变的值的变量一样有用,常量还防止在初始设置之后的某些地方意外地改变它的值。如果你试着在第一个声明之后给TAX_RATE
赋予一个不同的值,你的程序将会拒绝这个改变(而且在Strict模式下,会产生一个错误 —— 见第二章的“Strict模式”)。
顺带一提,这种防止编程错误的“保护”与静态类型的类型强制很类似,所以你可以看到为什么在其他语言中的静态类型很吸引人。
注意: 更多关于如何在你程序的变量中使用不同的值,参见本系列的 类型与文法。