pocket-lodash icon indicating copy to clipboard operation
pocket-lodash copied to clipboard

lodash源码分析之split

Open HeftyKoo opened this issue 4 years ago • 0 comments

本文为读 lodash 源码的第三百三十三篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash

gitbook也会同步仓库的更新,gitbook地址:pocket-lodash

依赖

import castSlice from './.internal/castSlice.js'
import hasUnicode from './.internal/hasUnicode.js'
import isRegExp from './isRegExp.js'
import stringToArray from './.internal/stringToArray.js'

《lodash源码分析之castSlice》

《lodash源码分析之hasUnicode》

《lodash源码分析之isRegExp》

《lodash源码分析之stringToArray》

源码分析

split 的作用基于字符串的 split 方法,会对 unicode 编码做特殊的处理。

源码如下:

const MAX_ARRAY_LENGTH = 4294967295
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 === undefined ? MAX_ARRAY_LENGTH : limit >>> 0
if (!limit) {
  return []
}

如果 limitundefined ,则默认 limit 为最大的数组长度。

如果有传 limit ,则使用无符号位右移,将 limit 转换成正整数。

这里的转换很巧妙,用了无符号位右移,无符号位右移首先会忽略小数位,这样 limit 就变成整数了,然后这里右移的位数是 0 位,对于正整数来说,右移 0 位和原来的一样,对于负数来说,无符号位右移会将符号位变成 0 ,右移 0 位就相当于取绝对值了。

如果转换后 limit0 ,则返回一个空数组。

处理含unicode字符串

if (string && (
  typeof separator === 'string' ||
  (separator != null && !isRegExp(separator))
)) {
  if (!separator && hasUnicode(string)) {
    return castSlice(stringToArray(string), 0, limit)
  }
}

也不是所有含有 unicode 的字符串都需要特殊处理的,只有 separator 为假值时,这时如果直接使用 split 来分割,可能会出现乱码。

因此先用 stringToArray 将字符串转换成数组,然后用 castSlice 来截取规定的长度。

其它情况处理

return string.split(separator, limit)

其它情况就很简单了,交由字符串的 split 方法处理即可。

License

署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)

最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:

作者:对角另一面

HeftyKoo avatar May 29 '20 14:05 HeftyKoo