index.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * @Author: Rindy
  3. * @Date: 2021-09-03 11:53:21
  4. * @LastEditors: Rindy
  5. * @LastEditTime: 2021-09-03 15:14:25
  6. * @Description:
  7. */
  8. export const objectToString = Object.prototype.toString
  9. export const toTypeString = value => objectToString.call(value)
  10. // 获取制定对象的类型比如toRawType(1) Number
  11. export const toRawType = value => toTypeString(value).slice(8, -1)
  12. /**
  13. * 判断是否函数
  14. * @param {any} target 参数对象
  15. */
  16. export const isFunction = target => toRawType(target) === 'Function'
  17. /**
  18. * 判断是否普通对象
  19. * @param {any} target 参数对象
  20. */
  21. export function isPlainObject(target) {
  22. if (!target || typeof target !== 'object' || {}.toString.call(target) != '[object Object]') {
  23. return false
  24. }
  25. var proto = Object.getPrototypeOf(target)
  26. if (proto === null) {
  27. return true
  28. }
  29. var Ctor = {}.hasOwnProperty.call(proto, 'constructor') && proto.constructor
  30. return typeof Ctor == 'function' && Ctor instanceof Ctor && Function.prototype.toString.call(Ctor) === Function.prototype.toString.call(Object)
  31. }
  32. /**
  33. * 获取忽略指定属性的对象
  34. * @param {Object} obj 源对象
  35. * @param {...any} props 忽略属性
  36. */
  37. export function omit(obj, ...props) {
  38. const result = { ...obj }
  39. props.forEach(function (prop) {
  40. delete result[prop]
  41. })
  42. return result
  43. }
  44. export const randomId = (e = 6) => {
  45. var t = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678',
  46. a = t.length,
  47. n = ''
  48. for (let i = 0; i < e; i++) {
  49. n += t.charAt(Math.floor(Math.random() * a))
  50. }
  51. return n
  52. }
  53. /**
  54. * 缓存指定方法运行结果
  55. * @param {*} fn
  56. * @param {*} overdue 缓存超时时间
  57. * @returns
  58. */
  59. export const cache = (fn, overdue) => {
  60. const cacheMap = new WeakMap()
  61. return function (...args) {
  62. let caches = cacheMap.get(fn)
  63. if (!caches) {
  64. caches = []
  65. cacheMap.set(fn, caches)
  66. }
  67. for (let i = 0; i < caches.length; i++) {
  68. const { oldNow, ret, oldArgs } = caches[i]
  69. if (oldArgs.length === args.length && args.every((arg, i) => arg === oldArgs[i])) {
  70. if (Date.now() - oldNow > overdue) {
  71. caches.splice(i, 1)
  72. break
  73. } else {
  74. return ret
  75. }
  76. }
  77. }
  78. const item = {
  79. oldNow: Date.now(),
  80. ret: fn.apply(this, args),
  81. oldArgs: args,
  82. }
  83. caches.push(item)
  84. setTimeout(() => {
  85. const index = caches.indexOf(item)
  86. if (~index) {
  87. caches.splice(index, 1)
  88. }
  89. })
  90. return item.ret
  91. }
  92. }
  93. // 是否修改
  94. const _inRevise = (raw1, raw2, readly) => {
  95. if (raw1 === raw2) return false
  96. const rawType1 = toRawType(raw1)
  97. const rawType2 = toRawType(raw2)
  98. if (rawType1 !== rawType2) {
  99. return true
  100. } else if (rawType1 === 'String' || rawType1 === 'Number' || rawType1 === 'Boolean') {
  101. return raw1 !== raw2
  102. }
  103. const rawsArray = Array.from(readly.values())
  104. for (const raws of rawsArray) {
  105. if (raws.includes(raw1) && raws.includes(raw2)) {
  106. return false
  107. }
  108. }
  109. readly.add([raw1, raw2])
  110. if (rawType1 === 'Array') {
  111. return raw1.length !== raw2.length || raw1.some((item1, i) => _inRevise(item1, raw2[i], readly))
  112. } else if (rawType1 === 'Object') {
  113. const rawKeys1 = Object.keys(raw1).sort()
  114. const rawKeys2 = Object.keys(raw2).sort()
  115. return _inRevise(rawKeys1, rawKeys2, readly) || rawKeys1.some(key => _inRevise(raw1[key], raw2[key], readly))
  116. } else if (rawType1 === 'Map') {
  117. const rawKeys1 = Array.from(raw1.keys()).sort()
  118. const rawKeys2 = Array.from(raw2.keys()).sort()
  119. return _inRevise(rawKeys1, rawKeys2, readly) || rawKeys1.some(key => _inRevise(raw1.get(key), raw2.get(key), readly))
  120. } else if (rawType1 === 'Set') {
  121. return inRevise(Array.from(raw1.values()), Array.from(raw2.values()))
  122. } else {
  123. return raw1 !== raw2
  124. }
  125. }
  126. export const os = (function () {
  127. let ua = navigator.userAgent,
  128. isWindowsPhone = /(?:Windows Phone)/.test(ua),
  129. isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
  130. isAndroid = /(?:Android)/.test(ua),
  131. isFireFox = /(?:Firefox)/.test(ua),
  132. isChrome = /(?:Chrome|CriOS)/.test(ua),
  133. isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)),
  134. isPhone = /(?:iPhone)/.test(ua) && !isTablet,
  135. isPc = !isPhone && !isAndroid && !isSymbian
  136. if (isPc && navigator.maxTouchPoints > 1) {
  137. isTablet = true
  138. }
  139. return {
  140. isTablet: isTablet,
  141. isPhone: isPhone,
  142. isAndroid: isAndroid,
  143. isPc: isPc,
  144. }
  145. })()
  146. export const inRevise = (raw1, raw2) => _inRevise(raw1, raw2, new Set())
  147. export * from './dom'
  148. export * from './zindex'
  149. export * from './vm'