在 js 中, 有四种用于检测数据类型的方式, 分别是:
typeof 用来检测数据类型的运算符
instanceof 检测一个实例是否属于某个类
constructor 构造函数
Object.prototype.toString.call() 原型链上的 Object 对象的 toString 方法
下面我们就来分别介绍一下上面四种方法的适用场景和局限性.
typeof 用来检测数据类型的运算符
使用 typeof 检测数据类型, 返回值是字符串格式. 能够返回的数据类型
是:"number","string","bolean","undefined","function","object".
<script>
console.log(typeof(1)); //number
console.log(typeof('hello')); //string
console.log(typeof(true)); //boolean
console.log(typeof(undefined)); //undefined
console.log(typeof(null)); //object
console.log(typeof({})); //object
console.log(typeof(function() {})); //function
</script>
局限性:
typeof (null); //"object". 这是由于在 js 中, null 值表示一个空对象指针, 而这也正是使用 typeof 操作 符检测 null 值时会返回 "object" 的原因.
不能具体的细分是数组还是正则, 还是对象中其他的值, 因为使用 typeof 检测数据类型, 对于对象数据类型的所有的值, 最后返回的都是 "object"
instanceof 检测某一个实例是否属于某个类
instanceof 主要用来弥补 typeof 不能检测具体属于哪个对象的局限性.
<script>
let arr = [1,2,3];
let reg = /\w/;
console.log(arr instanceof Array); //true
console.log(arr instanceof Object); //true
console.log(reg instanceof RegExp); //true
console.log(reg instanceof Object); //true
</script>
局限性:
不能用于检测和处理字面量方式创建出来的基本数据类型值, 即原始数据类型
instanceof 的特性: 只要在当前实例的原型链上的对象, 我们用其检测出来都为 true
在类的原型继承中, 我们最后检测出来的结果未必正确
constructor 构造函数
是函数原型上的属性, 该属性指向的是构造函数本身.
作用和 instsnceof 非常相似, 与 instanceof 不同的是, 不仅可以处理引用数据类型, 还可以处理原始数据类型.
<script>
let num = 12;
let obj = {};
console.log(num.constructor == Number);//true
console.log(obj.constructor == Object);//true
</script>
但是要注意一点的是, 当直接用(对象字面量或原始数据).constructor 时, 最好加上(). 为了便于理解, 我们来看一个例子.
<script>
1.constructor === Number; // 报错, Invalid or unexceped token
(1).constructor === Number; //true
{}.constructor === Number; // 报错, Invalid or unexceped token
({}).constructor === Number; //true
</script>
这主要是由于 js 内部解析方式造成的, js 会把 1.constructor 解析成小数, 这显然是不合理的, 小数点后应该是数字, 因此就会引发报错. js 会把 {} 解析成语句块来执行, 这时后面出现一个小数点显然也是不合理的, 因此也会报错. 为了解决这个问题, 我们可以为表达式加上 () 使 js 能够正确解析.
局限性: 我们可以把类的原型进行重写, 在重写的过程中很可能把之前 constructor 给覆盖了, 这样检测出来的结果就是不准确的
<script>
function Fn() {};
Fn.prototype = new Array;
var f = new Fn;
//f 是一个函数, 按道理说他的构造函数应该是 Function, 但是修改其原型链后, 它的 constructor 变成了 Array.
console.log(f.constructor == Array); //true
</script>
Object.prototype.toString.call() 原型链上的 Object 对象的 toString 方法
Object.prototype.toString 的作用是返回当前方法的执行主体 (方法中的 this) 所属类的详细信息, 是最全面也是最常用的检测数据类型的方式.
返回值的类型为 string 类型.
<script>
console.log(Object.prototype.toString.call(1)); //[object Number]
console.log(Object.prototype.toString.call(/^sf/)); //[object RegExp]
console.log(Object.prototype.toString.call("hello")); //[object String]
console.log(Object.prototype.toString.call(true)); //[object Boolean]
console.log(Object.prototype.toString.call(null)); //[object Null]
console.log(Object.prototype.toString.call(undefined)); //[object Undefined]
console.log(Object.prototype.toString.call(function() {})); //[object Function]
console.log(typeof(Object.prototype.toString.call(function() {}))); //string
</script>
来源: http://www.jb51.net/article/145078.htm