JavaScript 数据类型与类型判断 系列文章目录《前端 JavaScript 基础与进阶》第 01 篇JavaScript 数据类型与类型判断本文文章目录系列文章目录前言一、基本类型与引用类型二、typeof 运算符三、instanceof 运算符四、Object.prototype.toString.call五、严格相等、宽松相等与 Object.is六、类型判断方式的选择七、思考与练习总结前言ECMAScript 中类型属于运行时值变量本身不携带类型信息仅绑定到当前值。类型判断不准确时容易在null、数组、普通对象之间产生误判。本文归纳基本类型与引用类型的划分并说明typeof、instanceof、Object.prototype.toString.call的适用场景与局限同时简述、宽松相等与Object.is的差异文末附简要练习。一、基本类型与引用类型除Object及其派生类型外其余为基本类型primitiveundefined、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为一元运算符结果为字符串。常用于判断是否为undefinedtypeof x undefined判断是否为函数typeof fn function局限包括typeof []与typeof {}均为object无法区分数组与普通对象typeof null为object不能用于判空。示例typeofundefined;// undefinedtypeofnull;// objecttypeoftrue;// booleantypeof1;// numbertypeof1n;// biginttypeofa;// stringtypeofSymbol(s);// symboltypeof[];// objecttypeof{};// objecttypeoffunction(){};// function三、instanceof运算符语法obj instanceof Constructor。语义为判断Constructor.prototype是否出现在obj的原型链上因此反映的是构造关系而非语言内建的「类型标签」。若修改原型链结果可能变化。适用场景判断是否为某构造函数的实例含自定义类。数组判断可优先使用Array.isArray。需注意跨 iframe / 多 realm时不同全局环境下的Array等构造函数可能不一致导致instanceof失效。示例[]instanceofArray;// true[]instanceofObject;// trueconstarr[];Object.setPrototypeOf(arr,null);arrinstanceofArray;// 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(newDate());// [object Date]Object.prototype.toString.call(/x/);// [object RegExp]部分对象可通过Symbol.toStringTag影响上述字符串封装通用工具时需酌情处理。判断是否为纯粹普通对象时常见写法之一为与[object Object]比较functionisPlainObject(v){returnObject.prototype.toString.call(v)[object Object];}五、严格相等、宽松相等与Object.is业务代码中默认使用严格相等类型不同时结果为false。**宽松相等**会发生类型转换规则较多易引入隐蔽问题不建议在业务逻辑中依赖。以下为常见考点仅供理解语言行为nullundefined;// true0;// true[]0;// trueNaNNaN;// falseObject.is与主要有两处区别Object.is(NaN, NaN)为trueObject.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(typeofNaN);console.log(typeoftypeofNaN);解析NaN的类型为number故第一行为number。typeof的返回值为字符串第二行等价于对number再次使用typeof结果为string。2.console.log([]![]);解析![]先将[]转为布尔值true再取反得到false。[] false在宽松相等下经类型转换后可比较为true。此类写法仅作语言规则说明不宜在实际项目中使用。3. 练习实现getType(value)正确区分null与Object并区分数组与普通对象等。参考实现functiongetType(value){if(valuenull)returnnull;constttypeofvalue;if(t!object)returnt;consttagObject.prototype.toString.call(value).slice(8,-1).toLowerCase();returntagobject?object:tag;}总结本文说明了 ECMAScript 中基本类型与引用类型的划分typeof、instanceof、Object.prototype.toString.call的用途与限制以及、宽松相等与Object.is的差异。实际开发中应以为主结合Array.isArray、Object.prototype.toString.call等 API 做准确判断。后续文章将整理var、let、const与作用域、暂时性死区及常见相关例题。