背景
typeof和instanceof操作符都是用来判断数据类型的。但是他们使用场景不相同,其中的细节我们需要注意。
typeof
typeof是一个一元运算符,放在一个运算符前面,这个运算符可以以任何数据类型存在,判断时返回一个字符串来说明运算符的类型。
const type = typeof '中国万岁'; // string
typeof 666; // number
typeof true; // boolean
typeof undefined; // undefined
typeof Symbol(); // symbol
typeof 1n; // bigint
typeof () => {}; // function
typeof []; // object
typeof {}; // object
typeof new String('xxx'); // object
typeof null; // object
以上可知,typeof只能判断原始数据类型和函数,在无法准确的判断引用数据类型的时候全部返回object。
特别注意在我们调用typeof null的使用返回的也是object,这是因为特殊值null被认为是一个对空对象的引用。
instanceof
instanceof运算符返回的是一个布尔值,可以用来检测构造函数的prototype属性是否出现在某个实列的圆形脸上。简单来说只要右边变量的prototype在左边变量的原型链上就返回true。
const result = [] instanceof Array; // true
const Person = function() {};
const p = new Person();
p instanceof Person; // true
const message = new String('xxx');
message instanceof String; // true
区别
- typeof 会返回一个运算数的基本类型,instanceof 返回的是布尔值
- instanceof 可以准确判断引用数据类型,但是不能正确判断原始数据类型
- typeof 虽然可以判断原始数据类型(null 除外),但是无法判断引用数据类型(function 除外)
扩展
Object.prototype.toString.call()
typeof和instanceof都有一定的弊端,并不能满足所有场景的需求。如果需要通用检测数据类型,可以使用Object.prototype.toString.call()方法:
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(666); // "[object Number]"
Object.prototype.toString.call('xxx'); // "[object String]"
复制代码
注意,该方法返回的是一个格式为"[object Object]"的字符串。