# JS 中判断类型的三种方法
# 七种兵器三种方法
一般来说我们常用于判断一个数据的类型有这七种兵器三种方法
typeof
instanceof
Object.prototype.toString()
# typeof
typeof
操作符返回一个字符串,表示未经计算的操作数的类型
typeof
只会检查 JS 的基本数据类型
console.log(0, typeof 0); // 0 "number"
console.log(1, typeof 1); // 1 "number"
console.log(NaN, typeof NaN); // NaN "number"
console.log("0", typeof "0"); // 0 "string"
console.log("1", typeof "1"); // 1 "string"
console.log(false, typeof false); // false "boolean
console.log(true, typeof true); // true "boolean"
console.log(undefined, typeof undefined); // undefined "undefined"
console.log(null, typeof null); // null "object"
console.log([], typeof []); // [] "object"
console.log({}, typeof {}); // {} "object"
console.log(function () {}, typeof function () {}); // [Function] "function"
两个注意点
console.log([], typeof []); // [] "object"
console.log(NaN, typeof NaN); // NaN "number"
记住两个特例
console.log(null, typeof null); // null "object"
console.log(function () {}, typeof function () {}); // [Function] "function"
此外还有 ES6 新增的 BigInt 数据类型
const x = 1n;
console.log(x, typeof x); // 1n "bigint"
console.log(Object(x), typeof Object(x)); // BigInt {1n} "object"
# instanceof
instanceof
运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,返回一个布尔值。
使用方法
object instanceof constructor; //即检查object是否是constructor的一个实例
// 定义构造函数
function C() {}
function D() {}
var o = new C();
o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false,因为 D.prototype 不在 o 的原型链上
o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true
C.prototype instanceof Object; // true,同上
C.prototype = {};
var o2 = new C();
o2 instanceof C; // true
o instanceof C; // false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上.
D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true 因为 C.prototype 现在在 o3 的原型链上
注意
虽然在目前的 ES 规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 proto 伪属性,是可以实现的。比如执行 obj.proto = {} 之后,obj instanceof Foo 就会返回 false 了。
# Object.prototype.toString()
每个对象都有一个 toString()
方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。
如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。
因此可以通过 toString()
来获取每个对象的类型。
为了每个对象都能通过 Object.prototype.toString()
来检测,需要以 Function.prototype.call()
或者 Function.prototype.apply()
的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg。
var toString = Object.prototype.toString;
toString.call(new Date()); // [object Date]
toString.call(new String()); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]