1. var getProto = Object.getPrototypeOf; //用来获取当前某一个对象的原型
    2. var class2type = {};
    3. var toString = class2type.toString; //Object.prototype.toString
    4. var hasOwn = class2type.hasOwnProperty; //Object.prototype.hasOwnProperty
    5. var fnToString = hasOwn.toString; //函数.toString=>Function.prototype.toString
    6. var ObjectFunctionString = fnToString.call(Object); //=>Function.prototype.toString 执行,把方法中的this更改为Object [相当于]=>Object.toString() => "function Object() { [native code] }"
    7. // 检测是否是一个函数
    8. var isFunction = function isFunction(obj) {
    9. return typeof obj === "function" && typeof obj.nodeType !== "number" &&
    10. typeof obj.item !== "function";
    11. };
    12. // 检测是否是一个window对象
    13. var isWindow = function isWindow(obj) {
    14. // window.window===window 实现了套娃操作
    15. return obj != null && obj === obj.window;
    16. };
    17. // 标准的检测数据类型的办法
    18. /* var arr = ["Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Object", "Error", "Symbol"];
    19. arr.forEach(function (name) {
    20. class2type["[object " + name + "]"] = name.toLowerCase();
    21. });
    22. var toType = function toType(obj) {
    23. if (obj == null) return obj + "";
    24. //null和undefined 直接拼接成 字符串
    25. return typeof obj === "object" || typeof obj === "function" ?
    26. class2type[toString.call(obj)] || "object" :
    27. typeof obj;
    28. }; */
    29. //正则优化
    30. var toType = function toType(obj) {
    31. if (obj == null) return obj + "";
    32. var reg = /^\[object ([a-zA-Z0-9]+)\]$/i;
    33. return typeof obj === "object" || typeof obj === "function" ?
    34. reg.exec(toString.call(obj))[1].toLowerCase() :
    35. typeof obj;
    36. };
    37. // 检测是否为数组或者类数组
    38. var isArrayLike = function isArrayLike(obj) {
    39. var length = !!obj && "length" in obj && obj.length,
    40. type = toType(obj);
    41. if (isFunction(obj) || isWindow(obj)) return false;
    42. return type === "array" || length === 0 ||
    43. typeof length === "number" && length > 0 && (length - 1) in obj;
    44. };
    45. // 检测是否为纯粹的对象「直属类是Object || Object.create(null)」
    46. var isPlainObject = function isPlainObject(obj) {
    47. var proto, Ctor;
    48. if (!obj || toString.call(obj) !== "[object Object]") return false;
    49. proto = getProto(obj);
    50. if (!proto) return true;
    51. Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
    52. return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
    53. };
    54. // 检测是否是空对象
    55. var isEmptyObject = function isEmptyObject(obj) {
    56. var keys = Object.keys(obj);
    57. if (typeof Symbol !== "undefined") keys = keys.concat(Object.getOwnPropertySymbols(obj));
    58. return keys.length === 0;
    59. };
    60. // 检测是否是数字
    61. var isNumeric = function isNumeric(obj) {
    62. var type = toType(obj);
    63. return (type === "number" || type === "string") && !isNaN(obj);
    64. };