# result

# Description

这个方法类似 get, 除了如果解析到的值是一个函数的话,就绑定 this 到这个函数并返回执行后的结果。

# Params

(object, path, defaultValue)

# Return

{*}

# Depend

import castPath from './.internal/castPath.js'
import toKey from './.internal/toKey.js'

castPath 源码分析

toKey 源码分析

# Code

function result(object, path, defaultValue) {
  path = castPath(path, object)

  let index = -1
  let length = path.length

  // Ensure the loop is entered when path is empty.
  if (!length) {
    length = 1
    object = undefined
  }
  while (++index < length) {
    let value = object == null ? undefined : object[toKey(path[index])]
    if (value === undefined) {
      index = length
      value = defaultValue
    }
    object = typeof value === 'function' ? value.call(object) : value
  }
  return object
}

# Analyze

  1. 通过 castPath 将 path 转为路径数组

  2. 处理路径数组为空的情况

      if (!length) {
        length = 1
        object = undefined
      }
    

    length 置为 1, 将 object 置为 undefined,这里这么处理是为了在 while 循环中处理 defaultValue 的情况

  3. while 循环遍历

      while (++index < length) {
        let value = object == null ? undefined : object[toKey(path[index])]
        if (value === undefined) {
          index = length
          value = defaultValue
        }
        object = typeof value === 'function' ? value.call(object) : value
      }
    

    objectnull 或者 undefined 的情况下, value 就为 undefined ,否则的话 取出当前 path 对应的值

    判断 如果 valueundefined,则将 length 赋值给 index ,也就是结束循环,将 defaultValue 的值赋值给 value

    最后会判断,如果 value 是一个 方法,则调用这个方法,将返回的值 赋值给 object ,否则将当前的 value 赋值给 object

  4. 最后 返回 object

# Example

const obj = {
  a: {
    b: {
      c: () => 'Empty'
    }
  }
}

console.log(result(obj, 'a.b.c')) // Empty
console.log(result(obj, 'a.c', 'default')) // default