Capitalize the capitalize function is a string conversion function used to capitalize the first letter of a string and capitalize the rest of the string. This article involves the type checking (Object. The prototype. ToString, isSymbol), type conversion toString (), sparse arrays and intensive, string handling includes facial expressions.

Type checking

getTag

const toString = Object.prototype.toString
function getTag(value) {
  if (value == null) {
    // Compatible with low versions of javascript, special handling of null and undefined
    return value === undefined ? '[object Undefined]' : '[object Null]'
  }
  return toString.call(value)
}
Copy the code

isSymbol

The getTag method is called

function isSymbol(value) {
  const type = typeof value
  return type == 'symbol' || (type === 'object'&& value ! =null && getTag(value) == '[object Symbol]')}Copy the code

Type conversion

toString

Converts the passed value to a string. Array recursive processing (possible stack overflow). Special case of minus 0. Introduce the isSymbol function above

import isSymbol from './isSymbol.js'
/** Used as references for various `Number` constants. */
const INFINITY = 1 / 0

/** * Converts `value` to a string. An empty string is returned for `null` * and `undefined` values. The sign of `-0` is Preserved. * value is converted to string. Returning null or undefined returns an empty string. -0 will be retained * *@since 4.0.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {string} Returns the converted string.
 * @example* * toString (null) * / / = > '* * toString (0) * / / = >' 0 '* * toString ([1, 2, 3]) * / / = >' 1, 2, 3 '* /
function toString(value) {
  if (value == null) {
    return ' '
  }
  // Exit early for strings to avoid a performance hit in some environments.
  // String is directly returned
  if (typeof value === 'string') {
    return value
  }
  // Array type
  if (Array.isArray(value)) {
    // Recursively convert values (susceptible to call stack limits).
    // If the array item is not null or undefined, the recursive call itself is converted
    return `${value.map((other) => other == null ? other : toString(other))}`
  }
  // symbol type calls symbol's toString method
  if (isSymbol(value)) {
    return value.toString()
  }
  // Handle the -0 case
  const result = `${value}`
  return (result == '0' && (1 / value) == -INFINITY) ? '0' : result
}
Copy the code

Handles the first letter of a string

createCaseFirst

This function relies on the castSlice function, hasUnicode function, and stringToArray function.

The castSlice function, which, in contrast to the array.prototype. slice method, calls its own slice function and generates a dense Array. Source code address. About dense and sparse arrays:

console.log(new Array(5), new Array(5).fill(undefined))
// [<5 empty items>] Sparse array
// use undefined, undefined, undefined, undefined
Copy the code

The hasUnicode function is used to verify that the string passed in contains characters from the Unicode code table (in this case, the presence of special Unicode characters). Source code address. If present, the stringToArray function is used to parse the corresponding Unicode character correctly.

/ / star layer
const rsAstralRange = '\\ud800-\\udfff'
// https://www.unicode.org/charts/PDF/U0300.pdf
const rsComboMarksRange = '\\u0300-\\u036f'
// https://www.unicode.org/charts/PDF/UFE20.pdf
const reComboHalfMarksRange = '\\ufe20-\\ufe2f'
// https://www.unicode.org/charts/PDF/U20D0.pdf
const rsComboSymbolsRange = '\\u20d0-\\u20ff'
// https://www.unicode.org/charts/PDF/U1AB0.pdf
const rsComboMarksExtendedRange = '\\u1ab0-\\u1aff'
// https://www.unicode.org/charts/PDF/U1DC0.pdf
const rsComboMarksSupplementRange = '\\u1dc0-\\u1dff'
const rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange
// fe0e fe0f https://www.unicode.org/charts/PDF/UFE00.pdf
const rsVarRange = '\\ufe0e\\ufe0f'

/** Used to compose unicode capture groups. */
// ZWJ https://www.unicode.org/charts/PDF/U2000.pdf ZERO WIDTH JOINER
const rsZWJ = '\\u200d'

/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
const reHasUnicode = RegExp(` [${rsZWJ + rsAstralRange + rsComboRange + rsVarRange}] `)
Copy the code

The stringToArray function, as mentioned above, is used to correctly parse strings containing special Unicode encodings, such as emoticons. Source code address.

CreateCaseFirst uses the passed methodName to process the first letter of the string. Methods such as toUpperCase,toLowerCase, etc. that exist on the String. Prototype prototype chain

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

/** Creates a function like 'lowerFirst'@private
 * @param {string} methodName The name of the `String` case method to use.
 * @returns {Function} Returns the new case function.
 */
function createCaseFirst(methodName) {
  return (string) = > {
    // String does nothing for an empty string
    if(! string) {return ' '
    }

    // Contains the Unicode code, calling the internal asciiToArray and unicodeToArray methods
    const strSymbols = hasUnicode(string)
      ? stringToArray(string)
      : undefined

    // String characters do not contain the first character of a string that Unicode takes by default. Otherwise, take the first character after converting to an array
    const chr = strSymbols
      ? strSymbols[0]
      : string[0]

    // string intercepts the rest of the string. Contains Unicode cases, intercepting the 1 to last item of the array and converting it to a string
    const trailing = strSymbols
      ? castSlice(strSymbols, 1).join(' ')
      : string.slice(1)

    // Call the method corresponding to the first string to execute the function corresponding to prototype and append subsequent strings
    // Only the first character of the string is operated on
    return chr[methodName]() + trailing
  }
}
Copy the code

upperFirst

Call createCaseFirst, passing toUpperCase as an argument

Case the first character of 'string' to upper case@since 4.0.0
 * @category String
 * @param {string} [string=''] The string to convert.
 * @returns {string} Returns the converted string.
 * @see camelCase, kebabCase, lowerCase, snakeCase, startCase, upperCase
 * @example
 *
 * upperFirst('fred')
 * // => 'Fred'
 *
 * upperFirst('FRED')
 * // => 'FRED'
 */
const upperFirst = createCaseFirst('toUpperCase')
Copy the code

capitalize

Call toString and upperFirst. To the value of the incoming call toString function first, and then calls the String. The prototype. ToLowerCase method, finally call upperFirst functionality

const capitalize = (string) = > upperFirst(toString(string).toLowerCase())
Copy the code