2022 年 11 月 1 日

数据类型

JavaScript 中的值始终属于某种类型。例如,字符串或数字。

JavaScript 中有八种基本数据类型。在这里,我们将对它们进行概括,并在接下来的章节中详细讨论每一种类型。

我们可以将任何类型放入变量中。例如,一个变量可以同时是一个字符串,然后存储一个数字

// no error
let message = "hello";
message = 123456;

允许此类操作的编程语言(例如 JavaScript)被称为“动态类型”,这意味着存在数据类型,但变量不受任何类型约束。

数字

let n = 123;
n = 12.345;

数字类型表示整数和小数。

数字有许多运算,例如乘法 *、除法 /、加法 +、减法 - 等。

除了常规数字,还有属于此数据类型的“特殊数字值”:Infinity-InfinityNaN

  • Infinity 表示数学中的无穷大 ∞。它是一个大于任何数字的特殊值。

    我们可以通过除以零得到它

    alert( 1 / 0 ); // Infinity

    或直接引用它

    alert( Infinity ); // Infinity
  • NaN 表示计算错误。它是错误或未定义的数学运算的结果,例如

    alert( "not a number" / 2 ); // NaN, such division is erroneous

    NaN 是粘性的。对 NaN 的任何进一步数学运算都会返回 NaN

    alert( NaN + 1 ); // NaN
    alert( 3 * NaN ); // NaN
    alert( "not a number" / 2 - 1 ); // NaN

    因此,如果某个数学表达式中某个地方有 NaN,它会传播到整个结果(只有一个例外:NaN ** 01)。

数学运算很安全

在 JavaScript 中进行数学运算“很安全”。我们可以做任何事情:除以零、将非数字字符串视为数字等。

脚本永远不会停止并出现致命错误(“死掉”)。最坏的情况是,我们得到 NaN 作为结果。

特殊数字值形式上属于“数字”类型。当然,它们不是这个词的通常意义上的数字。

我们将在数字章节中看到更多有关数字操作的内容。

BigInt

在 JavaScript 中,“数字”类型不能安全地表示大于 (253-1)(即 9007199254740991)或小于 -(253-1)(对于负数)的整数。

确切地说,“数字”类型可以存储更大的整数(高达 1.7976931348623157 * 10308),但在安全整数范围 ±(253-1) 之外会出现精度误差,因为并非所有数字都适合固定 64 位存储。因此,可能会存储“近似”值。

例如,这两个数字(正好高于安全范围)是相同的

console.log(9007199254740991 + 1); // 9007199254740992
console.log(9007199254740991 + 2); // 9007199254740992

也就是说,大于 (253-1) 的所有奇数整数都无法存储在“数字”类型中。

对于大多数目的,±(253-1) 范围已经足够,但有时我们需要真正大整数的整个范围,例如用于加密或微秒级精度时间戳。

BigInt 类型最近被添加到语言中以表示任意长度的整数。

BigInt 值是通过将 n 追加到整数末尾创建的

// the "n" at the end means it's a BigInt
const bigInt = 1234567890123456789012345678901234567890n;

由于很少需要 BigInt 数字,因此我们不会在此处介绍它们,而是为它们专门写了一章 BigInt。当您需要如此大的数字时,请阅读它。

兼容性问题

目前,BigInt 在 Firefox/Chrome/Edge/Safari 中受支持,但在 IE 中不受支持。

您可以查看 MDN BigInt 兼容性表 以了解支持哪些版本的浏览器。

字符串

JavaScript 中的字符串必须用引号引起来。

let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;

在 JavaScript 中,有 3 种类型的引号。

  1. 双引号:"Hello"
  2. 单引号:'Hello'
  3. 反引号:`Hello`

双引号和单引号是“简单”引号。在 JavaScript 中,它们之间几乎没有区别。

反引号是“扩展功能”引号。它们允许我们将变量和表达式嵌入到字符串中,方法是将它们包装在 ${…} 中,例如

let name = "John";

// embed a variable
alert( `Hello, ${name}!` ); // Hello, John!

// embed an expression
alert( `the result is ${1 + 2}` ); // the result is 3

${…} 中的表达式经过计算,结果成为字符串的一部分。我们可以将任何内容放在其中:一个变量,如 name,或一个算术表达式,如 1 + 2,或更复杂的内容。

请注意,这只能在反引号中完成。其他引号没有此嵌入功能!

alert( "the result is ${1 + 2}" ); // the result is ${1 + 2} (double quotes do nothing)

我们将在 字符串 一章中更全面地介绍字符串。

没有字符类型。

在某些语言中,有一个特殊的“字符”类型用于表示单个字符。例如,在 C 语言和 Java 中,它被称为“char”。

在 JavaScript 中,没有这样的类型。只有一种类型:string。字符串可以由零个字符(为空)、一个字符或多个字符组成。

布尔值(逻辑类型)

布尔类型只有两个值:truefalse

此类型通常用于存储是/否值:true 表示“是,正确”,而 false 表示“否,不正确”。

例如

let nameFieldChecked = true; // yes, name field is checked
let ageFieldChecked = false; // no, age field is not checked

布尔值也是比较的结果

let isGreater = 4 > 1;

alert( isGreater ); // true (the comparison result is "yes")

我们将在 逻辑运算符 一章中更深入地介绍布尔值。

“null” 值

特殊的 null 值不属于上述任何类型。

它形成自己的单独类型,其中仅包含 null

let age = null;

在 JavaScript 中,null 不是其他一些语言中的“对不存在对象的引用”或“空指针”。

它只是一个特殊值,表示“无”、“空”或“未知值”。

上面的代码指出 age 是未知的。

“undefined” 值

特殊值 undefined 也独立存在。它形成自己的类型,就像 null 一样。

undefined 的意思是“未分配值”。

如果声明了一个变量,但未分配值,则其值为 undefined

let age;

alert(age); // shows "undefined"

从技术上讲,可以显式将 undefined 分配给变量

let age = 100;

// change the value to undefined
age = undefined;

alert(age); // "undefined"

…但我们不建议这样做。通常,使用 null 为变量分配“空”或“未知”值,而 undefined 则保留为未分配事物的默认初始值。

对象和符号

object 类型是特殊的。

所有其他类型被称为“基本类型”,因为它们的值只能包含一个内容(无论是字符串、数字还是其他任何内容)。相比之下,对象用于存储数据集合和更复杂的实体。

由于非常重要,因此对象需要特殊处理。在了解了更多有关基本类型的信息后,我们将在本章 对象 中讨论它们。

symbol 类型用于创建对象的唯一标识符。为了完整性,我们必须在此处提及它,但也要等到我们了解对象后才能了解详细信息。

typeof 运算符

typeof 运算符返回操作数的类型。当我们希望以不同方式处理不同类型的值或只想进行快速检查时,它很有用。

调用 typeof x 会返回一个带有类型名称的字符串

typeof undefined // "undefined"

typeof 0 // "number"

typeof 10n // "bigint"

typeof true // "boolean"

typeof "foo" // "string"

typeof Symbol("id") // "symbol"

typeof Math // "object"  (1)

typeof null // "object"  (2)

typeof alert // "function"  (3)

最后三行可能需要额外的解释

  1. Math 是一个内置对象,提供数学运算。我们将在 数字 一章中学习它。在这里,它只是作为对象的一个示例。
  2. typeof null 的结果是 "object"。这是 typeof 中一个公认的错误,它来自 JavaScript 的早期,并且为了兼容性而保留。当然,null 不是一个对象。它是一个具有自己单独类型的值。typeof 在此处的行为是错误的。
  3. typeof alert 的结果是 "function",因为 alert 是一个函数。我们将在下一章中学习函数,在那里我们还将看到 JavaScript 中没有特殊的“函数”类型。函数属于对象类型。但 typeof 以不同的方式处理它们,返回 "function"。这也源于 JavaScript 的早期。从技术上讲,这种行为是不正确的,但在实践中很方便。
typeof(x) 语法

你可能还会遇到另一种语法:typeof(x)。它与 typeof x 相同。

说清楚一点:typeof 是一个运算符,而不是一个函数。这里的括号不是 typeof 的一部分。这是用于数学分组的括号类型。

通常,此类括号包含数学表达式,例如 (2 + 2),但这里它们只包含一个参数 (x)。在语法上,它们可以避免 typeof 运算符与其参数之间出现空格,有些人喜欢这样。

有些人喜欢 typeof(x),尽管 typeof x 语法更常见。

总结

JavaScript 中有 8 种基本数据类型。

  • 七种原始数据类型
    • number 用于任何类型的数字:整数或浮点数,整数的限制为 ±(253-1)
    • bigint 用于任意长度的整数。
    • string 用于字符串。字符串可以有零个或多个字符,没有单独的单字符类型。
    • boolean 用于 true/false
    • null 用于未知值——一个具有单个值 null 的独立类型。
    • undefined 用于未赋值的值——一个具有单个值 undefined 的独立类型。
    • symbol 用于唯一标识符。
  • 以及一种非原始数据类型
    • object 用于更复杂的数据结构。

typeof 运算符允许我们查看变量中存储的类型。

  • 通常用作 typeof x,但 typeof(x) 也是可能的。
  • 返回一个包含类型名称的字符串,如 "string"
  • 对于 null 返回 "object"——这是语言中的一个错误,它实际上不是一个对象。

在下一章中,我们将专注于原始值,一旦我们熟悉它们,我们将继续学习对象。

任务

重要性:5

脚本的输出是什么?

let name = "Ilya";

alert( `hello ${1}` ); // ?

alert( `hello ${"name"}` ); // ?

alert( `hello ${name}` ); // ?

反引号将 ${...} 中的表达式嵌入到字符串中。

let name = "Ilya";

// the expression is a number 1
alert( `hello ${1}` ); // hello 1

// the expression is a string "name"
alert( `hello ${"name"}` ); // hello name

// the expression is a variable, embed it
alert( `hello ${name}` ); // hello Ilya
教程地图

评论

在评论前阅读此内容…
  • 如果您有改进建议 - 请 提交 GitHub 问题 或提交拉取请求,而不是发表评论。
  • 如果您无法理解文章中的内容,请详细说明。
  • 要插入几行代码,请使用 <code> 标签,对于多行代码,请将其包装在 <pre> 标签中,对于 10 行以上的代码,请使用沙盒 (plnkrjsbincodepen…)