javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > js数据类型与类型判断

JavaScript 数据类型与类型判断详解

作者:xiaofeichaichai

本文详细解析了JavaScript数据类型与类型判断,探讨了typeof、instanceof、Object.prototype.toString.call的相关知识,感兴趣的朋友一起看看吧

前言

ECMAScript 中,类型属于运行时值,变量本身不携带类型信息,仅绑定到当前值。类型判断不准确时,容易在 null、数组、普通对象之间产生误判。本文归纳基本类型与引用类型的划分,并说明 typeofinstanceofObject.prototype.toString.call 的适用场景与局限,同时简述 ===、宽松相等与 Object.is 的差异,文末附简要练习。

一、基本类型与引用类型

Object 及其派生类型外,其余为基本类型(primitive):undefinednullbooleannumberbigintstringsymbol。其中 number 包含 NaN±Infinity。检测 NaN 应使用 Number.isNaN,不应使用 x === NaN

ObjectArrayFunctionDate 等属于引用类型。变量保存的是对象引用,赋值与传参传递的是引用而非对象副本;两个内容相同的字面量对象,=== 比较结果为 false,除非指向同一引用。

null 表示有意的空值。需注意 typeof null 的值为 'object',属于历史遗留行为,判断 null 应使用严格相等:x === null

二、typeof运算符

typeof 为一元运算符,结果为字符串。常用于:

局限包括: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

nullundefined 使用 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)trueObject.is(0, -0)false(而 0 === -0true)。在需要区分 -0 或按同值语义处理 NaN 时使用。

六、类型判断方式的选择

七、思考与练习

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),正确区分 nullObject,并区分数组与普通对象等。参考实现:

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 中基本类型与引用类型的划分,typeofinstanceofObject.prototype.toString.call 的用途与限制,以及 ===、宽松相等与 Object.is 的差异。实际开发中应以 === 为主,结合 Array.isArrayObject.prototype.toString.call 等 API 做准确判断。

后续文章将整理 varletconst 与作用域、暂时性死区及常见相关例题。

到此这篇关于JavaScript 数据类型与类型判断详解的文章就介绍到这了,更多相关js数据类型与类型判断内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文