JavaScript 数据类型及判断方法详解 前言 JavaScript 是一种动态类型语言,理解其数据类型及如何准确判断类型是每个前端开发者的必备技能。本文将详细介绍 JavaScript 的七种数据类型以及各种类型判断方法的优缺点和使用场景。
一、JavaScript 的七种数据类型 JavaScript 共有七种数据类型,分为两大类:基本类型和引用类型。
1. 基本类型(原始类型)
Undefined :表示未定义,只有一个值undefined
Null :表示空值,只有一个值null
Boolean :布尔值,有两个值true和false
Number :数字类型,包括整数和浮点数
String :字符串类型
Symbol :符号类型(ES6 新增)
BigInt :大整数类型(ES2020 新增)
2. 引用类型
Object :对象类型,包括普通对象、数组、函数、日期、正则表达式等
二、类型判断方法 1. typeof 操作符 typeof是最基本的类型判断方法,返回一个表示数据类型的字符串。
1 2 3 4 5 6 7 8 9 10 typeof undefined ; typeof null ; typeof true ; typeof 42 ; typeof "hello" ; typeof Symbol (); typeof 123n ; typeof {}; typeof []; typeof function ( ) {};
优点 :
缺点 :
对于 null 返回”object”(历史遗留问题)
无法区分对象和数组
对于所有引用类型(除函数外)都返回”object”
2. instanceof 操作符 instanceof用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。
1 2 3 4 5 [] instanceof Array [] instanceof Object {} instanceof Object {} instanceof Array function ( ){} instanceof Function
优点 :
缺点 :
不能用于判断基本类型
跨 iframe 或 window 时可能失效
原型链可以被修改,导致判断不准确
3. Object.prototype.toString.call() 这是最准确的类型判断方法,返回[object Type]格式的字符串。
1 2 3 4 5 6 7 8 9 10 11 12 Object .prototype .toString .call (undefined ); Object .prototype .toString .call (null ); Object .prototype .toString .call (true ); Object .prototype .toString .call (42 ); Object .prototype .toString .call ("hello" ); Object .prototype .toString .call (Symbol ()); Object .prototype .toString .call (123n ); Object .prototype .toString .call ({}); Object .prototype .toString .call ([]); Object .prototype .toString .call (function ( ) {}); Object .prototype .toString .call (/regex/ ); Object .prototype .toString .call (new Date ());
优点 :
可以准确判断所有类型
不受原型链影响
可以区分内置对象类型
缺点 :
4. constructor 属性 每个对象都有一个constructor属性,指向创建该对象的构造函数。
1 2 3 4 (42 ).constructor === Number "hello" .constructor === String [].constructor === Array {}.constructor === Object
优点 :
缺点 :
null 和 undefined 没有 constructor 属性
constructor 可以被修改
原型链继承可能导致判断错误
5. Array.isArray() 专门用于判断是否为数组的方法。
1 2 Array .isArray ([]); Array .isArray ({});
优点 :
缺点 :
三、最佳实践 1. 封装通用类型判断函数 1 2 3 4 5 6 7 8 9 10 11 12 function getType (value ) { return Object .prototype .toString .call (value).slice (8 , -1 ).toLowerCase (); } getType (42 ); getType ("hello" ); getType ([]); getType ({}); getType (null ); getType (undefined );
2. 常用类型判断工具函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 function isNull (value ) { return value === null ; } function isUndefined (value ) { return value === undefined ; } function isNullOrUndefined (value ) { return value == null ; } function isNumber (value ) { return typeof value === "number" && !isNaN (value); } function isString (value ) { return typeof value === "string" ; } function isBoolean (value ) { return typeof value === "boolean" ; } function isFunction (value ) { return typeof value === "function" ; } function isArray (value ) { return Array .isArray (value); } function isPlainObject (value ) { return getType (value) === "object" ; } function isPromise (value ) { return getType (value) === "promise" ; }
3. 类型判断的选择建议
基本类型判断 :使用typeof(除了 null)
null 判断 :使用value === null
数组判断 :使用Array.isArray()
精确类型判断 :使用Object.prototype.toString.call()
自定义类型判断 :使用instanceof
四、常见陷阱与注意事项 1. typeof null === “object” 这是 JavaScript 的一个历史遗留 bug,在第一版 JavaScript 中,null 被标记为对象类型,虽然后来有了单独的 null 类型,但为了兼容性,这个 bug 被保留了下来。
2. NaN 的特殊性 1 2 3 4 5 typeof NaN === "number" ; NaN === NaN ; Object .is (NaN , NaN ); isNaN (NaN ); Number .isNaN (NaN );
3. 包装对象的影响 1 2 3 4 5 typeof new String ("hello" ); typeof "hello" ; new String ("hello" ) instanceof String ; "hello" instanceof String ;
4. 跨 iframe 问题 1 2 3 4 5 6 const iframeArray = window .frames [0 ].Array ;const arr = new iframeArray (1 , 2 , 3 );arr instanceof Array ; Array .isArray (arr);
五、总结 JavaScript 提供了多种类型判断方法,每种方法都有其适用场景:
typeof:适合判断基本类型(除 null 外)
instanceof:适合判断引用类型和自定义类型
Object.prototype.toString.call():最准确的类型判断方法
Array.isArray():专门用于判断数组
constructor:可以用于类型判断,但不够可靠
在实际开发中,建议根据具体需求选择合适的判断方法,或者封装成工具函数以提高代码的可读性和可维护性,准确的类型判断是编写健壮 JavaScript 代码的基础。