js数据类型

众所周知,js数据类型分为原始数据类型和引用数据类型,原始数据类型包括Number,String,boolean,undefined,null,储存在栈内存中,栈中储存的数据就是数据本身。引用数据类型包括function,object,Array。储存在堆内存中,其中在栈内存中储存了指针,保存了数据在堆内存中的位置。
当然,在es6引入了Symbol数据类型和BigInt数据类型,其中Symbol代表创建后独一无二且不变的数据类型,主要作用是为了解决可能出现的全局变量冲突的问题;BigInt是一种升级版的Number数据类型,可以安全储存和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。本博客暂不讨论这两种数据类型的判断。

方法1:typeof

console.log(typeof 2)							// 'number'
console.log(typeof 'dghh')						// 'string'
console.log(typeof true)						// 'boolean'
console.log(typeof undefined)					// 'undefined'
console.log(typeof null)						// 'object'
console.log(typeof [1,2,3])						// 'object'
console.log(typeof function(){})				// 'function'
console.log(typeof {})							// 'object'

其中数组,对象,null判断都为object,无法判断这三者数据类型,其余均正确。

方法2:===

其实这种方法只针对数据类型的可选值只有一种的情况,可判断null和undefined。

let a = undefined
let b = null
console.log(a === undefined)			// true
console.log(b === nul)					// true

方法3: instanceof

该方法可判断对象的具体数据类型,原理为在左边参数的原型链是否能找出右边构造函数的原型。

console.log(2 instanceof Number)						// false
console.log('dghh' instanceof String)					// false
console.log(true instanceof Boolean)					// false
console.log(function() {} instanceof Function)			// true
console.log([1,2] instanceof Array)						// true
console.log({} instanceof Object)						// true

注意这里判断时,右边为构造函数,首字母大写,返回值是boolean类型。

方法4:constructor

constructor有两个作用,一是判断数据类型,二是实例对象可以通过调用该属性查看构造函数,由于null与undefined并不能使用构造函数构造,因此constructor无法判断null与undefined。

console.log((2).constructor === Number)					// true 这里数字直接量如果不加括号直接调用,数字后小数点会引发歧义
console.log(''.constructor === String)					// true
console.log(true.constructor === Boolean) 				// true
console.log(function(){}.constructor === Function)		// true
console.log([].constructor === Array)					// true
console.log({}.constructor === Object)					// true

这里需要注意一点,constructor的原理是找到构造函数来判断数据类型,但根据原型链的知识,当数据类型的原型被修改时,constructor方法就失效了,例如:

function Fun() {}
Fun.prototype = new String()	//修改原型
let fun = new Fun()
console.log(fun.constructor)	// function String()

方法5:toString()方法

但是由于number,array,function等都重写的Object的toString()方法,因此需要使用Object原型上的toString()方法,并用call绑定到需要检测的变量上,该方法可判断所有数据类型,但只能通过输出来观察数据类型。当然,如果实在有判断需求,可通过返回值为字符串,通过slice(8,-1)来截取字符串判断。如下:

let toS = Object.prototype.toString()
console.log(toS.call(1))				// '[object Number]'
console.log(toS.call(1).slice(8,-1))	// 'Number' 截取字符串判断
console.log(toS.call('dghh'))			// '[object String]'
console.log(toS.call(true))				// '[object Boolean]'
console.log(toS.call([]))				// '[object Array]'
console.log(toS.call(function() {}))	// '[object Function]'
console.log(toS.call({}))				// '[object Object]'
console.log(toS.call(undefined))		// '[object Undefined]'
console.log(toS.call(null))				// '[object Null]'