如果你问一个手机店的店员一种特定手机的价格,而他们说“九十九块九毛九”(即,$99.99),他们给了你一个实际的美元数字来表示你需要花多少钱才能买到它。如果你想两部这种手机,你可以很容易地心算这个值的两倍来得到你需要花费的$199.98。

如果同一个店员拿起另一部相似的手机说它是“免费的”(也许在用手比划引号),那么他们就不是在给你一个数字,而是你的花费($0.00)的另一种表达形式 —— “免费”这个词。

当你稍后问到这个手机是否带充电器时,回答可能仅仅是“是”或者“不”。

以同样的方式,当你在程序中表达一个值时,你根据你打算对这些值做什么来选择不同的表达形式。

在编程术语中值的这些不同的表达形式称为 类型。JavaScript中对这些所谓的 基本类型 值都有内建的类型:

  • 但你需要做数学计算时,你需要一个number
  • 当你需要在屏幕上打印一个值时,你需要一个string(一个或多个字符,单词,句子)。
  • 当你需要在你的程序中做决定时,你需要一个booleantruefalse)。

在源代码中直接包含的值称为 字面量string字面量被双引号"..."或单引号('...')包围 —— 唯一的区别是风格上的偏好。numberboolean字面量用它们本身来表示(即,42true,等等)。

考虑如下代码:

  1. "I am a string";
  2. 'I am also a string';
  3. 42;
  4. true;
  5. false;

string/number/boolean值的类型以外,编程语言通常会提供 数组对象函数 等更多的类型。我们会在本章和下一章中讲解更多关于值和类型的内容。

类型间转换

如果你有一个number但需要将它打印在屏幕上,那么你就需要将这个值转换为一个string,在JavaScript中这种转换称为“强制转换”。类似地,如果某些人在一个电商网页的form中输入一系列数字,那么它是一个string,但是如果你需要使用这个值去做数学运算,那么你就需要将它 强制转换 为一个number

为了在 类型 之间强制转换,JavaScript提供了几种不同的工具。例如:

  1. var a = "42";
  2. var b = Number( a );
  3. console.log( a ); // "42"
  4. console.log( b ); // 42

使用上面展示的Number(..)(一个内建函数)是一种从任意其他类型到number类型的 明确的 强制转换。这应当是相当直白的。

但是一个具有争议的话题是,当你试着比较两个还不是相同类型的值时发生的事情,它需要 隐含的 强制转换。

当比较字符串"99.99"和数字99.99时,大多数人同意它们是等价的。但是他们不完全相同,不是吗?它们是相同的值的两种不同表现形式,两个不同的 类型。你可以说它们是“宽松地等价”的,不是吗?

为了在这些常见情况下帮助你,JavaScript有时会启动 隐含的 强制转换来把值转换为匹配的类型。

所以如果你使用==宽松等价操作符来进行"99.99" == 99.99比较,JavaScript会将左手边的"99.99"转换为它的number等价物99.99。所以比较就变成了99.99 == 99.99,这当然是成立的。

虽然隐含强制转换是为了帮助你而设计,但是它也可能把你搞糊涂,如果你没有花时间去学习控制它行为的规则。大多数开发者从没有这么做,所以常见的感觉是隐含的强制转换是令人困惑的,并且会产生意外的bug危害程序,因此应当避免使用。有时它甚至被称为这种语言中的设计缺陷。

然而,隐含强制转换是一种 可以被学习 的机制,而且是一种 应当 被所有想要认真对待JavaScript编程的人学习的机制。一旦你学习了这些规则,它不仅是消除了困惑,而且它实际上是你的程序变得更好!这种努力是值得的。

注意: 关于强制转换的更多信息,参见本书第二章和本系列 类型与文法 的第四章。