资讯专栏INFORMATION COLUMN

lodash的get方法

paraller / 2253人阅读

摘要:当然还要避免错误处理,返回相应的默认值。我们先不去看的方法,就能很轻易的判断它返回的应该是一个路径相关的数组。被检查的值被查询对象是否有对应的。

get这个方法,在lodash中是出场率很高的方法,初识起来有些疑惑,看了demo,又很直观。

get方法源码链接

下边是它的使用说明

 Gets the value at `path` of `object`. If the resolved value is
  `undefined`, the `defaultValue` is returned in its place.

根据object对象的path路径获取值。如果解析值是undefined,就返回一个默认的值(defaultValue)

 * var object = { "a": [{ "b": { "c": 3 } }] };
 *
 * _.get(object, "a[0].b.c");
 * // => 3
 *
 * _.get(object, ["a", "0", "b", "c"]);
 * // => 3
 *
 * _.get(object, "a.b.c", "default");
 * // => "default"

暂时不考虑第第三个参数,只考虑第二个参数,该参数的含义就是路径。 指向object的路径。

这个get方法事实上等同于我们取object上的某个属性的值。object["a"][0]["b"]["c"] 或者 object.a[0].b.c.

如果把复杂对象当成一个树来看,["a"][0]["b"]["c"]抑或是a[0].b.c都是树上的一个个树枝,树枝的终端可以另一个树枝,或者是一个具体的果实.

那该如何实现一个get方法呢。首先,第一个参数是具体的对象,第二个参数是一个路径,该路径我们当然会有一个约定俗成的格式,既足够直观理解,又便于我们格式化处理。当然还要避免错误处理,返回相应的默认值。

lodash的实现如下

function get(object, path, defaultValue) {
  var result = object == null ? undefined : baseGet(object, path);
  return result === undefined ? defaultValue : result;
}

export default get;

这里引入了一个baseGet。 get => baseGet

import castPath from "./_castPath.js";
import toKey from "./_toKey.js";


function baseGet(object, path) {
  path = castPath(path, object);

  var index = 0,
      length = path.length;

  while (object != null && index < length) {
    object = object[toKey(path[index++])];
  }
  return (index && index == length) ? object : undefined;
}

我们先不去看castPath的方法,就能很轻易的判断它返回的应该是一个路径相关的数组。

比如

// -var object = { "a": [{ "b": { "c": 3 } }] };
["a", "0", "b", "c"]
//

随着while遍历,object都会被重新赋值。最终取到我们目标的指

  return (index && index == length) ? object : undefined;

确认path中有确定想取的值。否则就是取不到值,undefined。

接下来我们可以考虑下castPath到底做了什么了。
/**
 * Casts `value` to a path array if it"s not one.
 * value如果不是数组,就将它转换成一个路径 数组。
 * @private
 * @param {*} value The value to inspect. 被检查的值
 * @param {Object} [object] The object to query keys on. 被查询对象是否有对应的key。
 * @returns {Array} Returns the cast property path array. 返回被转换的路径数组
 */

function castPath(value, object) {
  if (isArray(value)) {
    return value;
  }
  return isKey(value, object) ? [value] : stringToPath(toString(value));
}

isKey(value, object) 应该是用来判断value是object的key,如果是,那二话不说直接返回了。

换做是我,我要如何写这个isKey,可能我不会多带带写一个方法。

粗心点,我可能直接就写object[value]来判断了。

isKey比我们想的多的多。看看它是怎么写的

/** Used to match property names within property paths. */
var reIsDeepProp = /.|[(?:[^[]]*|([""])(?:(?!1)[^]|.)*?1)]/,
    reIsPlainProp = /^w*$/;
//reIsDeepProp 用来匹配属性名里包含路径属性  例如什么. [] 这种
/**
 * Checks if `value` is a property name and not a property path.
 * 检查value是一个属性名,不是属性路径
 * @private
 * @param {*} value The value to check. 被检查的值
 * @param {Object} [object] The object to query keys on.
 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
 */
function isKey(value, object) {
  if (isArray(value)) { // 数组,直接返回false
    return false;
  }
  var type = typeof value; // 对应的集中类型直接返回true,看到没,没有字符串,没有字符串。如果你考虑到
  if (type == "number" || type == "symbol" || type == "boolean" ||
      value == null || isSymbol(value)) {
    return true;
  }
  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
    (object != null && value in Object(object));
}

return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
    (object != null && value in Object(object));

先判断是字符串,而且不是那种包含.[]

value in Object(object))判断value是Object的key,返回一个bol

还剩下一个stringToPath

stringToPath(toString(value));

很显然,它的作用是将类似于"a[0]b.c"规则的字符串转换成数组路径["a", "0", "b", "c"]

var stringToPath = memoizeCapped(function(string) {
  var result = [];
  if (string.charCodeAt(0) === 46 /* . */) {
    result.push("");
  }
  //主要是下边这两行
  string.replace(rePropName, function(match, number, quote, subString) {
    result.push(quote ? subString.replace(reEscapeChar, "$1") : (number || match));
  });
  return result;
});

正则表达式的知识在自己补充吧。简单说就是匹配出我需要的 a,0,b,c.

至于memoize下一篇再说吧。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96066.html

相关文章

  • Webpack 最佳实践总结(三)

    摘要:这里要介绍的是工作流中的一种很普遍的代码加工流程正常的业务逻辑开发流程需要经过预处理器如或,然后再经过后处理器如进行深加工。 还未看的,可以点击查看上两篇文章哟:Webpack 最佳实践总结(一)、Webpack 最佳实践总结(二) 好了,这篇是第三篇,也是完结篇,我感觉这一篇是最乱的一篇,凑合着看吧,不会让你失望的 整合 CSS 加工流 有时候,前端项目中除了 JavaScript ...

    pkhope 评论0 收藏0
  • Webpack 最佳实践总结(三)

    摘要:这里要介绍的是工作流中的一种很普遍的代码加工流程正常的业务逻辑开发流程需要经过预处理器如或,然后再经过后处理器如进行深加工。 还未看的,可以点击查看上两篇文章哟:Webpack 最佳实践总结(一)、Webpack 最佳实践总结(二) 好了,这篇是第三篇,也是完结篇,我感觉这一篇是最乱的一篇,凑合着看吧,不会让你失望的 整合 CSS 加工流 有时候,前端项目中除了 JavaScript ...

    jerryloveemily 评论0 收藏0
  • lodash源码分析之缓存方式选择

    摘要:接口设计同样实现了跟一致的数据管理接口,如下依赖源码分析之缓存源码分析之缓存源码分析是否使用这个函数用来判断是否使用缓存。返回表示使用缓存,返回则使用或者缓存。获取对应缓存方式的实例这个函数根据来获取储存了该的缓存实例。 每个人心里都有一团火,路过的人只看到烟。——《至爱梵高·星空之谜》 本文为读 lodash 源码的第八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-...

    HitenDev 评论0 收藏0
  • lodash源码分析之缓存方式选择

    摘要:接口设计同样实现了跟一致的数据管理接口,如下依赖源码分析之缓存源码分析之缓存源码分析是否使用这个函数用来判断是否使用缓存。返回表示使用缓存,返回则使用或者缓存。获取对应缓存方式的实例这个函数根据来获取储存了该的缓存实例。 每个人心里都有一团火,路过的人只看到烟。——《至爱梵高·星空之谜》 本文为读 lodash 源码的第八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-...

    AdolphLWQ 评论0 收藏0
  • lodash源码分析之Hash缓存

    摘要:只接收一个二维数组作为参数,调用方式如下其中子项中的第一项会作为,第二项是需要缓存的值。实例化的结果如下缓存的数量储存在的对象中。的作用是清空缓存,因此需要将重置为。将缓存的数据设置为空对象。因为在缓存中是以来表示的,因此遇到值为时,返回。 在那小小的梦的暖阁,我为你收藏起整个季节的烟雨。——洛夫《灵河》 本文为读 lodash 源码的第四篇,后续文章会更新到这个仓库中,欢迎 sta...

    cartoon 评论0 收藏0
  • lodash源码分析之Hash缓存

    摘要:只接收一个二维数组作为参数,调用方式如下其中子项中的第一项会作为,第二项是需要缓存的值。实例化的结果如下缓存的数量储存在的对象中。的作用是清空缓存,因此需要将重置为。将缓存的数据设置为空对象。因为在缓存中是以来表示的,因此遇到值为时,返回。 在那小小的梦的暖阁,我为你收藏起整个季节的烟雨。——洛夫《灵河》 本文为读 lodash 源码的第四篇,后续文章会更新到这个仓库中,欢迎 sta...

    justjavac 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<