JavaScript有哪些数据类型?
JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt。
Symbol 和 BigInt
其中Symbol 和 BigInt 是 ES6+(ECMAScript 2015+)中新增的数据类型:
-
Symbol 可以理解为一个独特的标识符。想象一下,你有一把独一无二的钥匙,这把钥匙就是 Symbol。它的主要用途是避免在使用对象属性时发生意外的名字冲突。比如,如果你和别人合作开发一个大型项目,你们都想给一个对象添加一个叫"id"的属性,使用 Symbol 可以确保你们的"id"不会互相覆盖。 -
BigInt 是专门用来处理特别大的整数的。普通的 Number 类型在JavaScript中有一个最大安全整数(9007199254740991),超过这个数字可能会出现计算错误。而 BigInt 可以安全地表示和计算任意大的整数,就像是给了数字一个无限的跑道。比如,当你需要精确计算天文数字或者处理非常大的金融数据时,BigInt 就非常有用。
这两种数据类型的加入,使得 JavaScript 能够更好地处理独特标识和超大整数,增强了语言的功能性和适用范围。
简单类型和复杂类型
JavaScript 的数据类型可以分为两大类:简单类型和复杂类型。
-
简单类型(也叫原始类型):
-
这些类型就像是一个个小盒子,每个盒子里直接装着一个值。 -
包括:Undefined、Null、Boolean、Number、String、Symbol 和 BigInt。 -
它们存储在计算机的"栈"内存中,就像一摞盘子,取用方便快捷。 -
复杂类型(也叫引用类型):
-
这些类型更像是大箱子,里面可以装很多东西。 -
主要是 Object 类型,包括普通对象、数组和函数。 -
它们存储在"堆"内存中,就像一个大仓库,可以存放更多、更复杂的数据。
简单来说,简单类型就是单纯的数据,复杂类型则可以包含更多信息和功能。
两种类型的区别在于存储位置的不同:
-
栈内存:原始数据类型就像是小纸条,上面写着简单的信息(如数字或文字)。这些小纸条直接放在一个叫"栈"的抽屉里。这个抽屉很小,但是拿东西特别快,所以经常用到的小纸条就放在这里。 -
堆内存:引用数据类型则像是大箱子,里面可能装着很多东西(如各种衣物)。这些大箱子放在一个叫"堆"的大仓库里。因为箱子太大了,不能直接放在小抽屉里,所以我们在小抽屉里放了一张写有箱子位置的便利贴。当我们需要箱子里的东西时,先在抽屉里找到便利贴,然后按照便利贴上的位置信息去仓库里找到对应的箱子。
数据类型检测
-
typeof: 7种基础数据类型中除了 null 返回的是 object,其他都能准确返回(包括 Symbol 返回 symbol,BigInt 返回 bigint),复杂数据类型中 Function 类型的数据返回 function,其他都返回 object;
console.log(typeof 42); // 输出: "number"
console.log(typeof "Hello"); // 输出: "string"
console.log(typeof true); // 输出: "boolean"
console.log(typeof Symbol()); // 输出: "symbol"
console.log(typeof 42n); // 输出: "bigint"
console.log(typeof null); // 输出: "object"
console.log(typeof {}); // 输出: "object"
console.log(typeof []); // 输出: "object"
console.log(typeof function(){}); // 输出: "function"
-
instanceof: 复杂数据类型如Array等都准确返回相应的boolean值,对于基本数据类型则是返回 false (只有是通过new运算符来进行初始化,然后通过instanceof来判断是否是某个类的实例,才会返回true,比如"var k = new Number(11); console.log(k instanceof Number)",其返回true);
console.log([] instanceof Array); // 输出: true
console.log({} instanceof Object); // 输出: true
console.log(new Date() instanceof Date); // 输出: true
console.log(42 instanceof Number); // 输出: false
console.log(new Number(42) instanceof Number); // 输出: true
-
使用constructor检测:上面的instanceof对于直接声明如:"var a = 1;" 不能进行判断,我们可以通过使用constructor来实现判断,如 "a.constructor==Number" (其返回true,不过对于"1.constructor==Number"这类直接用数值来访问 constructor 的情况是会报错的),但对于null则仍然无法判断 ,而且会报错,比如"var k = null; console.log(k.constructor==Object)";
console.log((42).constructor === Number); // 输出: true
console.log("Hello".constructor === String); // 输出: true
console.log([].constructor === Array); // 输出: true
console.log(({}).constructor === Object); // 输出: true
// console.log(null.constructor === Object); // 这行会报错
-
使用Object.prototype.toString.call使用:这个方法可以获取所有的类型(包括null型),不过其返回的是类似"object Array"的形式的字符串。
console.log(Object.prototype.toString.call(42)); // 输出: "[object Number]"
console.log(Object.prototype.toString.call("Hello")); // 输出: "[object String]"
console.log(Object.prototype.toString.call(true)); // 输出: "[object Boolean]"
console.log(Object.prototype.toString.call(null)); // 输出: "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // 输出: "[object Undefined]"
console.log(Object.prototype.toString.call([])); // 输出: "[object Array]"
console.log(Object.prototype.toString.call({})); // 输出: "[object Object]"
console.log(Object.prototype.toString.call(function(){})); // 输出: "[object Function]"
注意事项
-
null
的类型检测: -
使用 typeof null
会返回"object"
,这是 JavaScript 的一个历史遗留 bug。 -
要准确检测 null
,可以使用严格相等:value === null
-
原始值包装对象:
-
JavaScript 会自动为原始值创建包装对象,这就是为什么我们可以在原始值上调用方法。 -
例如: "hello".toUpperCase()
实际上 JavaScript 会临时创建一个 String 对象。 -
Symbol 的特殊性:
-
Symbol 值是唯一的,即使描述相同,两个 Symbol 也不相等。 -
例如: Symbol('foo') !== Symbol('foo')
-
BigInt 的使用:
-
BigInt 数字后面要加 n
,例如:const bigInt = 1234567890123456789012345678901234567890n;
-
BigInt 不能与普通数字进行混合运算。 -
类型转换:
-
JavaScript 中的类型转换可能会导致意外结果,例如:
console.log([] + []); // 输出空字符串 ""
console.log([] + {}); // 输出 "[object Object]"
console.log({} + []); // 输出 0 (在某些环境下)
原创参考链接:原创参考链接