第一种:Typeof
- typeof 检测数据类型
console.log(typeof 10); // number console.log(typeof 'name'); // string console.log(typeof true); // boolean console.log(typeof undefined); // undefined console.log(typeof Symbol(100)); // symbol console.log(typeof function fn() { }); // function console.log(typeof typeof []); //=>"string" console.log(typeof null); // object console.log(typeof {}); // object console.log(typeof new RegExp(/A/)); // object console.log(typeof []); // object"
- 局限性:
- 只能区分 基本数据类型,不能判断 引用数据类型;
- 不能区分 null 和 引用数据类型;
第二种:Object.prototype.toString
Symbol.toStringTag 是一个内置 symbol 类型的值,它通常作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型标签;
通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里;
-
检测数据类型
({}).toString.call(250) // "[object Number]" ({}).toString.call(true) // "[object Boolean]" ({}).toString.call('') // "[object String]" ({}).toString.call([]) // "[object Array]" ({}).toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]" Object.prototype.toString.call({}) // "[object Object]" Object.prototype.toString.call(/^.$/) // "[object RegExp]" Object.prototype.toString.call(() => { }) // "[object Function]"
-
局限性:
- 只能检测出是 object 类型,不能细分是谁的实例 (可利用 Symbol.toStringTag 做一些特殊处理实现检测自定义类型);
JavaScriptJavaScript
// 不能校验自定义类型 class Cat { } let cat = new Cat(); console.log(Object.prototype.toString.call(cat)); // [object Object]
class Cat { } let cat = new Cat(); Object.defineProperty(cat, Symbol.toStringTag, { value: '猫' }); // [object 猫] console.log(Object.prototype.toString.call(cat));
- 只能检测出是 object 类型,不能细分是谁的实例 (可利用 Symbol.toStringTag 做一些特殊处理实现检测自定义类型);
第三种:instanceof
-
检测某个实例是否属于这个类,所有出现在其原型链上的类,检测结果都是 true;
console.log(12 instanceof Number); // false console.log(new Number(12) instanceof Number); // true console.log([] instanceof Array); // true console.log([] instanceof Object); // true
-
局限性:
- 基本数据类型的值,连对象都不是,更没有 __proto__ ,虽说也是所属类的实例,在 JS 中也可以调取所属类原型上的方法,但是 instanceof 是不认的;
- 由于可以基于 __proto__ 或者 prototype 改动原型链的动向,所以基于 instanceof 检测出来的结果并不一定是准确的;
function Fn() { } let f = new Fn(); console.log(f instanceof Array); // false //原型链:f -> Fn.prototype -> Object.prototype Fn.prototype.__proto__ = Array.prototype; // 改变原型指向 //原型链:f -> Fn.prototype -> Array.prototype -> Object.prototype console.log(f instanceof Array); // true
第四种:constructor
-
在类的原型上一般都会带有 constructor 属性,存储当前类本身,也是利用这一点,获取实例的 constructor 属性值,验证是否为所属的类,从而进行数据类型检测;
console.log(12.constructor === Number); // true
-
局限:
- constructor 属性值太容易被修改;
- 除了 null 和 undefined ,constructor 可以正确检测出原始类型和对象类型;
面试题
实现 instanceof 关键字
function _instanceof(A, B) {
while (B.prototype) {
if (A.__proto__ == B.prototype) {
return true
} else {
B = B.prototype
}
}
return false
}
console.log(_instanceof('a', String)); // true
第 2️⃣ 座大山:this 的五种情况
上一篇