You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constcharCodeOfDot='.'.charCodeAt(0)constreEscapeChar=/\\(\\)?/gconstrePropName=RegExp(// Match anything that isn't a dot or bracket.'[^.[\\]]+'+'|'+// Or match property names within brackets.'\\[(?:'+// Match a non-string expression.'([^"\'][^[]*)'+'|'+// Or match strings (supports escaping characters).'(["\'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2'+')\\]'+'|'+// Or match "" as the space between consecutive dots or empty brackets.'(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))','g')conststringToPath=memoizeCapped((string)=>{constresult=[]if(string.charCodeAt(0)===charCodeOfDot){result.push('')}string.replace(rePropName,(match,expression,quote,subString)=>{letkey=matchif(quote){key=subString.replace(reEscapeChar,'$1')}elseif(expression){key=expression.trim()}result.push(key)})returnresult})
本文为读 lodash 源码的第六十八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
gitbook也会同步仓库的更新,gitbook地址:pocket-lodash
依赖
《lodash源码分析之memoizeCapped》
源码分析
stringToPath
同样是lodash
的内部方法,作用是将深层嵌套属性字符串转换成路径数组,即将类似于a.b.c
这样的字符串,转换成['a', 'b', 'c'] 这样的数组,
方便lodash
从数组中将属性一个一个取出,然后取值。代码如下:
处理以
.
开头的字符串以
.
开头的字符串,lodash
会认定最外层的属性为空字符串。注意这里用
charCodeAt(0)
来获取.
的charCode
,再和string
的0
位的charCode
作对比,这里最开始的时候是用正则/^\./
来做匹配的,后来有个提交了个pr
才最终使用charCode
来比较,因为这样的性能更好。处理常规路径
lodash
的这个正则相当复杂,主要处理三种情况。首先看看
a.b.c
这种情况。在这种情况下,可以简化成下面的代码:这种情况下,是最简单的,只有
match
有值,回调函数会调用三次,match
的值分别为a
、b
、c
。直接将结果push
入result
数组即可。处理一般中括号取值
在数组取值的情况下,会写上中括号加上索引,如
a[0].b
这样的形式,转换成路径数组是['a', '0', 'b']
。在这种情况下,可以简化成这样的形式:
在匹配到索引
0
时,match
的结果是[0]
,但是这里expression
的结果是0
,因此key
为0
。处理带引号的情况
中括号的情况下,有些人会习惯性地带上引号,如写成
a['0'].b
的形式,如果这个string
是通过接口返回的,可以还会带上转义字符,如a[\'0\'].b
,在这种情况下,quote
会有值,
,这时subString
为在没转义的情况下为0
,在有转义符的情况下为\'0\'
,因此需要用reEscapeChar
正则将转义字符替换掉。License
署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)
最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:
作者:对角另一面
The text was updated successfully, but these errors were encountered: