本文已参与「新人创作礼」活动,一起开启掘金创作之路
动态类型
JavaScript 是一种弱类型或者说动态语言。这意味着你不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。这也意味着你可以使用同一个变量保存不同类型的数据:
let foo = 42; // foo 现在是一个数字
foo = 'bar'; // foo 现在是一个字符串
foo = true; // foo 现在是一个布尔值
JavaScript 类型
JS的数据类型由 primitive values 和 objects 组成。
-
Primitive values (直接表示在语言底层的不可变数据)
-
Objects (属性的集合) primitive values是指不能改变的值,例如:字符串都是不能改变的。具体如下:
Boolean type
布尔表示一个逻辑实体,可以有两个值:true 和 false。更多详情可查看 Boolean 和 Boolean。
Null 类型
Null 类型只有一个值:null,更多详情可查看 null 和 Null。
Undefined 类型
一个没有被赋值的变量会有个默认值 undefined,更多详情可查看 undefined 和 Undefined。
Numeric types
ECMAScript有两个内置的数字类型。Number 和 BigInt - 以及相关的值 NaN.
Number type
数字类型是一种基于 IEEE 754 标准的双精度 64 位二进制格式的值(从 -(2^53 -1) 到 2^53 - 1 之间的数字)。除了能够表示浮点数外,还有三个带符号的值:+Infinity、-Infinity 和 NaN(非数值,Not-a-Number)。
要检查值是否大于或小于 ±Infinity,你可以使用常量 Number.MAX_VALUE 和 Number.MIN_VALUE。
备注: 从 ECMAScript 2015 开始,除了
Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER,你还可以通过Number.isSafeInteger()来检查值是否在双精度浮点数的取值范围内。超出这个范围,JavaScript 中的整数将不再安全,该值将表示为与该值近似的双精度浮点数。
数字类型中只有一个整数有两种表示方法:0 可表示为 -0 和 +0(0 是 +0 的简写)。
在实践中,这几乎没有任何影响。例如,+0 === -0 为真。但是,你需要注意除以零的情况:
> 42 / +0
Infinity
> 42 / -0
-Infinity
尽管一个数字通常仅代表它本身的值,但 JavaScript 提供了一些位运算符。
备注: 虽然位运算符可通过 掩码 同时表示多个布尔类型的值,但这通常被认为是不好的。JavaScript 提供了其他的方式来表示一组布尔值(如一个布尔值数组或一个布尔值分配给命名属性的对象)。掩码也容易使代码变得难以阅读、理解和维护。
在一些非常受限的情况下,可能需要用到这些技术,比如试图应对本地存储的存储限制,或在一些极端场景下(例如,网络传输的每一比特都尤为重要时)。位操作只应该是用来优化字节数的最后选择。
NaN("Not a Number")通常是在算术运算的结果不能表示为一个数字时遇到的。它也是JavaScript中唯一不等于自身的值。
BigInt 类型
BigInt 类型是 JavaScript 中的一个基础的数值类型,可以表示任意精度的整数。使用 BigInt,您可以安全地存储和操作大整数,甚至可以超过数字类型的安全整数限制。
BigInt 是通过在整数末尾附加字母 n 或调用构造函数来创建的。
通过使用常量 Number.MAX_SAFE_INTEGER,您可以获得可以用数字递增的最安全的值。通过引入 BigInt,您可以操作超过 Number.MAX_SAFE_INTEGER 的数字。
以下示例演示了,递增超过 Number.MAX_SAFE_INTEGER 的值可以返回预期的结果:
// BigInt
> const x = BigInt(Number.MAX_SAFE_INTEGER);
9007199254740991n
> x + 1n === x + 2n; // 9007199254740992n === 9007199254740993n
false
// Number
> Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; // 9007199254740992 === 9007199254740992
true
可以对 BigInt 使用运算符 +、*、-、** 和 %,就像对数字一样。BigInt 严格来说并不等同于一个数字,但它也同样可以轻松地使用。
在将 BigInt 转换为 Boolean 时(例如:if、||、&&、Boolean 和 !),它的行为类似于一个数字。
BigInt 不能与数字相互运算。否则,将抛出 TypeError。
String 类型
JavaScript 的字符串类型用于表示文本数据。它是一组 16 位的无符号整数值的“元素”。在字符串中的每个元素占据了字符串的位置。第一个元素的索引为 0,下一个是索引 1,依此类推。字符串的长度是它的元素的数量。
不同于一些编程语言(例如,C 语言),JavaScript 的字符串是不可更改的。这意味着字符串一旦被创建,就不能被修改。
但是,可以基于对原始字符串的操作来创建新的字符串。例如:
- 获取一个字符串的子串可通过选择个别字母或者使用
String.substring()。 - 两个字符串的连接使用连接运算符(
+)或者String.concat()。
注意代码中的“字符串类型”!
可以使用字符串来表达复杂的数据。以下是一些很好的性质:
- 容易通过字符串拼接来构造复杂的字串符
- 字符串容易被调试(你看到的往往在字符串里)
- 字符串通常是许多 APIs 的常见标准(input fields、local storage 中的值,以及
XMLHttpRequest使用responseText等作为响应)而且这些 APIs 可能只能与字符串一同使用。
使用约定,字符串一般可以用来表示任何数据结构。但这并不总是一个好主意。例如,使用一个分隔符,可以模拟一个列表(而 JavaScript 数组可能更适合)。不幸的是,当分隔符用于列表中的元素时,列表就会被破坏。这时可以选择转义字符,等等。所有这些都需要约定,并造成不必要的维护负担。
表示文本数据时候推荐使用字符串。当需要表示复杂的数据时,使用字符串解析并使用适当的抽象。
Symbol 类型
符号(Symbols)类型是唯一且不可修改的原始值,并且可以用来作为对象的键 (key)(如下),在某些语言当中也有与之相似的类型(原子类型,atoms)。
更多详情可查看 Symbol 和 Symbol。
在计算机科学中,对象(object)是指内存中的可以被标识符引用的一块区域。
对象
在计算机科学中,对象(object)是指内存中的可以被标识符引用的一块区域。
属性
在 JavaScript 中,对象可以被看作是一组属性的集合。用对象字面量语法来定义一个对象时,会自动初始化一组属性。而后,这些属性还可以被添加和移除。属性的值可以是任意类型,包括其它对象。属性使用键(key)来标识,它的键值可以是一个字符串或者符号值(Symbol)。
备注: 每个属性(property)都由对应的特性(attributes)。JavaScript 引擎在内部使用了特性(attributes),因此你不能直接访问它们。这就是为什么特性(attributes)被放在两对方括号内,而不是单独列出的原因。
数据属性
数据属性是键值对,并且每个数据属性拥有下列特性:
| 特性 | 数据类型 | 描述 | 默认值 |
|---|---|---|---|
| [[Value]] | 任何 Javascript 类型 | 包含这个属性的数据值。 | undefined |
| [[Writable]] | Boolean | 如果该值为 false,则该属性的 [[Value]] 特性不能被修改。 | false |
| [[Enumerable]] | Boolean | 如果该值为 true,则该属性可以用 for...in 循环来枚举。 参见 属性的可枚举性和所有权。 | false |
| [[Configurable]] | Boolean | 如果该值为 false,则该属性不能被删除(对于访问器属性则不能被修改),并且除了 [[Value]] 和 [[Writable]] 以外的特性都不能被修改。 | false |
| 特性 | 类型 | 描述 |
|---|---|---|
| Read-only | Boolean | ES5 [[Writable]] 属性的反状态 (Reversed state)。 |
| DontEnum | Boolean | ES5 [[Enumerable]] 属性的反状态。 |
| DontDelete | Boolean | ES5 [[Configurable]] 属性的反状态。 |
访问器属性
访问器属性有一个或两个访问器函数(get 和 set)来存取数值。
备注: 注意它是访问器属性,而非访问器方法。我们可以将函数作为值赋给 JavaScript 对象的访问器(使得对象表现得像一个类)——但这不会使对象变成类。
访问器属性具有以下特性(attributes):
| 特性 | 类型 | 描述 | 默认值 |
|---|---|---|---|
| [[Get]] | 函数对象或者 undefined | 该函数使用一个空的参数列表,用于在有权访问的情况下读取属性值。参见 get。 | undefined |
| [[Set]] | 函数对象或者 undefined | 该函数有一个参数,用于在有权访问的情况下写入属性值。参见 set。 | undefined |
| [[Enumerable]] | Boolean | 如果该值为 true,则该属性可以用 for...in 循环来枚举。 | false |
| [[Configurable]] | Boolean | 如果该值为 false,则该属性不能被删除,且不能被转变成数据属性 | false |
“标准的”对象和函数
一个 JavaScript 对象就是键和值之间的映射。键是一个字符串(或者 Symbol),值可以是任意类型的。这使得对象非常符合哈希表。
函数是一个附带可被调用功能的常规对象。
日期
当你想要显示日期时,毋庸置疑,使用 JavaScript 内建的 Date 对象。
有序集:数组和类型数组
数组是一种使用整数作为键(integer-keyed)属性并与长度(length)属性关联的常规对象。
此外,数组对象还继承了 Array.prototype 的一些操作数组的便捷方法。例如,indexOf()(搜索数组中的一个值)或 push()(向数组中添加一个元素),等等。这使得数组是表示列表或集合的最优选择。
此外还有ES6新增的一些对象,比如map, set等。