类型判断 typeof
、 instanceof
、Object.prototype.toString
涉及面试题:typeof 是否能正确判断类型?instanceof 能正确判断对象的原理是什么?
typeof
typeof
对于原始类型来说,除了 null
都可以显示正确的类型
typeof
对于引用类型,除了函数都会显示 object,所以说 typeof 并不能准确判断变量到底是什么类型
console.log(' =====> typeof null:', typeof null);
console.log(' =====> typeof undefined:', typeof undefined);
console.log(' =====> typeof 1:', typeof 1);
console.log(' =====> typeof str:', typeof 'str');
console.log(' =====> typeof true:', typeof true);
console.log(' =====> typeof Symbol():', typeof Symbol());
console.log(' =====> typeof {}:', typeof {});
console.log(' =====> typeof function(){}:', typeof function(){});
console.log(' =====> typeof []:', typeof []);
=====> typeof null: object
=====> typeof undefined: undefined
=====> typeof 1: number
=====> typeof str: string
=====> typeof true: boolean
=====> typeof Symbol(): symbol
=====> typeof {}: object
=====> typeof function(){}: function
=====> typeof []: object
instanceof
如果需要判断一个对象类型的类型,可以使用instanceof
instanceof
内部机制是通过原型链来判断的,检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上, 检测constructor.prototype
是否存在于参数 object 的原型链上
// 定义构造函数
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 的原型链上
需要注意的是,如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 Foo.prototype 属性的值有可能会改变,改变之后的值很有可能不存在于 obj 的原型链上,这时原表达式的值就会成为 false。另外一种情况下,原表达式的值也会改变,就是改变对象 obj 的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 proto 伪属性,是可以实现的。比如执行 obj.proto = {} 之后,obj instanceof Foo 就会返回 false 了。
Symbol.hasInstance
一个能让我们自定义 instanceof 行为的东西
class PrimitiveString {
static [Symbol.hasInstance](x) {
return typeof x === 'string'
}
}
console.log('hello world' instanceof PrimitiveString) // true
Object.prototype.toString
MDN:
toString()
方法返回一个表示该对象的字符串。
要准确判断类型可以使用这个方法。
项目常用的可以做个简单的封装:
let getType = value => {
return Object.prototype.toString.apply(value).slice(8, -1)
}
// let type = getType('sss') // String