typeof
、instanceof
、constructor
、Object.prototype.toString()
它们来展开的一系列写法。
typeof
操作符返回一个字符串(全小写字母)
,表示未经计算的操作数的类型。
用法可以是 typeof operand 或 typeof(operand) 。
operand
一个表示对象或原始值的表达式,其类型将被返回。
//数值
console.log(typeof 1); //number
console.log(typeof 1.11); //number
console.log(typeof(1)); //number
console.log(typeof Math.PI); //number
console.log(typeof Infinity); //number
console.log(typeof NaN); //number
console.log(typeof Number(1)); //number
//字符串
console.log(typeof ""); //string
console.log(typeof "abc"); //string
console.log(typeof "1"); //string
console.log(typeof (typeof 1)); //string
console.log(typeof String(1)); //string
//布尔值
console.log(typeof false); //boolean
console.log(typeof true); //boolean
console.log(typeof Boolean(1)); //boolean
console.log(typeof !!(1)); //boolean
//Symbol
console.log(typeof Symbol()); //symbol
console.log(typeof Symbol('foo')); //symbol
console.log(typeof Symbol.iterator); //symbol
//undefined
console.log(typeof undefined); //undefined
//函数
console.log(typeof function(){}); //function
console.log(typeof class C{}); //function
console.log(typeof Math.min); //function
//对象
console.log(typeof {}); //object
console.log(typeof null); //object
console.log(typeof []); //object
console.log(typeof new Date()); //object
console.log(typeof new RegExp()); //object
// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
console.log(typeof new Boolean(true)) //object
console.log(typeof new Number(1)) //object
console.log(typeof new String('abc')) //object
instanceof
运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
语法 [对象] instanceof [构造函数]
instanceof
用来判断A
是否为B
的实例,表达式为:A instanceof B
,如果A
是B
的实例,则返回true
,否则返回false
。instanceof
检测的是原型,内部机制是通过判断对象的原型链中是否有类型的原型。
console.log({} instanceof Object); //true
console.log([] instanceof Array); //true
console.log([] instanceof Object); //true
console.log("123" instanceof String); //false
console.log(new String(123) instanceof String); //true
我们来实现一下 instanceof
function _instance(L,R){
let prototype = R.prototype; //原型
let proto = L.__proto__; //隐式原型
while(true){ //循环判断对象的原型是否等于隐式原型,直到对象原型为null,因为原型链最终为null
if(proto === null || proto === undefined){ //当到达proto原型链顶端还未匹配,返回false
return false;
}
if(proto === prototype){ //全等时,返回true
return true;
}
proto = proto.__proto__;
}
}
console.log(_instance({},Object)); //true
console.log(_instance([],Number)); //false
对象的
constructor
属性用于返回创建该对象的函数,也就是我们常说的构造函数
。
语法 object.constructor
console.log(''.constructor === String) //true
console.log(true.constructor === Boolean) //true
console.log(new Number(1).constructor === Number) //true
console.log(new Function().constructor === Function) //true
console.log(new Date().constructor === Date) //true
console.log(new Error().constructor === Error) //true
console.log([].constructor === Array) //true
console.log(document.constructor === HTMLDocument) //true
console.log(window.constructor === Window) //true
toString()
是Object原型对象上的方法,返回的是代表该对象的字符串。
调用该方法,默认返回当前对象的[[Class]],这是一个内部属性,其格式为
[object Xxx]
,其中Xxx
就是对象的类型。
而对于
Object
对象,直接调用toString()
就能返回[object Object]
,而对于其他对象(Array、String、Number、Boolean、RegExp、Date等)
,则需要通过call、apply
来调用才能返回正确的类型信息。
注
: 因为Array、String、Number、Boolean、RegExp、Date等
类型都重写
了toString()
,如果直接调用则因为自身的原型对象上已有toString()
方法,就不会调用到Object原型对象
上的toString()
方法了。
Object.prototype.toString()与Object.toString()的区别
Object.toString()
的toString()是Object构造函数上的方法,返回的是对应的函数。Object.prototype.toString()
的toString()是Object原型对象上的方法,返回的是代表该对象的字符串。+++ ok—回归正题
//判断基本类型
Object.prototype.toString.call(null); //"[object Null]"
Object.prototype.toString.call(undefined); //"[object Undefined]"
Object.prototype.toString.call(“abc”); //"[object String]"
Object.prototype.toString.call(123); //"[object Number]"
Object.prototype.toString.call(true); //"[object Boolean]"
//判断引用类型
Object.prototype.toString.call(new Function()); //"[object Function]"
Object.prototype.toString.call(new Date()); //"[object Date]"
Object.prototype.toString.call(new Array()); //"[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 Window]"
//判断JSON对象
Object.prototype.toString.call(window.JSON); //"[object JSON]"
function getType(data){
let type = typeof data;
if(type !== "object"){
return type
}
return Object.prototype.toString.call(data).replace(/^\[object (\S+)\]$/,'$1')
}
这里用到正则以及String对象的replace方法,replace详细看w3c
或者MDN