用法
lodash的split方法接收3个参数
- 第一个参数是需要拆解的字符串
- 第二个参数是拆分的分隔符
- 第三个参数是保留字符的个数
split('a-b-c', '-', 2)
// => ['a', 'b']
解析
首先来看它的函数入口
function split(string, separator, limit) {
limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0
if (!limit) {
return []
}
if (string && (
typeof separator === 'string' ||
(separator != null && !isRegExp(separator))
)) {
if (!separator && hasUnicode(string)) {
return castSlice(stringToArray(string), 0, limit)
}
}
return string.split(separator, limit)
}
首先,对传入的limit进行了校验,如果没有传,那么就把分解的字符全部保留下来,如果传了,那么使用无符号移位运算符 '>>>' 使limit进行有意义的转化(如非负,不能有小数),如果limit没有意义则返回空数组
关于无符号移位运算符 '>>>' 可以看这篇文章
之后在第一个if中,判断了传入字符串是否有意义,并检测分隔符是否为字符串类型,或者不为null和regExp。如果不满足,直接调用string原生的split方法。
满足的话进入下一个if判断,第二个if判定检测分隔符是否为空,并且通过检查unicode编码,判定string中是否有特殊的符号,这里来看看hasUnicode方法
const rsAstralRange = '\\ud800-\\udfff'
const rsComboMarksRange = '\\u0300-\\u036f'
const reComboHalfMarksRange = '\\ufe20-\\ufe2f'
const rsComboSymbolsRange = '\\u20d0-\\u20ff'
const rsComboMarksExtendedRange = '\\u1ab0-\\u1aff'
const rsComboMarksSupplementRange = '\\u1dc0-\\u1dff'
const rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange
const rsVarRange = '\\ufe0e\\ufe0f'
const rsZWJ = '\\u200d'
function hasUnicode(string) {
return reHasUnicode.test(string)
}
接下来我们来看castSlice方法,这个方法就是一个对数组进行切割的方法,这里传入的array是传入的分割后的数组。
function castSlice(array, start, end) {
const { length } = array
end = end === undefined ? length : end
return (!start && end >= length) ? array : slice(array, start, end)
}
接着我们来看stringToArray方法,这个方法也先检测了是否有特殊符号,如果有的话,就用unicodeToArray方法,这里的reUnicode定义的非常的复杂,主要是为了囊括所有的符号。否则的话就调用原生的split方法
function stringToArray(string) {
return hasUnicode(string)
? unicodeToArray(string)
: asciiToArray(string)
}
function unicodeToArray(string) {
return string.match(reUnicode) || []
}
function asciiToArray(string) {
return string.split('')
}
总结
lodash的split方法之于原生的split方法增加了许多的边界判定,并且这些判定函数复用到了很多的方法中。