判断数据类型


/**
 * 判断一个 变量 的类型,是 数组、字符串、还是对象或者函数等复杂类型。
 */

//  首先声明一些变量
const str = "string",
  num = 12,
  isBool = true,
  isUndefined = undefined,
  isNull = null,
  obj = { name: "tom" },
  arr = [1],
  fun = () => {};

/**
 * 先看最简单的 typeof 方法
 */

console.log(typeof str);
console.log(typeof num);
console.log(typeof isBool);
console.log(typeof isUndefined);
console.log(typeof isNull);
console.log(typeof obj);
console.log(typeof arr);
console.log(typeof fun);

/**
 * 输出:string
 * number
 * boolean
 * undefined
 * object
 * object
 * object
 * function
 *
 * typeof 能判断简单类型的变量,但是对于引用类型的数组,对象等却无法区别
 * 都会识别为 object
 *
 */

/**
 * 使用 instanceof 方法
 */

console.log(str instanceof String); // false
console.log(num instanceof Number); // false
console.log(isBool instanceof Boolean); // false
// console.log(isUndefined instanceof undefined); // 报错
// console.log(isNull instanceof null); // 报错
console.log(obj instanceof Object); // true
console.log(arr instanceof Object); // true
console.log(arr instanceof Array); // true
console.log(fun instanceof Object); // true
console.log(fun instanceof Function); // true

/**
 * 从上面结果可以看出:
 *  对于简单类型的字面量声明,使用 instanceof 方法无法判断类型
 *  对于复杂类型 instanceof 方法对于 Object 都会返回true,因为 数组,函数本质来说都是对象。
 * instanceof 方法的作用是:检测构造函数的 prototype 属性是否出现在某个实例对象的原型链。
 * 即,fun instanceof Object 说明 fun 在 Object 的原型链上。并不是一个对象。
 * arr, fun 都会沿着原型链找到 Object 所以,也会返回true,使用时要注意。
 */

let str1 = new String("12");
console.log(`这是一个字符串:${str1}`); // 这是一个字符串:12
console.log(typeof str1); // object
console.log(str1 instanceof String); // true
/**
 * 此时 str1 能沿着原型链找到 String
 */

/**
 * 使用 原型方法 进行判断
 */

console.log(Object.prototype.toString.call(str)); // [object String]
console.log(Object.prototype.toString.call(num)); // [object String]
console.log(Object.prototype.toString.call(isBool)); //
console.log(Object.prototype.toString.call(isUndefined)); //
console.log(Object.prototype.toString.call(isNull)); //
console.log(Object.prototype.toString.call(obj)); //
console.log(Object.prototype.toString.call(arr)); //
console.log(Object.prototype.toString.call(fun)); //
/**
 * [object String]
 * [object Number]
 * [object Boolean]
 * [object Undefined]
 * [object Null]
 * [object Object]
 * [object Array]
 * [object Function]
 *
 * 利用原型上的方法可以正确的判断出元素类型
 *
 */

/**
 * 上述三种方法的优劣:
 *    Array.isArray 优于 instanceof, 因为Array.isArray能检测iframes。
 *
 *    Objec.prototype.toString.call() 对于所有的基本数据类型都能进行判断,包括 undefined 、null。常用于判断浏览器内置对象。
 *
 *    instanceof  的内部机制是通过判断对象的原型链中是不是能找到类型的 prototype。
 *    使用 instanceof判断一个对象是否为数组,instanceof 会判断这个对象的原型链上是否会找到对应的 Array 的原型,找到返回 true,否则返回 false。
 *    instanceof 只能用来判断对象类型,原始类型不可以。并且所有对象类型 instanceof Object 都是 true
 *
 *    Array.isArray()是ES5新增的方法,当不存在 Array.isArray()
 *    可以用 Object.prototype.toString.call() 实现。如下例子:
 */

if (!Array.isArray) {
  Array.isArray = function (arg) {
    return Object.prototype.toString.call(arg) == "[object Array]";
  };
}

// Array.isArray 的性能最好,instanceof 比 toString.call 稍微好了一点点。

原文地址:https://www.cnblogs.com/xguoz/p/13827159.html