JavaScript有哪些数据类型?

JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt。

一、基本数据类型(原始类型)

1. String(字符串)
表示文本数据,用单引号 '' 或双引号 "" 包裹。支持转义字符(如 \n 换行)和模板字符串(ES6)。

2. Number(数字)
包含整数、浮点数及特殊值(Infinity、-Infinity、NaN)。JavaScript不区分整型和浮点型,均以64位浮点数存储。

3. Boolean(布尔值)
仅有两个值:true 和 false,常用于条件判断。

4. Null
表示“空值”,通常用于显式清空变量引用。typeof null 返回 "object"(历史遗留问题)。

5. Undefined
表示变量已声明但未赋值,或对象属性不存在时的默认值。

6. Symbol(符号,ES6新增)
唯一且不可变的值,常用作对象属性的唯一标识符。

7. BigInt(大整数,ES2020新增)
用于表示超出 Number 精度范围的大整数,后缀加 n(如 123n)。

二、引用数据类型(对象类型)

1. Object(对象)
键值对的集合,可包含任意类型数据(包括其他对象)。例如:

let person = { name: "John", age: 30 };

2. Array(数组)
有序集合,元素可为任意类型。通过索引访问,支持动态长度:

let arr = [1, "two", true];


3. Function(函数)
可执行代码块,本质是“可调用对象”。例如:

let arr = [1, "two", true];


4. 其他内置对象
包括 Date(日期)、RegExp(正则表达式)、Map/Set(ES6新增数据结构)等。

三、类型特性与操作

1. 动态类型
JavaScript是弱类型语言,变量类型可动态改变:

let a = 10;    // Number
a = "text";    // 变为 String


2. 类型检测

  • typeof:返回类型字符串(如 typeof "text" → "string",但 typeof null → "object")。

  • instanceof:检测对象是否为某构造函数的实例(如 arr instanceof Array → true)。

  • Array.isArray():专用于检测数组。

3. 类型转换

  • 隐式转换:如 5 + "10" → "510"(数字转字符串)。

  • 显式转换:使用 Number()、String()、Boolean() 等函数。

四、注意事项

• 引用类型与内存管理:对象类型变量存储的是内存地址,复制时需注意浅拷贝与深拷贝的区别。

• null vs undefined:null 表示空值(需显式赋值),undefined 表示未初始化。

• Symbol与唯一性:Symbol('key') !== Symbol('key'),适用于避免属性名冲突。

Symbol 和 BigInt

其中Symbol 和 BigInt 是 ES6+(ECMAScript 2015+)中新增的数据类型:

  • Symbol 可以理解为一个独特的标识符。想象一下,你有一把独一无二的钥匙,这把钥匙就是 Symbol。它的主要用途是避免在使用对象属性时发生意外的名字冲突。比如,如果你和别人合作开发一个大型项目,你们都想给一个对象添加一个叫"id"的属性,使用 Symbol 可以确保你们的"id"不会互相覆盖。
  • BigInt 是专门用来处理特别大的整数的。普通的 Number 类型在JavaScript中有一个最大安全整数(9007199254740991),超过这个数字可能会出现计算错误。而 BigInt 可以安全地表示和计算任意大的整数,就像是给了数字一个无限的跑道。比如,当你需要精确计算天文数字或者处理非常大的金融数据时,BigInt 就非常有用。

这两种数据类型的加入,使得 JavaScript 能够更好地处理独特标识和超大整数,增强了语言的功能性和适用范围。

简单类型和复杂类型

JavaScript 的数据类型可以分为两大类:简单类型和复杂类型。

  1. 简单类型(也叫原始类型)

    • 这些类型就像是一个个小盒子,每个盒子里直接装着一个值。
    • 包括:Undefined、Null、Boolean、Number、String、Symbol 和 BigInt。
    • 它们存储在计算机的"栈"内存中,就像一摞盘子,取用方便快捷。
  2. 复杂类型(也叫引用类型)

    • 这些类型更像是大箱子,里面可以装很多东西。
    • 主要是 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]"

注意事项

  1. null的类型检测:

    • 使用typeof null会返回"object",这是 JavaScript 的一个历史遗留 bug。
    • 要准确检测null,可以使用严格相等:value === null
  2. 原始值包装对象:

    • JavaScript 会自动为原始值创建包装对象,这就是为什么我们可以在原始值上调用方法。
    • 例如:"hello".toUpperCase()实际上 JavaScript 会临时创建一个 String 对象。
  3. Symbol 的特殊性:

    • Symbol 值是唯一的,即使描述相同,两个 Symbol 也不相等。
    • 例如:Symbol('foo') !== Symbol('foo')
  4. BigInt 的使用:

    • BigInt 数字后面要加n,例如:const bigInt = 1234567890123456789012345678901234567890n;
    • BigInt 不能与普通数字进行混合运算。
  5. 类型转换:

    • JavaScript 中的类型转换可能会导致意外结果,例如:

console.log([] + []); // 输出空字符串 ""
console.log([] + {}); // 输出 "[object Object]"
console.log({} + []); // 输出 0 (在某些环境下)

 

posted @ 2024-09-26 10:28  有只橘猫  阅读(413)  评论(0)    收藏  举报