JS中的8种数据类型及区别
基本类型:存储在栈内存,被引用或拷贝时,会创建一个完全相等的变量
Number
String
Boolean
Symbol // ES6引入的数据类型,表示独一无二的值
null
undefined
BigInt // ES2020引入的新数据类型,它提供了一种方法来表示大于 2的53次方 - 1 的整数。这原本是Javascript中可以用Number表示的最大数字。BigInt可以表示任意大的整数
引用类型:Object( 包含:Array,RegExp,Date,Math,Function )
数据类型检测
typeof
console.log(typeof 1); // number
console.log(typeof true); // boolean
console.log(typeof 'mc'); // string
console.log(typeof Symbol) // function
console.log(typeof BigInt) // function
console.log(typeof function(){}); // function
// 引用数据类型 Object,用 typeof 来判断的话,除了 function 会判断为 OK 以外,其余都是 'object',是无法判断出来的
console.log(typeof console.log()); // function
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof null); // object typeof null 为object是因为null的二进制全是0,所以也被判断为Object类型
console.log(typeof undefined); // undefined
// 能够快速区分出基本类型
// 不能区分出
原理:
-
typeof是操作符而不是函数,用来检测变量的类型 -
数据在底层都表示为二进制,
js中前三位(低位)代表数据类型- 000:对象
- 110:布尔
- 100:字符串
- 010:浮点数
- 1:整数
instanceof
语法: object instanceof constructor 等同于constructor.prototype.isPrototypeOf(object)
console.log(1 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
// instanceof代码实现
function instanceof(L, R) { //L是表达式左边,R是表达式右边
const O = R.prototype;
L = L.__proto__;
while(true) {
if (L === null)
return false;
if (L === O) // 这里重点:当 L 严格等于 O 时,返回 true
return true;
L = L.__proto__;
}
}
// 优点:能够区分Array、Object和Function,适合用于判断自定义的类实例对象
// 缺点:Number,Boolean,String基本数据类型不能判断
原理:
instanceof的机制是检测构造函数的prototype属性是否出现在某个实例对象的原型链上,是则返回true,否则false
结论:
- instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型;
- 而 typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了 function 类型以外,其他的也无法判断。
Object.prototype.toString
Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call({}) // 同上结果,加上call也ok
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
实现一个全局通用的数据类型判断方法
function getType(obj) {
let type = typeof obj
if (type !== "object") {
return type
}
return Object.prototype.toString.call(obj).replace(/^[object (\S+)]$/, '$1'); // 注意正则中间有个空格
}
/* 代码验证,需要注意大小写,哪些是typeof判断,哪些是toString判断?思考下 */
getType([]) // "Array" typeof []是object,因此toString返回
getType('123') // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null) // "Null"首字母大写,typeof null是object,需toString来判断
getType(undefined) // "undefined" typeof 直接返回
getType() // "undefined" typeof 直接返回
getType(function(){}) // "function" typeof能判断,因此首字母小写
getType(/123/g) //"RegExp" toString返回