JavaScript 数据类型与类型判断详解
前言
ECMAScript 中,类型属于运行时值,变量本身不携带类型信息,仅绑定到当前值。类型判断不准确时,容易在 null、数组、普通对象之间产生误判。本文归纳基本类型与引用类型的划分,并说明 typeof、instanceof、Object.prototype.toString.call 的适用场景与局限,同时简述 ===、宽松相等与 Object.is 的差异,文末附简要练习。
一、基本类型与引用类型
除 Object 及其派生类型外,其余为基本类型(primitive):undefined、null、boolean、number、bigint、string、symbol。其中 number 包含 NaN 与 ±Infinity。检测 NaN 应使用 Number.isNaN,不应使用 x === NaN。
Object、Array、Function、Date 等属于引用类型。变量保存的是对象引用,赋值与传参传递的是引用而非对象副本;两个内容相同的字面量对象,=== 比较结果为 false,除非指向同一引用。
null 表示有意的空值。需注意 typeof null 的值为 'object',属于历史遗留行为,判断 null 应使用严格相等:x === null。
二、typeof运算符
typeof 为一元运算符,结果为字符串。常用于:
- 判断是否为
undefined:typeof x === 'undefined' - 判断是否为函数:
typeof fn === 'function'
局限包括:typeof [] 与 typeof {} 均为 'object',无法区分数组与普通对象;typeof null 为 'object',不能用于判空。
示例:
typeof undefined; // 'undefined'
typeof null; // 'object'
typeof true; // 'boolean'
typeof 1; // 'number'
typeof 1n; // 'bigint'
typeof "a"; // 'string'
typeof Symbol("s"); // 'symbol'
typeof []; // 'object'
typeof {}; // 'object'
typeof function () {}; // 'function'三、instanceof运算符
语法:obj instanceof Constructor。语义为判断 Constructor.prototype 是否出现在 obj 的原型链上,因此反映的是构造关系,而非语言内建的「类型标签」。若修改原型链,结果可能变化。
适用场景:判断是否为某构造函数的实例(含自定义类)。数组判断可优先使用 Array.isArray。需注意跨 iframe / 多 realm 时,不同全局环境下的 Array 等构造函数可能不一致,导致 instanceof 失效。
示例:
[] instanceof Array; // true [] instanceof Object; // true const arr = []; Object.setPrototypeOf(arr, null); arr instanceof Array; // false
对 null 与 undefined 使用 instanceof 无实际意义。
四、Object.prototype.toString.call
若直接调用对象自身的 toString,可能得到被重写的返回值。使用 Object.prototype.toString.call(obj) 可在多数内置类型上得到形如 [object Array]、[object Date] 的规范字符串,对区分内置类型、判断 null 等场景较为可靠。
示例:
Object.prototype.toString.call(undefined); // '[object Undefined]'
Object.prototype.toString.call(null); // '[object Null]'
Object.prototype.toString.call([]); // '[object Array]'
Object.prototype.toString.call({}); // '[object Object]'
Object.prototype.toString.call(new Date()); // '[object Date]'
Object.prototype.toString.call(/x/); // '[object RegExp]'部分对象可通过 Symbol.toStringTag 影响上述字符串,封装通用工具时需酌情处理。
判断是否为纯粹普通对象时,常见写法之一为与 [object Object] 比较:
function isPlainObject(v) {
return Object.prototype.toString.call(v) === "[object Object]";
}
五、严格相等、宽松相等与Object.is
业务代码中默认使用 ===(严格相等),类型不同时结果为 false。
**==(宽松相等)**会发生类型转换,规则较多,易引入隐蔽问题,不建议在业务逻辑中依赖。以下为常见考点,仅供理解语言行为:
null == undefined; // true "" == 0; // true [] == 0; // true NaN == NaN; // false
Object.is 与 === 主要有两处区别:Object.is(NaN, NaN) 为 true;Object.is(0, -0) 为 false(而 0 === -0 为 true)。在需要区分 -0 或按同值语义处理 NaN 时使用。
六、类型判断方式的选择
undefined、函数:可优先考虑typeofnull:使用x === null- 数组:优先
Array.isArray - 内置对象细分:
Object.prototype.toString.call - 某类的实例:在原型稳定、同 realm 前提下可使用
instanceof - 一般相等判断:
===;NaN、正负零等特殊情形结合Number.isNaN、Object.is
七、思考与练习
1.
console.log(typeof NaN); console.log(typeof typeof NaN);
解析:NaN 的类型为 number,故第一行为 'number'。typeof 的返回值为字符串,第二行等价于对 'number' 再次使用 typeof,结果为 'string'。
2.
console.log([] == ![]);
解析:![] 先将 [] 转为布尔值 true 再取反,得到 false。[] == false 在宽松相等下经类型转换后可比较为 true。此类写法仅作语言规则说明,不宜在实际项目中使用。
3. 练习:实现 getType(value),正确区分 null 与 Object,并区分数组与普通对象等。参考实现:
function getType(value) {
if (value === null) return "null";
const t = typeof value;
if (t !== "object") return t;
const tag = Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
return tag === "object" ? "object" : tag;
}总结
本文说明了 ECMAScript 中基本类型与引用类型的划分,typeof、instanceof、Object.prototype.toString.call 的用途与限制,以及 ===、宽松相等与 Object.is 的差异。实际开发中应以 === 为主,结合 Array.isArray、Object.prototype.toString.call 等 API 做准确判断。
后续文章将整理 var、let、const 与作用域、暂时性死区及常见相关例题。
到此这篇关于JavaScript 数据类型与类型判断详解的文章就介绍到这了,更多相关js数据类型与类型判断内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Bootstrap实现基于carousel.js框架的轮播图效果
这篇文章主要为大家详细介绍了Bootstrap实现基于carousel.js框架的轮播图效果,无过渡动画,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-05-05
ES6中Promise、async、await用法超详细讲解指南
async+await是ES6中引入的异步编程解决方案,旨在解决异步编程中的回调地狱问题,下面这篇文章主要给大家介绍了关于ES6中Promise、async、await用法超详细讲解的相关资料,需要的朋友可以参考下2024-08-08
微信小程序中this.data与this.setData的区别详解
这篇文章主要给大家介绍了关于微信小程序中this.data与this.setData区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧2018-09-09
《javascript设计模式》学习笔记三:Javascript面向对象程序设计单例模式原理与实现方法分析
这篇文章主要介绍了Javascript面向对象程序设计单例模式原理与实现方法,结合实例形式分析了《javascript设计模式》中Javascript面向对象单例模式相关概念、原理、用法及操作注意事项,需要的朋友可以参考下2020-04-04


最新评论