typeof 与 instanceof 区别
判断数据类型的方式有很多,typeof 与 instanceof 是两个js提供的接口,那么它们都有什么优势和缺点呢?我们又如何去实现一个更完美的判断数据类型方式呢?
一、typeof
使用方式
- 指令式: typeof operand
- 函数调用式:typeof (operand)
operand
表示对象或原始值的表达式,其类型将被返回
返回值
-
返回值为字符串,一般都是(
number, boolean, string, function, object, undefined
)为什么说一般呢,因为有个Symbol
它的返回值是symbol
-
见过一道笔试题:
typeof typeof(any)
他的结果是string
ps : typeof 返回值为字符串 -
对于
Array 、 Null
等特殊对象使用 typeof 一律返回object
, 这正是 typeof 的局限性。 -
typeof null
为object
,但这只是JavaScript
存在的一个悠久Bug
,不代表null
就是引用数据类型,并且null
本身也不是对象
<script>
let a, b, c, d, e, f, g, h, i;
a = [1, 2, 3, 4, 5];
b = 1;
c = "小七";
d = false;
f = null;
e = new Date();
g = undefined;
h = function () {};
console.log(typeof(a));//object
console.log(typeof(b));//number
console.log(typeof(c));//string
console.log(typeof(d));//boolean
console.log(typeof(e));//object
console.log(typeof(f));//object
console.log(typeof(g));//undefined
console.log(typeof(h));//function
console.log(typeof(i));//undefined
</script>
缺点:可以判断基本数据类型(null 除外),但是引用数据类型中,除了function 类型以外,其他的也无法判断。
二、instanceof
instanceof
运算符用于检测构造函数的prototype
属性是否出现在某个实例对象的原型链上
使用方式
object instanceof constructor
object为实例对象, constructor为构造函数
返回值
instanceof
返回的是一个布尔值
举个栗子:
let a = new Array();
alert(a instanceof Array); // true
alert(a instanceof Object) // true
//如上, 会返回 true, 同时 alert(a instanceof Object) 也会返回 true;
// 这是因为 Array 是 object 的子类。
alert(b instanceof Array) // b is not defined
function Test() {};
var a = new test();
alert(a instanceof test) // true
根据instanceof的使用方式,其实我们是可以自己写一个出来的!
function myInstanceof(example,dataType){
let proto = Object.getPrototypeOf(example)
let prototype = dataType.prototype
while(true){
if(!proto) return false
if(proto === prototype) return true
else{
proto = Object.getPrototypeOf(proto)
}
}
}
// 使用
console.log(myInstanceof('123',Array)); //false
console.log(myInstanceof([1,2,3],Array)); //true
缺点:
instanceof
可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型。
-------------------------------------------------------
行文到此,我们可以发现这两种方式都有自己的缺陷,那我们如何得到一个比较完美的解决方案呢
三、Object.prototype.toString
使用方式
Object.prototype.toString( { } )
括号内写要判断的数据
返回值
- 统一返回格式
[object XXX]
的字符串XXX
就是该数据的数据类型
完美解决方案:
function getType(obj){
let type = typeof obj;
if (type !== "object") return type
return Object.prototype.toString.call(obj).slice(8,-1);
}
}
getType([]) // "Array" typeof []是object,因此toString返回
getType('123') // "string" typeof 直接返回