JavaScript 基础知识| 数据类型|类型转换
数据类型
JavaScript 中的值都具有特定的类型。例如,字符串或数字。
在 JavaScript 中有 8 种基本的数据类型(译注:7 种原始类型和 1 种引用类型)。在这里,我们将对它们进行大体的介绍,在下一章中,我们将详细讨论它们。
我们可以将任何类型的值存入变量。例如,一个变量可以在前一刻是个字符串,下一刻就存储一个数字:
// 没有错误
let message = "hello";
message = 123456;
允许这种操作的编程语言,例如 JavaScript,被称为“动态类型”(dynamically typed)的编程语言,意思是虽然编程语言中有不同的数据类型,但是你定义的变量并不会在定义后,被限制为某一数据类型。
Number 类型
let n = 123;
n = 12.345;
number 类型代表整数和浮点数。
数字可以有很多操作,比如,乘法 *
、除法 /
、加法 +
、减法 -
等等。
除了常规的数字,还包括所谓的“特殊数值(“special numeric values”)”也属于这种类型:Infinity
、-Infinity
和 NaN
。
-
Infinity
代表数学概念中的 无穷大 ∞。是一个比任何数字都大的特殊值。我们可以通过除以 0 来得到它:
alert( 1 / 0 ); // Infinity
或者在代码中直接使用它:
alert( Infinity ); // Infinity
-
NaN
代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果,比如:alert( "not a number" / 2 ); // NaN,这样的除法是错误的
NaN
是粘性的。任何对NaN
的进一步数学运算都会返回NaN
:alert( NaN + 1 ); // NaN alert( 3 * NaN ); // NaN alert( "not a number" / 2 - 1 ); // NaN
所以,如果在数学表达式中有一个
NaN
,会被传播到最终结果(只有一个例外:NaN ** 0
结果为1
)。
ℹ️数学运算是安全的
在 JavaScript 中做数学运算是安全的。我们可以做任何事:除以 0,将非数字字符串视为数字,等等。
脚本永远不会因为一个致命的错误(“死亡”)而停止。最坏的情况下,我们会得到
NaN
的结果。特殊的数值属于 “number” 类型。当然,对“特殊的数值”这个词的一般认识是,它们并不是数字。
我们将在 【数字类型】一节中学习数字的更多细节。
BigInt 类型
在 JavaScript 中,“number” 类型无法表示大于 (253-1)
(即 9007199254740991
),或小于 -(253-1)
的整数。这是其内部表示形式导致的技术限制。
在大多数情况下,这个范围就足够了,但有时我们需要很大的数字,例如用于加密或微秒精度的时间戳。
BigInt
类型是最近被添加到 JavaScript 语言中的,用于表示任意长度的整数。
可以通过将 n
附加到整数字段的末尾来创建 BigInt
值。
// 尾部的 "n" 表示这是一个 BigInt 类型
const bigInt = 1234567890123456789012345678901234567890n;
由于很少需要 BigInt
类型的数字,我们在这没有对其进行讲解,我们在单独的章节 BigInt 中专门对其进行了介绍。当你需要使用那样的大数字的时候,可以去阅读该章节。
ℹ️兼容性问题
目前 Firefox/Chrome/Edge/Safari 已经支持
BigInt
了,但 IE 还没有。你可以查看 MDN BigInt 兼容性表 以了解哪些版本的浏览器已经支持 BigInt 了。
String 类型
JavaScript 中的字符串必须被括在引号里。
let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;
在 JavaScript 中,有三种包含字符串的方式。
- 双引号:
"Hello"
. - 单引号:
'Hello'
. - 反引号:
Hello
.
双引号和单引号都是“简单”引用,在 JavaScript 中两者几乎没有什么差别。
反引号是 功能扩展 引号。它们允许我们通过将变量和表达式包装在 ${…}
中,来将它们嵌入到字符串中。例如:
let name = "John";
// 嵌入一个变量
alert( `Hello, ${name}!` ); // Hello, John!
// 嵌入一个表达式
alert( `the result is ${1 + 2}` ); // the result is 3
${…}
内的表达式会被计算,计算结果会成为字符串的一部分。可以在 ${…}
内放置任何东西:诸如名为 name
的变量,或者诸如 1 + 2
的算数表达式,或者其他一些更复杂的。
需要注意的是,这仅仅在反引号内有效,其他引号不允许这种嵌入。
alert( "the result is ${1 + 2}" ); // the result is ${1 + 2}(使用双引号则不会计算 ${…} 中的内容)
我们会在 【字符串】 一节中学习字符串的更多细节。
ℹ️JavaScript 中没有 *character* 类型。
在一些语言中,单个字符有一个特殊的 “character” 类型,在 C 语言和 Java 语言中被称为 “char”。
在 JavaScript 中没有这种类型。只有一种
string
类型,一个字符串可以包含零个(为空)、一个或多个字符。
Boolean 类型(逻辑类型)
boolean 类型仅包含两个值:true
和 false
。
这种类型通常用于存储表示 yes 或 no 的值:true
意味着 “yes,正确”,false
意味着 “no,不正确”。
比如:
let nameFieldChecked = true; // yes, name field is checked
let ageFieldChecked = false; // no, age field is not checked
布尔值也可作为比较的结果:
let isGreater = 4 > 1;
alert( isGreater ); // true(比较的结果是 "yes")
更详细的内容将会在 【逻辑运算符】 一节中介绍。
null 值
特殊的 null
值不属于上述任何一种类型。
它构成了一个独立的类型,只包含 null
值:
let age = null;
相比较于其他编程语言,JavaScript 中的 null
不是一个“对不存在的 object
的引用”或者 “null 指针”。
JavaScript 中的 null
仅仅是一个代表“无”、“空”或“值未知”的特殊值。
上面的代码表示 age
是未知的。
undefined 值
特殊值 undefined
和 null
一样自成类型。
undefined
的含义是 未被赋值
。
如果一个变量已被声明,但未被赋值,那么它的值就是 undefined
:
let age;
alert(age); // 弹出 "undefined"
从技术上讲,可以显式地将 undefined
赋值给变量:
let age = 100;
// 将值修改为 undefined
age = undefined;
alert(age); // "undefined"
……但是不建议这样做。通常,使用 null
将一个“空”或者“未知”的值写入变量中,而 undefined
则保留作为未进行初始化的事物的默认初始值。
Object 类型和 Symbol 类型
object
类型是一个特殊的类型。
其他所有的数据类型都被称为“原始类型”,因为它们的值只包含一个单独的内容(字符串、数字或者其他)。相反,object
则用于储存数据集合和更复杂的实体。
因为它非常重要,所以我们对其进行单独讲解。在充分学习了原始类型后,我们将会在 【对象】一章中介绍 object
。
symbol
类型用于创建对象的唯一标识符。我们在这里提到 symbol
类型是为了完整性,但我们要在学完 object
类型后再学习它。
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)
最后三行可能需要额外的说明:
Math
是一个提供数学运算的内建object
。我们会在 【数字类型】 一节中学习它。此处仅作为一个object
的示例。typeof null
的结果为"object"
。这是官方承认的typeof
的错误,这个问题来自于 JavaScript 语言的早期阶段,并为了兼容性而保留了下来。null
绝对不是一个object
。null
有自己的类型,它是一个特殊值。typeof
的行为在这里是错误的。typeof alert
的结果是"function"
,因为alert
在 JavaScript 语言中是一个函数。我们会在下一章学习函数,那时我们会了解到,在 JavaScript 语言中没有一个特别的 “function” 类型。函数隶属于object
类型。但是typeof
会对函数区分对待,并返回"function"
。这也是来自于 JavaScript 语言早期的问题。从技术上讲,这种行为是不正确的,但在实际编程中却非常方便。
ℹ️**
typeof(x)
语法**你可能还会遇到另一种语法:
typeof(x)
。它与typeof x
相同。简单点说:
typeof
是一个操作符,不是一个函数。这里的括号不是typeof
的一部分。它是数学运算分组的括号。通常,这样的括号里包含的是一个数学表达式,例如
(2 + 2)
,但这里它只包含一个参数(x)
。从语法上讲,它们允许在typeof
运算符和其参数之间不打空格,有些人喜欢这样的风格。有些人更喜欢用
typeof(x)
,尽管typeof x
语法更为常见。
总结
JavaScript 中有八种基本的数据类型(译注:前七种为基本数据类型,也称为原始类型,而 object
为复杂数据类型)。
number
用于任何类型的数字:整数或浮点数,在±(253-1)
范围内的整数。bigint
用于任意长度的整数。string
用于字符串:一个字符串可以包含 0 个或多个字符,所以没有单独的单字符类型。boolean
用于true
和false
。null
用于未知的值 —— 只有一个null
值的独立类型。undefined
用于未定义的值 —— 只有一个undefined
值的独立类型。symbol
用于唯一的标识符。object
用于更复杂的数据结构。
我们可以通过 typeof
运算符查看存储在变量中的数据类型。
- 通常用作
typeof x
,但typeof(x)
也可行。 - 以字符串的形式返回类型名称,例如
"string"
。 typeof null
会返回"object"
—— 这是 JavaScript 编程语言的一个错误,实际上它并不是一个object
。
在接下来的章节中,我们将重点介绍原始类型值,当你掌握了原始数据类型后,我们将继续学习 object
。
✅任务
字符串的引号
重要程度: 5
下面的脚本会输出什么?
let name = "Ilya";
alert( `hello ${1}` ); // ?
alert( `hello ${"name"}` ); // ?
alert( `hello ${name}` ); // ?
解决方案
反引号将包装在 ${...}
中的表达式嵌入到了字符串。
let name = "Ilya";
// 表达式为数字 1
alert( `hello ${1}` ); // hello 1
// 表达式是一个字符串 "name"
alert( `hello ${"name"}` ); // hello name
// 表达式是一个变量,嵌入进去了。
alert( `hello ${name}` ); // hello Ilya
交互:alert、prompt 和 confirm
由于我们将使用浏览器作为我们的演示环境,让我们看几个与用户交互的函数:alert
,prompt
和confirm
。
alert
这个我们前面已经看到过了。它会显示一条信息,并等待用户按下 “OK”。
例如:
alert("Hello");
弹出的这个带有信息的小窗口被称为 模态窗。“modal” 意味着用户不能与页面的其他部分(例如点击其他按钮等)进行交互,直到他们处理完窗口。在上面示例这种情况下 —— 直到用户点击“确定”按钮。
prompt
prompt
函数接收两个参数:
result = prompt(title, [default]);
浏览器会显示一个带有文本消息的模态窗口,还有 input 框和确定/取消按钮。
-
title
显示给用户的文本
-
default
可选的第二个参数,指定 input 框的初始值。
ℹ️语法中的方括号
[...]
上述语法中
default
周围的方括号表示该参数是可选的,不是必需的。
访问者可以在提示输入栏中输入一些内容,然后按“确定”键。然后我们在 result
中获取该文本。或者他们可以按取消键或按 Esc 键取消输入,然后我们得到 null
作为 result
。
prompt
将返回用户在 input
框内输入的文本,如果用户取消了输入,则返回 null
。
举个例子:
let age = prompt('How old are you?', 100);
alert(`You are ${age} years old!`); // You are 100 years old!
⚠️IE 浏览器会提供默认值
第二个参数是可选的。但是如果我们不提供的话,Internet Explorer 会把 "undefined"
插入到 prompt。
我们可以在 Internet Explorer 中运行下面这行代码来看看效果:
let test = prompt("Test");
所以,为了 prompt 在 IE 中有好的效果,我们建议始终提供第二个参数:
let test = prompt("Test", ''); // <-- 用于 IE 浏览器
confirm
语法:
result = confirm(question);
confirm
函数显示一个带有 question
以及确定和取消两个按钮的模态窗口。
点击确定返回 true
,点击取消返回 false
。
例如:
let isBoss = confirm("Are you the boss?");
alert( isBoss ); // 如果“确定”按钮被按下,则显示 true
总结
我们学习了与用户交互的 3 个浏览器的特定函数:
-
alert
显示信息。
-
prompt
显示信息要求用户输入文本。点击确定返回文本,点击取消或按下 Esc 键返回
null
。 -
confirm
显示信息等待用户点击确定或取消。点击确定返回
true
,点击取消或按下 Esc 键返回false
。
这些方法都是模态的:它们暂停脚本的执行,并且不允许用户与该页面的其余部分进行交互,直到窗口被解除。
上述所有方法共有两个限制:
- 模态窗口的确切位置由浏览器决定。通常在页面中心。
- 窗口的确切外观也取决于浏览器。我们不能修改它。
这就是简单的代价。还有其他一些方式可以显示更漂亮的窗口,并与用户进行更丰富的交互,但如果“花里胡哨”不是非常重要,那使用本节讲的这些方法也挺好。
✅任务
创建一个简单的页面
重要程度: 4
创建一个要求用户输入 name
,并通过浏览器窗口对键入的内容进行输出的 web 页面。
解决方案
JavaScript 代码:
let name = prompt("What is your name?", "");
alert(name);
整个页面的代码:
<!DOCTYPE html>
<html>
<body>
<script>
'use strict';
let name = prompt("What is your name?", "");
alert(name);
</script>
</body>
</html>
类型转换
大多数情况下,运算符和函数会自动将赋予它们的值转换为正确的类型。
比如,alert
会自动将任何值都转换为字符串以进行显示。算术运算符会将值转换为数字。
在某些情况下,我们需要将值显式地转换为我们期望的类型。
ℹ️对象还未纳入讨论中
在本章中,我们不会讨论 object 类型。目前,我们将只学习原始类型。
之后,在我们学习完 object 类型后,我们会在 【对象 — 原始值转换】一章中学习对象 — 原始值转换。
字符串转换
当我们需要一个字符串形式的值时,就会进行字符串转换。
比如,alert(value)
将 value
转换为字符串类型,然后显示这个值。
我们也可以显式地调用 String(value)
来将 value
转换为字符串类型:
let value = true;
alert(typeof value); // boolean
value = String(value); // 现在,值是一个字符串形式的 "true"
alert(typeof value); // string
字符串转换最明显。false
变成 "false"
,null
变成 "null"
等。
数字型转换
在算术函数和表达式中,会自动进行 number 类型转换。
比如,当把除法 /
用于非 number 类型:
alert( "6" / "2" ); // 3, string 类型的值被自动转换成 number 类型后进行计算
我们也可以使用 Number(value)
显式地将这个 value
转换为 number 类型。
let str = "123";
alert(typeof str); // string
let num = Number(str); // 变成 number 类型 123
alert(typeof num); // number
当我们从 string 类型源(如文本表单)中读取一个值,但期望输入一个数字时,通常需要进行显式转换。
如果该字符串不是一个有效的数字,转换的结果会是 NaN
。例如:
let age = Number("an arbitrary string instead of a number");
alert(age); // NaN,转换失败
number 类型转换规则:
值 | 变成…… |
---|---|
undefined |
NaN |
null |
0 |
true 和 false |
1 and 0 |
string |
去掉首尾空格后的纯数字字符串中含有的数字。如果剩余字符串为空,则转换结果为 0 。否则,将会从剩余字符串中“读取”数字。当类型转换出现 error 时返回 NaN 。 |
例子:
alert( Number(" 123 ") ); // 123
alert( Number("123z") ); // NaN(从字符串“读取”数字,读到 "z" 时出现错误)
alert( Number(true) ); // 1
alert( Number(false) ); // 0
请注意 null
和 undefined
在这有点不同:null
变成数字 0
,undefined
变成 NaN
。
大多数数学运算符也执行这种转换,我们将在下一节中进行介绍。
布尔型转换
布尔(boolean)类型转换是最简单的一个。
它发生在逻辑运算中(稍后我们将进行条件判断和其他类似的东西),但是也可以通过调用 Boolean(value) 显式地进行转换。
转换规则如下:
- 直观上为“空”的值(如
0
、空字符串、null
、undefined
和NaN
)将变为false
。 - 其他值变成
true
。
比如:
alert( Boolean(1) ); // true
alert( Boolean(0) ); // false
alert( Boolean("hello") ); // true
alert( Boolean("") ); // false
⚠️请注意:包含 0 的字符串 "0"
是 true
一些编程语言(比如 PHP)视 "0"
为 false
。但在 JavaScript 中,非空的字符串总是 true
。
alert( Boolean("0") ); // true
alert( Boolean(" ") ); // 空白,也是 true(任何非空字符串都是 true)
总结
有三种常用的类型转换:转换为 string 类型、转换为 number 类型和转换为 boolean 类型。
字符串转换 —— 转换发生在输出内容的时候,也可以通过 String(value)
进行显式转换。原始类型值的 string 类型转换通常是很明显的。
数字型转换 —— 转换发生在进行算术操作时,也可以通过 Number(value)
进行显式转换。
数字型转换遵循以下规则:
值 | 变成…… |
---|---|
undefined |
NaN |
null |
0 |
true / false |
1 / 0 |
string |
“按原样读取”字符串,两端的空白会被忽略。空字符串变成 0 。转换出错则输出 NaN 。 |
布尔型转换 —— 转换发生在进行逻辑操作时,也可以通过 Boolean(value)
进行显式转换。
布尔型转换遵循以下规则:
值 | 变成…… |
---|---|
0 , null , undefined , NaN , "" |
false |
其他值 | true |
上述的大多数规则都容易理解和记忆。人们通常会犯错误的值得注意的例子有以下几个:
- 对
undefined
进行数字型转换时,输出结果为NaN
,而非0
。 - 对
"0"
和只有空格的字符串(比如:" "
)进行布尔型转换时,输出结果为true
。
我们在本小节没有讲 object 类型的转换。在我们学习完更多关于 JavaScript 的基础知识后,我们会在专门介绍 object 的章节 【对象 — 原始值转换】中详细讲解 object 类型转换。
- 点赞
- 收藏
- 关注作者
评论(0)