javascript之类型判断

201 阅读2分钟

前言

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;
}

参考:github.com/mqyqingfeng…