数据类型
- 基本数据类型:String、Number、Boolean、Symbol、Undefined、Null、BigInt。
- 引用数据类型:object、Array、Function、Date等等
判断方法
- typeof
- instanceof
- Object.prototype.toString()
- constructor
typeof
- 对于基本类型,除 null 以外,均可以返回正确的结果:包括number、boolean、symbol、string、undefined、BigInt。
- 对于引用类型,除function返回function 类型以外,对Array、Function、Date等等均返回 object 类型。
- 对于 null ,返回 object 类型。
typeof是操作符而不是函数,用来检测变量的类型
- typeof的判断原理:js中数据类型在底层上是用二进制表示的,前三位(低位)代表数据类型
000:对象(因为null的二进制全是0,所以也被typeof判断为Object类型)
110:布尔
100:字符串
010:浮点数
1:整数
let num = 18
let str = "yhd"
let show = true
let sym = Symbol()
let data = undefined
let info = null
console.log(typeof num)
console.log(typeof str)
console.log(typeof show)
console.log(typeof sym)
console.log(typeof data)
console.log(typeof info)
let fun = function add() {}
let arr = ["yhd", "gsr"]
let obj = {name: "yhd", age: "23"}
let date = new Date()
console.log(typeof fun)
console.log(typeof arr)
console.log(typeof obj)
console.log(typeof date)
instance
- instanceof 可以正确判断对象的数据类型,用来判断 A 是否为 B 的实例,表达式为: A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。因为内部机制是通过判断 A 对象的原型链中是不是能找到 B 构造函数的prototype。
- 示例
let fun = function add() {};
let arr = ["yhd", "gsr"];
let obj = {name: "yhd", age: "23"};
let date = new Date();
console.log(fun instanceof Function);
console.log(arr instanceof Array);
console.log(obj instanceof Object);
console.log(date instanceof Date);
console.log(arr instanceof Object)
console.log(fun instanceof Object);
console.log(date instanceof Object);
function instance(A,B) {
A = A.__proto__
B = B.prototype
while(true){
if(A===NULL) return false
if(A===B) return true
A=A.__proto__
}
}
- instanceof 能够判断出 arr是 Array的实例,但他也认为 arr 也是 Object 的实例,为什么呢?
原因:从 instanceof 中能够判断出 arr.__proto __ 指向 Array.prototype,而 Array.prototype.__proto __ 又指向了Object.prototype,最终 Object.prototype.__proto __ 指向了null,标志着原型链的结束。因此,arr、Array、Object 就在内部形成了一条原型链。
在原型链上,arr 的 __proto __ 直接指向Array.prototype,间接指向 Object.prototype。function、date同理。
- instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。
constructor
- 当一个函数被定义时,JS引擎会为函数添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向他的构造函数
let num = 18
let str = "yhd"
let show = true
let sym = Symbol()
let data = undefined
let info = null
console.log(num.constructor)
console.log(str.constructor)
console.log(show.constructor)
console.log(sym.constructor)
console.log(data.constructor)
console.log(info.constructor)
let fun = function add() {}
let arr = ["yhd", "gsr"]
let obj = {name: "yhd", age: "23"}
let date = new Date()
console.log(fun.constructor)
console.log(arr.constructor)
console.log(obj.constructor)
console.log(date.constructor)
- null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
- 函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
toString
- toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object xxx] ,其中 xxx 就是对象的类型。
- 对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
Object.prototype.toString.call(1);
Object.prototype.toString.call('');
Object.prototype.toString.call(true);
Object.prototype.toString.call(Symbol());
Object.prototype.toString.call(undefined);
Object.prototype.toString.call(null);
Object.prototype.toString(Object);
Object.prototype.toString.call(new Function()) ;
Object.prototype.toString.call([]) ;
Object.prototype.toString.call(new Date()) ;
Object.prototype.toString.call(new RegExp()) ;
Object.prototype.toString.call(new Error()) ;
Object.prototype.toString.call(NaN) ;
参考出处