js中,根据存储的方式不一样(参见文末链接), 数据能够划分为如下两大类型:数组
string, number, boolean, undefined, null, symbol函数
Object (Array, Function, RegExp, Date)post
判断数据的所属类型此处列举四种方法,并对每种方法使用的范围以及限制进行说明.若是对原型链还不熟悉的同窗,请先阅读相关的原型链知识(见文末)ui
typeof
通常仅用于判断原始类型(不包含null),返回值为该类型的字符串this
console.log(typeof 'str'); // string
console.log(typeof 1); // number
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof Symbol()); // symbol
复制代码
注意:
typeof
不能用于判断原始类型中的null
以及引用类型object
,结果都会返回字符串object(Function
类型除外,结果会返回function,但在在 IE 6, 7 和 8 上则返回object)spa
console.log(typeof null); // object
console.log(typeof {}); // object
console.log(typeof alert); // function
console.log(typeof []); // object
console.log(typeof new RegExp()); // object
console.log(typeof new Date()); // object
复制代码
constructor
主要是利用原型上的prototype.constructor
指向实例的构造函数来进行判断的prototype
先定义一个构造函数Animal
, 并new
一个实例dog
3d
const Animal = function (name) {this.name = name}; // 声明一个构造函数
let dog = new Animal('dog'); // 生成实例dog
复制代码
声明Animal
函数的同时js会在Animal
上挂载一个prototype
对象,同时在prototype
对象上会自动生成一个constructor
属性并指向构造函数Animal
,至关于:
Animal.prototype.constructor === Animal // true
,根据原型链的查找原则, console(dog.prototype) // Animal
因此利用构造函数原型上的constructor
属性能够判断当前实例是否为当前构造函数的实例,进而肯定数据所属类型:code
console.log('1'.constructor === String); // true
console.log(new Number(1).constructor === Number); // true
console.log(true.constructor === Boolean); // true
console.log(alert.constructor === Function); // true
console.log([].constructor === Array); // true
console.log(new Date().constructor === Date); // true
复制代码
注意:对象
null
,undefined
是无效的对象,所以是不会有constructor
存在的,这两种类型的数据须要经过其余方式来判断。- 函数的 constructor 是不稳定的,这个主要体如今自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
用 constructor
判断类型的限制过多且不许确,容易出错,少用,或者不用!
与 typeof
和 constructor
不一样, instanceof
通常用于判断引用类型,返回值为布尔值, 例如:
[] instanceof Array // true
instanceof
是经过判断当前实例的原型与构造函数的原型是否为同一对象,进而肯定当前数据的类型,这样讲或许不够明了,咱们简单实现一下 instanceof
const self_instanceof = function (instance, constructor) {
let instance_proto = instance.__proto__;
let constructor_proto = constructor.prototype;
while(true) {
// 找到终点返回false
if (instance_proto === null) {return false};
// 找到返回true
if (instance_proto === constructor_proto) {return true};
// 当实例与构造函数原型不相同, 沿着原型链继续向上查找
instance_proto = instance_proto.__proto__;
}
}
console.log([] instanceof Array) // true
console.log(self_instanceof([], Array)) // true
复制代码
当一个页面存在多个
iframe
时,也就是存在多个全局变量window
,instanceof
的判断会被来自不一样的iframe的数据所干扰,致使不可信
假设:页面pageA
经过iframe
内嵌了页面pageB
, 此时pageB
传递了一个数组 let arrB = []
到页面 pageA
, 若在pageA
使用instanceof
判断数组arrB
会出现 arrB instanceof Array // false
主要缘由是由于 arrB
是由pageB
上的Array
构造出来的
要避免这种问题可使用Es6
提供的数组静态方法 Array.isArray
, 或者咱们即将提到的toString
方法进行判断
Array.isArray(arrB) // true
toString
是Object.prototype
上的一个方法, 经常使用方式为 Object.prototype.toString.call(target)
返回值是 [object 类型]
字符串,该方法基本上能判断全部的数据类型(自定义数据类型除外)
// 定义判断类型函数
let getType = target => Object.prototype.toString.call(target)
console.log(getType('')); // [object String]
console.log(getType(2)); // [object Number]
console.log(getType(true)); // [object Boolean]
console.log(getType(undefined)); // [object Undefined]
console.log(getType(null)); // [object Null]
console.log(getType(Symbol())); // [object Symbol]
console.log(getType({})); // [object Object]
console.log(getType([])); // [object Array]
console.log(getType(alert)); // [object Function]
console.log(getType(new RegExp())); // [object RegExp]
console.log(getType(new Date())); // [object Date]
复制代码
该方法准确稳定,推荐使用
以上为类型判断的一些看法, 有不当之处, 还请大佬们指正!
相关知识点文章请参考: