发布于2026-07-23 阅读(0)
扫一扫,手机访问
Ja vaScript 的数据类型,说到底就两大阵营:原生值(primitive values)和对象(objects)。搞清楚这个分类,很多看似奇怪的行为就有了答案。
到目前为止,Ja vaScript 一共定义了七个原生值。记住一个简单的规则:这七个之外的所有东西,都是对象。
原生值有个很重要的特性——不可变(immutable)。意思是,你没法直接修改值本身。举个简单的例子:
let greeting = "Hi"; greeting = "Hello"; // 此时打印 greeting 是 Hello,但 "Hi" 这个值本身没变,只是 greeting 指向了新的值
这七个原生值分别是:
字符串是最常见的原生值之一。前面提到它不可变,所以当你用 substring() 截取或 concat() 拼接时,实际上返回的是一个新的字符串,原字符串纹丝不动。
只有 true 和 false 两个值,没什么好说的,但它是所有逻辑判断的基石。
Ja vaScript 不像某些语言那样区分整数和浮点数,统统用 number 这个类型。甚至 +Infinity、-Infinity 和 NaN 也都是 number——不信你试试:
console.log(typeof NaN); // "number"
这里有个关键点:number 在 Ja vaScript 里是双精度浮点数,精确范围在 -(2^53 − 1) 到 2^53 − 1 之间。超出这个范围,精度就会出问题,这时候就该 BigInt 登场了。
前面说整数和浮点数都用 number,其实只说对了一半。因为 number 的精度有限(2^53 - 1 大约是 9007199254740991,日常很少用到那么大),但某些场景(比如加密、高精度数学计算)需要更精确的整数。这时 BigInt 就派上用场了。
BigInt 可以按需控制精度,而且支持 +、*、-、**、% 等运算符。但要注意:它不能和 number 混用,否则会直接抛 TypeError。
undefined 既是类型,也是值。它代表“尚未定义”。
比如变量未声明就直接使用,会报 ReferenceError:
console.log(a); // ReferenceError: a is not defined
用 let/const 声明了但在初始化前使用:
console.log(a); let a = 1; // ReferenceError: Cannot access 'a' before initialization
变量声明了但没有赋值:
let greeting; console.log(greeting); // undefined
null 是很容易和 undefined 搞混的一个值。简单说:undefined 是 Ja vaScript 帮你“自动”产生的,表示这个变量还没给值;而 null 是你自己主动赋给变量的,表示“这里我想要一个空值”。
最后一个原生值是 Symbol,它是独一无二的标识符,通常配合对象使用,作为对象的键(key):
const sym = Symbol("ExplainYYDS");
const obj = { [sym]: "Interview Preps for Software Engineers" };
obj[sym]; // "Interview Preps for Software Engineers"
除了上面七个原生值,剩下的全是对象。Ja vaScript 圈有个经典梗:数组是对象,函数是对象,对象还是对象。没错,就是这么简单粗暴。
最常用的方法是 typeof。比如:
let greeting = "hi"; console.log(typeof greeting); // 'string'
但有两个坑需要心里有数:
typeof null 返回的是 "object"——这是历史遗留的 bug,修复成本太高,就一直这么留着了。typeof 数组 返回 "object",typeof 函数 返回 "function"。console.log(typeof null); // "object"
console.log(typeof []); // "object"
console.log(typeof function () {}); // "function"
附上 typeof 完整结果表:
| val 的类型 | 结果 |
|---|---|
| Undefined | "undefined" |
| Null | "object" |
| Boolean | "boolean" |
| Number | "number" |
| String | "string" |
| Object (原生且未实现 [[Call]]) | "object" |
| Object (原生或宿主且实现了 [[Call]]) | "function" |
| Object (宿主且未实现 [[Call]]) | 由实现定义,但不能是 "undefined"、"boolean"、"number" 或 "string" |
正因为 typeof 无法区分数组和普通对象,所以需要额外的方法。
Array.isArray() 是最直接的方式:
Array.isArray([1, 2, 3]); // true
Array.isArray({ foo: 123 }); // false
如果想更通用地辨别数组、函数和普通对象,可以用 Object.prototype.toString():
const arr = [1, 2, 3];
const fn = () => { return 123; };
const obj = { foo: 123 };
console.log(Object.prototype.toString.call(arr)); // [object Array]
console.log(Object.prototype.toString.call(fn)); // [object Function]
console.log(Object.prototype.toString.call(obj)); // [object Object]
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8