1. (function () {
    2. "use strict"
    3. const toString = Object.prototype.toString
    4. // 万能检测数据类型的办法「返回结果:"小写数据类型"」
    5. const toType = function toType(obj) {
    6. if (obj === null) return "null"
    7. let type = typeof obj,
    8. reg = /^\[object (\w+)\]$/
    9. if (/^(object|function)$/.test(type)) {
    10. // 检测的值是对象
    11. type = toString.call(obj)
    12. return reg.exec(type)[1].toLowerCase()
    13. }
    14. // 检测的值是原始值
    15. return type
    16. }
    17. // 笼统校验是否为对象
    18. const isObject = function isObject(obj) {
    19. return obj !== null && /^(object|function)$/.test(typeof obj)
    20. }
    21. // 检测是否为纯粹的对象「标准普通对象」
    22. const isPlainObject = function isPlainObject(obj) {
    23. if (obj == null) return false
    24. if (toString.call(obj) !== '[object Object]') return false
    25. // 考虑 Object.create(null) 这种情况
    26. let proto = Object.getPrototypeOf(obj)
    27. if (!proto) return true
    28. // 剩下的就看其 constructor 是不是 Object
    29. let ctor = proto.hasOwnProperty('constructor') && obj.constructor
    30. return typeof ctor === 'function' && ctor instanceof ctor && ctor === Object
    31. }
    32. // 检测是否为函数
    33. const isFunction = function isFunction(obj) {
    34. return typeof obj === 'function'
    35. }
    36. // 检测是否为window
    37. const isWindow = function isWindow(obj) {
    38. return obj != null && obj === obj.window
    39. }
    40. // 检测是否为数组或者伪数组
    41. const isArrayLike = function isArrayLike(obj) {
    42. let length = !!obj && "length" in obj && obj.length,
    43. type = toType(obj)
    44. if (isFunction(obj) || isWindow(obj)) return false
    45. return type === "array" || length === 0 ||
    46. typeof length === "number" && length > 0 && (length - 1) in obj
    47. }
    48. // 获取对象所有私有成员「兼容到IE、不受枚举和类型的限制」
    49. const ownKeys = function ownKeys(obj) {
    50. if (!isObject(obj)) throw new TypeError('传递的obj不是一个对象')
    51. let keys = Object.getOwnPropertyNames(obj)
    52. if (typeof Symbol !== 'undefined') {
    53. keys = keys.concat(Object.getOwnPropertySymbols(obj))
    54. }
    55. return keys
    56. }
    57. // 给对象新增一个“不可枚举”的成员
    58. const def = function def(obj, key, value) {
    59. Object.defineProperty(obj, key, {
    60. value,
    61. writable: true,
    62. configurable: true,
    63. enumerable: false
    64. })
    65. }
    66. //延迟函数
    67. const delay = function delay(interval = 1000) {
    68. return new Promise((resolve) => {
    69. setTimeout(() => {
    70. resolve()
    71. }, interval)
    72. })
    73. }
    74. /* 暴露API */
    75. const utils = {
    76. toType,
    77. isFunction,
    78. isWindow,
    79. isObject,
    80. isPlainObject,
    81. isArrayLike,
    82. ownKeys,
    83. def,
    84. delay
    85. }
    86. if (typeof define === "function" && define.amd) {
    87. define("utils", [], function () {
    88. return utils
    89. })
    90. }
    91. if (typeof module === 'object' && typeof module.exports === 'object') {
    92. module.exports = utils
    93. }
    94. if (typeof window !== 'undefined') {
    95. window.utils = window._ = utils
    96. }
    97. })()