【面试】知识点--类型判断

220 阅读2分钟

1. typeof

可以判断8种数据类型:

  • 基本类型6个 undefined null boolean, number, string、symbol
  • 引用类型2个 object、function

注意点:

  1. typeof null // 'object': 不能用typeof判断null,得用===判断
  2. typeof [] // 'object': 不能判断出来array和object,因为都是object
  3. typeof (() => {}) // 'function': 可以判断出来function

为什么这样设计,是不是js语言的糟粕,但是我们写代码的时候要注意这些,不然容易出bug。如果要判断Object类型的具体类型的话,就需要用Object.prototype.toString

2. Object.prototype.toString

判断方法Object.prototype.toString.call(xxx), 返回格式是[object xxx],xxx就是具体类型,可以取出来。

注意不能用obj.toString() 这个是类型转换为字符串的方法,都重写了这个方法,例如function类型返回函数体的字符串,array类型返回元素组成的字符串。所以判断类型需要调用Object原型链上的方法,并且要call调用。

var number = 1;
var string = '';
var boolean = true;
var und = undefined;
var nu = null;
var sym = Symbol('a');
var obj = {a: 1};
var array = [1, 2, 3];
var date = new Date();
var error = new Error();
var reg = /a/g;
var func = function a() {};

function checkType() {
    for (var i = 0; i < arguments.length; i++) {
        console.log(Object.prototype.toString.call(arguments[i]));
    }
}
checkType(number, string, boolean, und, nu, sym, obj, array, date, error, reg, func);

结果:

image.png

可以结合以上两个写类型判断函数,如果是object就用Object.prototype.toString方法,否则用typeof。

function getToStringType(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
/**
 * object、function用toString,其余用typeof
 * @param {} obj 
 */
function type(obj) {
    return typeof obj === 'object' || typeof obj === 'function' ?
        getToStringType(obj) || 'object' : typeof obj;
}

// 判断函数
function isFunction(obj) {
    return type(obj) === 'function';
}

function isArray(obj) {
    return type(obj) === 'array'
}

3. instanceof

判断引用类型,a instanceof B 是判断右侧函数的原型对象是否在左侧对象的原型链上,如果是返回true。

function myInstanceof(left, right) {
    let leftProto = getPrototypeOf(left);
    const rightPrototype = right.prototype;
    while (leftProto) {
        if (leftProto === rightPrototype) {
            return true;
        }
        leftProto = getPrototypeOf(leftProto)
    }
    return false;
}

4. 判断数组的方式有哪些?

  • Array.isArray()
  • obj instanceof Array
  • getToStringType(obj) === 'array'
  • obj.proto === Array.prototype

5. null与undefined

  • null:空对象;
  • undefined: 为定义 image.png

看见这个结果就想maniang。

isNaN 与 Number.isNaN

  • isNaN: 会尝试将参数转换为数值,任何不能转化为数值的值都会返回true,即非数字值传入也会返回true,有问题
  • Number.isNaN: 会先判断是否是数字,如果是数字再判断是否是NaN,不会进行类型判断,所以对于NaN判断更准确。
[1, 2, 3, 4].map(parseInt);
// 1 NaN NaN NaN
parseInt传入0或者不传,按照字符串转为10进制