Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lodash源码分析之createPadding #327

Open
HeftyKoo opened this issue May 27, 2020 · 0 comments
Open

lodash源码分析之createPadding #327

HeftyKoo opened this issue May 27, 2020 · 0 comments
Labels
internal 内部函数或方法 系列文章

Comments

@HeftyKoo
Copy link
Owner

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

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

依赖

import repeat from '../repeat.js'
import baseToString from './baseToString.js'
import castSlice from './castSlice.js'
import hasUnicode from './hasUnicode.js'
import stringSize from './stringSize.js'
import stringToArray from './stringToArray.js'

lodash源码分析之repeat

lodash源码分析之baseToString

lodash源码分析之castSlice

lodash源码分析之hasUnicode

lodash源码分析之stringSize

lodash源码分析之stringToArray

源码分析

createPadding 其实也可以理解成 repeatslice 的组合,它接收一个字符串 chars 和长度 length ,最终会返回一个长度为 length 的字符串。

如果 chars 的长度不足 length , 会重复 chars ,得到一个长度为 length 的字符串,如果 chars 的长度大于 length ,则会对 chars 进行截断。

源码如下:

function createPadding(length, chars) {
  chars = chars === undefined ? ' ' : baseToString(chars)

  const charsLength = chars.length
  if (charsLength < 2) {
    return charsLength ? repeat(chars, length) : chars
  }
  const result = repeat(chars, Math.ceil(length / stringSize(chars)))
  return hasUnicode(chars)
    ? castSlice(stringToArray(result), 0, length).join('')
    : result.slice(0, length)
}

对chars进行转换

chars = chars === undefined ? ' ' : baseToString(chars)

如果 charsundefined ,则默认 chars 为一个空格。

否则调用 baseToStringchars 转换成字符串。

处理chars长度小于2的情况

const charsLength = chars.length
if (charsLength < 2) {
  return charsLength ? repeat(chars, length) : chars
}

charsLength 小于 2,也即为 0 或者 1 的时候,不涉及到截断操作。

charsLength 有值时,也即为 1 时,调用 repeatchars 重复 length 次即可,即使 length0repeat 得到是将会是一个空字符串,不需要再进行额外的截断操作。

charsLength0 时,即本身就是一个空字符串,直接返回。

重复

const result = repeat(chars, Math.ceil(length / stringSize(chars)))

调用 stringSize 来取得 chars 的长度,再使用 length 除以 chars 的长度得到字符串的重复多少次才能达到 length 的长度,但是计算出来的次数是可能有小数的。

因此需要使用 Math.ceil 来向上取整,再调用 repeat 来重复得到结果 result ,因为是向上取整,这个 result 有可能比 length 要长。

截断

return hasUnicode(chars)
    ? castSlice(stringToArray(result), 0, length).join('')
    : result.slice(0, length)

因为 result 有可能比 length 要长,因此需要对 result 进行截断操作。

截断需要区分两种情况,如果含有 unicode 编码,则先调用 stringToArrayresult 转换成字符串数组,然后调用 castSlice 来进行截断,截断后就是一个长度为 length 的字符串数组,再用 join 方法拼接成长度为 length 的字符串,这样可以避免直接使用 slice 来截断出现乱码。

如果没有 unicode 编码,直接使用字符串的 slice 截断。

License

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

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

作者:对角另一面

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal 内部函数或方法 系列文章
Projects
None yet
Development

No branches or pull requests

1 participant