引自MDN:
最新的 ECMA 标准定义了 7 种数据类型:
至今,JS中共上述7种数据类型。这里需要注意,不要将js的内置对象:Date、Array等与数据类型混淆了,这些内置对象和我们自己创建的对象统一属于 类型。
6中原始类型的值都无法改变。举个栗子,数值1,我们是无法将他改变成2的;字符串的变化实质上也是产生了一个新的字符串,旧的字符串仍然不变。由于这种特性,js会将其存至栈中,按值访问。而引用类型 内容是可变的,而且大小不固定,所以将它存入堆中,通过地址引用的方式调用。
Boolean类型:表示逻辑,取值true、false。
Number类型:表示数字,和其他语言不同,js只有一种数字类型,是基于IEEE 754标准的双精度64位的值,取值范围(-2^63 - 1 至 2^63 - 1)。此外还有一些特殊标识符:Infinity、-Infinity、NaN。
String类型:表示字符串,由字符(2个字节)组成的一组数据,因此它也具有数组的可遍历、拥有长度属性等特性。
Symbol类型:表示符号类型,ES6新增的数据类型,表示一个唯一值,一般作为对象的key值或者枚举之用,非常适合消除魔法字符串。
Null类型:表示空值,可以理解为一个尚未创建的对象。它虽然是空值,但是却是一个对象,而且 对象是继承自它,所以它可以说才是真正的对象始祖。
注意:虽然null是一个对象,但是其中的属性都是不可访问的,因此,我们是无法通过代码获取它的属性的。
Undefined类型:表示未定义,一个没有定义的变量或者没有赋予初始值的对象的值就是undefined。这里不要与Null混淆,它不是一个对象。
null === undefined; //falsenull == undefined; //true null === null; //trueundefined == undefined; //true 类型:表示对象。在计算机科学中, 对象是指内存中的可以被标识符引用的一块区域。在JS中,对象可以被看做是一组属性的集合。JS中以 和Function两个对象为基础,衍生出了现在百花齐放的各种对象,JS的继承、原型等都在这个基础上实现的。
类型判断
由于js弱类型的机制,变量的类型需要我们自己判断。江湖上出现了各种判断方法,下面我们来总结一下。
1.typeof
MDN上推荐的方法。
let str = 'string'; let pNum = 11; let bRt = true; let pSymbol = Symbol('symbol'); let pObj = {}; let pArray = []; let fun = function () {}; //typeof console.log('字符串', typeof str); //string console.log('数字', typeof pNum); //number console.log('布尔', typeof bRt); //boolean console.log('符号', typeof pSymbol); //symbol console.log('null', typeof null); // console.log('undefined', typeof undefined); //undefined console.log('对象', typeof pObj); // console.log('数组', typeof pArray); // console.log('函数', typeof fun); //function如上执行结果,对于原始类型(除了null以外),输出结果没问题。但是对于引用类型,输出结果只会是 、function,这并非我们预期的结果。
typeof输出的结果包含以下7种:number、boolean、string、symbol、undefined、 、function。
2.instanceof
这种方式只能判断拥有原型的对象,并且只能判断比较的两个对象之间是否属于实例关系(包括继承),不能获取类型。
console.log('对象', pObj instanceof ); //true console.log('数组是否数组', pArray instanceof Array); //true console.log('数组是否对象', pArray instanceof ); //true console.log('函数是否函数', fun instanceof Function); //true console.log('函数是否对象', fun instanceof ); //true需要注意,它会去原型链上去寻找匹配项,例如:
pArray instanceof 结果也是true。该方法用作判断变量是否是某个类的实例非常有效。但是需要注意,这里的比对默认都是在同一个全局环境下比对的。也就是说,在同一个 下,我们才能得到正确结果。如果在 1下去判断一个变量是否属于 2的 ,只会得到false结果。3.constructor或__proto__
console.log('construct'); console.log('字符串', str.construct === String.construct); //true // console.log('数字', typeof pNum); //数字没有construct console.log('布尔', bRt.construct === Boolean.construct); //true // console.log('符号', typeof pSymbol); //symbol没有construct // console.log('null', typeof null); //null无法访问construct属性 // console.log('undefined', typeof undefined); //undefined无法访问construct属性 console.log('对象', pObj.construct === .construct); //true console.log('数组', pArray.construct === Array.construct); //true console.log('函数', fun.construct === Function.construct); //true console.log('__proto__'); console.log('字符串', str.__proto__ === String.prototype); //true // console.log('数字', typeof pNum); //数字没有prototype console.log('布尔', bRt.__proto__ === Boolean.prototype); //true // console.log('符号', typeof pSymbol); //symbol没有prototype // console.log('null', typeof null); //null无法访问prototype属性 // console.log('undefined', typeof undefined); //undefined无法访问prototype属性 console.log('对象', pObj.__proto__ === .prototype); //true console.log('数组', pArray.__proto__ === Array.prototype); //true console.log('函数', fun.__proto__ === Function.prototype); //true原理同2,只是不会再去原型链上查找了,这里固定只对比当前对象的实例。
4.toString
console.log('字符串', .prototype.toString.call(str)); //[ String] console.log('数字', .prototype.toString.call(pNum)); //[ Number] console.log('布尔', .prototype.toString.call(bRt)); //[ Boolean] console.log('符号', .prototype.toString.call(pSymbol)); //[ Symbol] console.log('null', .prototype.toString.call(null)); //[ Null] console.log('undefined', .prototype.toString.call(undefined)); //[ Undefined] console.log('对象', .prototype.toString.call(pObj)); //[ ] console.log('数组', .prototype.toString.call(pArray)); //[ Array] console.log('函数', .prototype.toString.call(fun)); //[ Function] console.log('日期', .prototype.toString.call(new Date())); //[ Date] console.log('window', .prototype.toString.call(window)); //[ HTMLDocument] console.log('document', .prototype.toString.call(document)); //[ global]中定义的toString方法,返回的是当前对象的内部属性[[Class]],结果格式为[ Xxx],其中Xxx就是我们判断数据类型的依据,也是内置对象的字符串。
看一下优秀的框架是怎么做的
JQuery
function toType( obj ) { if ( obj == null ) { return obj + ""; } // Support: Android <=2.3 only (functionish RegExp) return typeof obj === " " || typeof obj === "function" ? class2type[ toString.call( obj ) ] || " " : typeof obj;}原始类型使用typeof,引用类型使用toString。
AngularJs
function isNumber(value) {return typeof value === 'number';}function isDate(value) { return toString.call(value) === '[ Date]';}也是一样,原始类型使用typeof,引用类型使用toString。
这里其实toString能够完成typeof的所有任务,不知为何以上两个框架会混用。私自猜测可能是因为typeof使用起来更为简洁一点,所以会优先使用typeof。
总结
①boolen、number、string、symbol、function可通过typeof或toString方式判断。
②null、undefined直接通过 ===运算符判断。
③js内置对象,如: 、Function、Date、Regex等通过toString方式判断。
④自定义类和相应继承类,通过 instanceof判断。
继续阅读与本文标签相同的文章
sinon.js基础使用教程---单元测试
-
Vue 实战 (一) -- Vue 基础总结
2026-06-02栏目: 教程
-
美丽的闭包,在js中实现函数重载
2026-06-02栏目: 教程
-
安装完zsh之后终端显示mvn命令不存在的问题
2026-06-02栏目: 教程
-
Vue 2.x 实战之后台管理系统开发(二)
2026-06-02栏目: 教程
-
Oracle 11g sql_Monitor的实时监控
2026-06-02栏目: 教程
