util.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /**
  2. * Get the first item that pass the test
  3. * by second argument function
  4. *
  5. * @param {Array} list
  6. * @param {Function} f
  7. * @return {*}
  8. */
  9. export function find (list, f) {
  10. return list.filter(f)[0]
  11. }
  12. /**
  13. * Deep copy the given object considering circular structure.
  14. * This function caches all nested objects and its copies.
  15. * If it detects circular structure, use cached copy to avoid infinite loop.
  16. *
  17. * @param {*} obj
  18. * @param {Array<Object>} cache
  19. * @return {*}
  20. */
  21. export function deepCopy (obj, cache = []) {
  22. // just return if obj is immutable value
  23. if (obj === null || typeof obj !== 'object') {
  24. return obj
  25. }
  26. // if obj is hit, it is in circular structure
  27. const hit = find(cache, c => c.original === obj)
  28. if (hit) {
  29. return hit.copy
  30. }
  31. const copy = Array.isArray(obj) ? [] : {}
  32. // put the copy into cache at first
  33. // because we want to refer it in recursive deepCopy
  34. cache.push({
  35. original: obj,
  36. copy
  37. })
  38. Object.keys(obj).forEach(key => {
  39. copy[key] = deepCopy(obj[key], cache)
  40. })
  41. return copy
  42. }
  43. /**
  44. * forEach for object
  45. */
  46. export function forEachValue (obj, fn) {
  47. Object.keys(obj).forEach(key => fn(obj[key], key))
  48. }
  49. export function isObject (obj) {
  50. return obj !== null && typeof obj === 'object'
  51. }
  52. export function isPromise (val) {
  53. return val && typeof val.then === 'function'
  54. }
  55. export function assert (condition, msg) {
  56. if (!condition) throw new Error(`[vuex] ${msg}`)
  57. }
  58. export function partial (fn, arg) {
  59. return function () {
  60. return fn(arg)
  61. }
  62. }