core/get.js

  1. import {
  2. index,
  3. prop,
  4. } from 'path/consts'
  5. import { isNil } from 'util/lang'
  6. import { toPath } from 'path/toPath'
  7. /**
  8. * Gets the value at <code>path</code> of <code>obj</code>.
  9. * @memberof core
  10. * @param {*} obj The object.
  11. * @param {string|Array} path The path of the property to get.
  12. * @param {*} defaultValue The default value.
  13. * @return {*} Returns the value or <code>defaultValue</code>.
  14. * @example get({ nested: { prop: 'val' } }, 'nested.prop') // => 'val'
  15. * @example get({ nested: { prop: 'val' } }, 'nested.unknown', 'default') // => 'default'
  16. * @since 1.0.0
  17. */
  18. function get(obj, path, defaultValue) {
  19. function walkPath(curObj, remPath) {
  20. if (remPath.length === 0) return curObj === undefined ? defaultValue : curObj
  21. if (isNil(curObj)) return defaultValue
  22. const [[, prop], ...pathRest] = remPath
  23. return walkPath(curObj[prop], pathRest)
  24. }
  25. const parsedPath = toPath(path)
  26. if (parsedPath.some(([propType]) => propType !== prop && propType !== index))
  27. throw TypeError('get supports only properties and array indexes in path')
  28. return walkPath(obj, parsedPath)
  29. }
  30. export { get }