本文详细介绍JavaScript中检测数据类型的四种常用方法:typeof、instanceof、constructor以及Object.prototype.toString。文章深入解析了各方法的语法、返回值特点及局限性,重点对比了typeof在null和function判断上的特殊表现,以及instanceof在原型链检测中的原理与不足,最后推荐Object.prototype.toString.call()作为最准确的类型检测方案。
在深入探讨具体的类型检测手段之前,有必要先梳理JavaScript语言中数据类型的整体架构。
JavaScript的数据体系主要划分为两大阵营:基本数据类型(Primitive Types)与引用数据类型(Reference Types)。
基本数据类型涵盖number、string、boolean、null、undefined以及ES6新增的symbol;引用数据类型则主要指object,其下包含array、function、date等具体类型。
如需了解各类数据类型的详细特性,可参考相关技术文档。
针对数据类型的检测,JavaScript提供了四种主流方案。
- typeof运算符
- instanceof运算符
- constructor属性
- Object.prototype.toString.call()方法
1. typeof
语法:
typeof(变量)
//or
typeof 变量示例:
console.log(typeof ""); //string
console.log(typeof 1); //number
console.log(typeof true); //boolean
console.log(typeof null); //object!!!
console.log(typeof undefined); //undefined
console.log(typeof []); //object
console.log(typeof function(){}); //function
console.log(typeof console.log); //function
console.log(typeof {}); //object
console.log(typeof Symbol()); //symbol(es6)
console.log(typeof 23423n); //bigint(谷歌67版本新提出)总结:
typeof的返回类型为字符串,值有:number、boolean、string、object、function、undefined、symbol、biginttypeof一般用来判断基本数据类型,除了判断null会输出"object",其它都是正确的typeof判断引用数据类型时,除了判断函数会输出"function",其它都是输出"object"
注意:这里涉及两个经常考的面试题!
null的数据类型是object (null是一个空的引用对象,是一个占位符)console.log的数据类型是function- 对于引用数据类型的判断,使用typeof并不准确,所以可以使用instanceof来判断引用数据类型
2. instanceof
instanceof 可以准确的判断引用数据类型,它的原理是检测构造函数的prototype属性是否在某个实例对象的原型链上
语法:
obj1 instanceof obj2 //obj1 是否是 obj2的实例
示例:
console.log(9 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('libo' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
// 注意以下两组
console.log(typeof null); //object
console.log(null instanceof Object); //false !!!
console.log(typeof NaN); //number
console.log(NaN instanceof Number); //false !!!总结:
instanceof用来判断对象,代码形式为 【obj1 instanceof obj2】(obj2 必须为对象,否则会报错!)instanceof返回值为布尔值
注意:
instanceof只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型
3. constructor(构造函数)
当一个函数 F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向 F 的引用。
如下所示:

当执行 var f = new F() 时,F 被当成了构造函数,f 是F的实例对象,此时 F 原型上的 constructor 传递到了 f 上,因此f.constructor === F

可以看出,F 利用原型对象上的 constructor 引用了自身,当 F 作为构造函数来创建对象时,原型上的 constructor 就被遗传到了新创建的对象上, 从原型链角度讲,构造函数 F 就是新对象的类型。这样做的意义是,让新对象在诞生以后,就具有可追溯的数据类型。
同样,JavaScript 中的内置对象在内部构建时也是这样做的:

🔺注意:
- null和undefined是无效的对象,所以他们不会有constructor属性!
- 函数的constructor是不稳定的,主要是因为开发者可以重写prototype,原有的constructor引用会丢失,constructor会默认为Object
为什么变成了 Object?
因为 prototype 被重新赋值的是一个 { }, { } 是 new Object() 的字面量,因此 new Object() 会将 Object 原型上的 constructor 传递给 { },也就是 Object 本身。
因此,为了规范开发,在重写对象原型时一般都需要重新给 constructor 赋值,以保证对象实例的类型不被篡改。
4. Object.prototype.toString.call()
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); // [object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; // [object global] window 是全局对象 global 的引用到此这篇关于JavaScript中检测数据类型的四种方法的文章就介绍到这了,更多相关JavaScript检测数据类型内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!