index.js 5.0 KB

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