JavaScript 中的 7 种数据类型详解

看了很多关于 JavaScript 基本数据类型和引用数据类型的说明,真的是众说纷纭,有的其中还存在一些错误的描述,感觉不容易理清楚,因此想对其做一个总结。

JavaScript 是一种弱类型或者说动态语言。这意味着你不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。这也意味着你可以使用同一个变量保存不同类型的数据。

数据类型

最新的 ECMAScript 标准定义了 7 种数据类型:

  • 6 种原始类型(或者叫做基本类型):
    • Boolean
    • Null
    • Undefined
    • Number
    • String
    • Symbol (ES 6 新增)
  • 1 种引用类型:
    • Object

基本数据类型

Object 之外的所有类型,它们的值都是不可变的。例如:JavaScript 中对字符串的操作,是返回了一个新的字符串,而原字符串并没有被改变。

这些类型的值,被称为“原始值”。

Boolean 类型

在计算机科学中,布尔值是一种取值仅能为 真 或 假 的数据类型,它赋予了编程语言在逻辑上表达真 或 假 的能力。

布尔表示一个逻辑实体,可以有两个值:truefalse

Null 类型

Null 类型只有一个值: null

null 特指对象的值未设置。

null 是一个字面量。 null 是表示缺少的标识,指示变量未指向任何对象。把 null 作为尚未创建的对象,也许更好理解。在 APIs 中, null 常在返回类型是对象,但没关联值的地方使用。

1
2
3
4
5
6
7
8
// foo不存在,它从来没有被定义过或者是初始化过:
foo;
"ReferenceError: foo is not defined"

// foo现在已经是知存在的,但是它没有类型或者是值:
var foo = null;
foo;
null

Undefined 类型

一个没有被赋值的变量会有个默认值 undefined。全局属性 undefined 表示原始值 undefined

undefined 是全局对象的一个属性。也就是说,它是全局作用域的一个变量。undefined 的最初值就是原始数据类型 undefined

自 ECMAscript5 标准以来 undefined 是一个不能被配置(non-configurable),不能被重写(non-writable)的属性。即便事实并非如此,也要避免去重写它。

一个没有被赋值的变量的类型是 undefined。

一个函数如果没有使用 return 语句指定返回值,就会返回一个 undefined 值。

严格相等操作符

可以使用严格相等操作符 === 来判断一个变量是否拥有值。

1
2
3
4
5
6
7
var x;

if (x === undefined) {
// 执行这些语句
} else {
// 这些语句不会被执行
}

注意: 不能用标准相等操作符 == 来判断,因为当值为 null 时, null == undefined 的结果为 true。但是 null 不同于 undefined

typeof 操作符

也可以使用 typeof 操作符,对变量进行判断。

1
2
3
4
var x;
if(typeof x === 'undefined') {
// 执行这些语句
}

使用 typeof 可以避免在变量没有声明时抛出错误。

1
2
3
4
5
6
7
8
// 这里没有声明y
if(typeof y === 'undefined') { // 没有错误,执行结果为true
console.log("y is " + typeof y ) // y is undefined
}

if(y === undefined) { // ReferenceError: y is not defined

}

void 操作符

还可以使用 void 操作符。

void expression 对给定的表达式进行求值,然后返回 undefined

void 运算符通常只用于获取 undefined 的原始值,一般使用void(0)(等同于void 0)。

1
2
3
4
5
6
7
8
9
var x;
if(x === void 0) {
// 执行这些语句
}

// 没有声明y
if(y === void 0) {
// 抛出一个RenferenceError错误(与`typeof`相比)
}

Number 类型

根据 ECMAScript 标准,JavaScript 中只有一种数字类型:

基于 IEEE 754 标准的双精度 64 位二进制格式的值,即:$-(2^{63} - 1)$ 到 $2^{63} - 1$。

JavaScript 中,并没有为整数设置一个特定的类型(如其他语言中常见的 int)。

除了能够表示浮点数之外,还能表示一些带符号的值:

  • +Infinity
  • -Infinity
  • NaN(非数值,Not-a-Number)

String 类型

JavaScript 的字符串类型用于表示文本数据。它是一组 16 位的无符号整数值的“元素”。在字符串中的每个元素占据了字符串的位置。第一个元素的索引为0,下一个是索引1,依此类推。字符串的长度是它的元素的数量。

这里不做过多描述。

Symbol 类型

符号是 ECMAScript 第 6 版新定义的。符号类型是唯一的并且是不可修改的, 并且也可以用来作为 Object 的 key 的值。

要了解详细使用场景和方法,可以参考ECMAScript 6 入门 - Symbol

引用类型

对象

在 Javascript 里,对象可以被看作是一组属性的集合。

一个 Javascript 对象就是键和值之间的映射.。键是一个字符串(或者 Symbol) ,值可以是任意类型的值。

函数是一个附带可被调用功能的常规对象。

数组是一种使用整数作为键(integer-key-ed)属性和长度(length)属性之间关联的常规对象。

类型数组(Typed Arrays)是ECMAScript Edition 6中新定义的 JavaScript 内建对象,提供了一个基本的二进制数据缓冲区的类数组视图。

JavaScript 有一个内置对象的标准库。请查看参考来了解更多对象。

涉及 Object 的具体细节过多,不是本文重点,不做描述。

typeof 操作符与数据类型

虽说 JavaScript 有 7 种数据类型,而 typeof 操作符的功能是返回一个未经计算的操作数的类型的字符串值。

但是 typeof 的返回值还是与我们预料的有些差别,我们来看一下:

类型 结果
Undefined “undefined”
Null “object”
Boolean “boolean”
Number “number”
String “string”
Symbol “symbol”
宿主对象(由 JS 环境提供) Implementation-dependent
函数对象 “function”
任何其他对象 “object”

其中,最值得注意的是:typeof null 的结果为 "object",要说为什么,只能说是历史遗留的问题。

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null的类型标签也成为了 0,typeof null 就错误的返回了"object"

ECMAScript提出了一个修复(通过opt-in),但被拒绝了。

因此,我们记住这点就好,typeof null 的结果为 "object"

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Numbers
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 尽管NaN是"Not-A-Number"的缩写
typeof Number(1) === 'number'; // 但不要使用这种形式!

// Strings
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof总是返回一个字符串
typeof String("abc") === 'string'; // 但不要使用这种形式!

// Booleans
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(true) === 'boolean'; // 但不要使用这种形式!

// Symbols
typeof Symbol() === 'symbol';
typeof Symbol('foo') === 'symbol';
typeof Symbol.iterator === 'symbol';

// Undefined
typeof undefined === 'undefined';
typeof declaredButUndefinedVariable === 'undefined';
typeof undeclaredVariable === 'undefined';

// Objects
typeof {a:1} === 'object';

// 使用Array.isArray 或者 Object.prototype.toString.call
// 区分数组,普通对象
typeof [1, 2, 4] === 'object';

typeof new Date() === 'object';

// 下面的容易令人迷惑,不要使用!
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String("abc") === 'object';

// 函数
typeof function(){} === 'function';
typeof class C{} === 'function'
typeof Math.sin === 'function';
typeof new Function() === 'function';

typeof null === 'object'; // 从一开始出现JavaScript就是这样的

总结

JavaScript 中目前一共有 7 种数据类型,BooleanNullUndefinedNumberStringSymbol(ES 6 新增) 和 Object

其中基本数据类型一共有 6 种,分别是 BooleanNullUndefinedNumberStringSymbol

而常见的诸如函数(function),数组(array)等,都是属于对象,Object 类型。

参考链接

-------------本文结束感谢您的阅读-------------
0%