本文用最简明的语言,带你掌握 JS 类型判断与类型转换的核心方法和底层逻辑,配合实例,助你轻松复习和应用。
一、JS 的数据类型有哪些?
JavaScript 的数据类型分为两大类:
- 基本类型(Primitive Types):
string
、number
、boolean
、undefined
、null
、symbol
、bigint
- 引用类型(Reference Types):如
Object
、Array
、Function
、Date
、RegExp
等
二、类型判断方法全览
1. typeof:最常用的类型判断
typeof
是前端面试和开发中最常用的类型判断工具。它的用法非常简单:
console.log(typeof 123); // "number"
console.log(typeof 'hello'); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof Symbol()); // "symbol"
console.log(typeof 10n); // "bigint"
但是,typeof 有两个“坑”:
- 无法准确判断 null
console.log(typeof null);
这是 JS 设计早期的历史遗留问题,
null
实际上是基本类型,但 typeof
却返回 "object"。
- 无法区分对象类型
console.log(typeof {}); // "object" console.log(typeof []); // "object" console.log(typeof function(){}); // "function"
除了函数,其他引用类型都只会返回 "object"。
原理小科普
typeof
本质是通过值的二进制标识来判断类型。对于前三位为 0 的,都会被识别为对象类型,而所有引用类型的二进制前三位都是 0,null
的二进制全是 0,所以也被误判为 "object"。
2. instanceof:判断对象归属
instanceof
用于判断一个对象是否属于某个构造函数的实例。它的判断机制是:通过对象的隐式原型链(__proto__
)查找是否存在等于右边构造函数的 prototype。
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(function(){} instanceof Function); // true
console.log([] instanceof Object); // true
注意:
instanceof
只能判断引用类型,不能判断基本类型。console.log(123 instanceof Number); // false
- 适合判断自定义对象、数组、函数等。
3. Object.prototype.toString.call:最精确的类型判断
如果你想要精确判断所有类型,包括 null
和 undefined
,推荐使用 Object.prototype.toString.call()
。
console.log(Object.prototype.toString.call(123)); // [object Number]
console.log(Object.prototype.toString.call('abc')); // [object String]
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]
原理简述
- 如果 this value 未定义,则返回 "[object Undefined]"
- 如果 this value 为 null,则返回 "[object Null]"
- 其他类型会返回 "[object 类型名]"
这种方式几乎可以判断所有 JS 内置类型,是最推荐的类型判断方法。
注意
返回的结果是一个用 [] 包裹的字符串,所以如果只想要得到类型的话,可以使用方法: console.log(type.slice(8, -1)) 将类型截取出来。
4. Array.isArray:专门判断数组
判断数组最推荐的方法是 Array.isArray()
:
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
console.log(Array.isArray('abc')); // false
三、类型转换的原理与场景
类型转换分为显示转换和隐式转换,本质原理一致,只是触发方式不同。
1. 显示类型转换
- 转布尔:
Boolean(x)
- 转数字:
Number(x)
- 转字符串:
String(x)
例子:
console.log(Boolean(0)); // false
console.log(Number('123')); // 123
console.log(String(456)); // "456"
2. 隐式类型转换
JS 在特定场景下会自动进行类型转换,常见场景有:
- 四则运算:
+ - * / %
- 判断语句:
if while == >= <= != > <
例子:
console.log('5' + 3); // "53"(字符串拼接)
console.log('5' - 3); // 2 (字符串转数字)
console.log(1 == '1'); // true(== 会进行类型转换)
console.log([] == false); // true(复杂的隐式转换)
四、== 与 === 的区别
==
会进行隐式类型转换,只判断值是否相等。===
不会进行类型转换,值和类型都要相等。
例子:
console.log(1 == '1'); // true
console.log(1 === '1'); // false
console.log(null == undefined); // true
console.log(null === undefined); // false
建议:
开发中优先使用 ===
,避免隐式转换带来的坑。
五、ToPrimitive 原理
当 JS 需要将对象转为原始类型时,会调用 ToPrimitive
,分为两种模式:
ToPrimitive(obj, String)
:先调用toString()
,再调用valueOf()
ToPrimitive(obj, Number)
:先调用valueOf()
,再调用toString()
例子:
const obj = {
valueOf() { return 123; },
toString() { return 'abc'; }
};
console.log(String(obj)); // "abc"(优先 toString)
console.log(Number(obj)); // 123 (优先 valueOf)
如果
toString()
或 valueOf()
返回的不是原始类型,会继续尝试下一个方法,否则抛出 TypeError。
六、valueOf 和 toString 的区别
valueOf()
:返回对象的原始值,通常用于数字运算。toString()
:返回对象的字符串表示,通常用于字符串拼接。
例子:
const arr = [1, 2, 3];
console.log(arr.valueOf()); // [1, 2, 3]
console.log(arr.toString()); // "1,2,3"
七、常见隐式类型转换场景
1. 四则运算
+
:只要有一个是字符串,另一个也会转为字符串拼接。- 其他运算符(
- * / %
):会将操作数都转为数字。
例子:
console.log('2' + 3); // "23"
console.log('2' - 1); // 1
console.log(true + 1); // 2
console.log(false * 2); // 0
2. 判断语句
if (x)
、while (x)
:会将x
转为布尔值。
例子:
if ('') console.log('不会执行');
if (0) console.log('不会执行');
if ([]) console.log('会执行'); // 空数组为 true
八、总结
-
类型判断优先用
Object.prototype.toString.call
,判断数组用Array.isArray
。 -
类型转换要分清显示和隐式,开发中尽量避免隐式转换带来的不确定性。
-
==
和===
区别牢记,推荐全用===
。 -
理解
ToPrimitive
、valueOf
、toString
的调用顺序和作用。 -
多写例子,多调试,遇到类型相关的 bug,先用
console.log(typeof x)
或Object.prototype.toString.call(x)
检查类型。
类型判断和类型转换是 JS 基础中的基础,掌握好常用方法和转换逻辑,写代码更稳健,排查 bug 更高效。遇到类型相关问题,回头看看这篇,一定有收获!