前言
js中数据类型判断,简单点数字或字符串判断,复杂点就是数组和对象,更深的判断对象、空对象、日期、错误类型、正则、window对象等。
1、typeof,基础类型的判断
var obj = new Object();
var fun = function a(){};
typeof null //object
typeof obj //object
typeof fun // function
一共有七种数据类型有:Undefined、Null、Boolean、Number、String、Symbol、Object。
typeof用于检测数据的基本类型,不能判断引用类型和null
2、instanceof
instanceof用于检测引用类型的值,知道是什么类型的对象,不能判断基本类型
1 instanceof Object //false
3、Object.prototype.toString
调用 Object.prototype.toString 会返回一个由 "[object " 和 class 和 "]" 组成的字符串,而 class 是要判断的对象的内部属性。
Object.prototype.toString.call(undefined) //[object Undefined]
Object.prototype.toString.call(Math); // [object Math]
Object.prototype.toString.call(JSON); // [object JSON]
var number = 1; // [object Number]
var string = '123'; // [object String]
var boolean = true; // [object Boolean]
var und = undefined; // [object Undefined]
var nul = null; // [object Null]
var obj = {a: 1} // [object Object]
var array = [1, 2, 3]; // [object Array]
var date = new Date(); // [object Date]
var error = new Error(); // [object Error]
var reg = /a/g; // [object RegExp]
var func = function a(){}; // [object Function]
封装一个判断类型,在 IE6 中,null 和 undefined 会被 Object.prototype.toString 识别成 [object Object]!
function type(v) {
if(v == null){
return v + '';
}
return typeof v === 'object' || typeof v === 'function' ?
Object.prototype.toString.call(v)
.replace('[object ', '')
.replace(']', '')
.toLowerCase() : typeof v;
}
type([]) === 'array'
function isArray(v){
return type(v) === "array";
}
function isFunction(v) {
return type(v) === "function";
}
plainObject
function isPlainObject(v) {
var proto,
constructor,
hasOwn = Object.prototype.hasOwnProperty;
if(type(v) !== 'object'){
return false;
}
proto = Object.getPrototypeOf(v);
if(!proto){
return true;
}
constructor = hasOwn.call(proto, 'constructor')
&& proto.constructor;
return typeof constructor === 'function'
&& hasOwn.toString.call(constructor) === hasOwn.toString.call(Object)
}
hasOwn.toString 调用的其实是 Function.prototype.toString,毕竟 hasOwnProperty 可是一个函数。函数的 toString 方法会返回一个表示函数源代码的字符串。具体来说,包括 function关键字,形参列表,大括号,以及函数体中的内容。
console.log(Function.prototype.toString.call(Object)); // function Object() { [native code] }
针对自定义的类,type函数返回object,为了区分函数创建的实例。(注:这个其实可以根据业务看看是否要那么严格判断)
function Person(name) {
this.name = name;
}
type(new Person('li')); //object
isPlainObject(new Person('li')) //false
isPlainObject(Object.create({})) //false
isPlainObject(Object.create(null)) //true
isPlainObject({}) //true
isEmptyObject
function isEmptyObject (v) {
if(!isPlainObject(v)){
return false;
}
for (let name in obj) {
return false;
}
return true;
}
isWindow
function isWindow(v){
return v != null && v.window === v
}
isElement
function isElement(v){
return !!(v && v.nodeType === 1);
}
两次取反保证返回值是布尔值
isArrayLike
1、是数组
2、长度为 0(注:arguments长度为0的情况)
3、length 属性是大于 0 的数字类型,并且obj[length - 1]必须存在(注:这一条可以根据业务是否放宽)
满足其一
function isArrayLike(v){
var lenght = !!v && 'length' in v && v.lenght;
var typeRes = type(v);
// 排除掉函数和 Window 对象
if (typeRes === "function" || isWindow(obj)) {
return false;
}
return typeRes === 'array'
|| lenght === 0
|| typeof lenght === "number" && lenght > 0 && (lenght - 1) in v;
}