Functions and usage scenarios
The get method in lodash is to get the value of an object. In the case of the optional chain operator es, and without ts, the general value of the object is object.a.b.c… , if do not have this one in the object properties, and get the value directly, will throw an error, affect the program execution, code in order to improve the robustness, will use the if add judgment, or use &&, | | and other logical operators, however, in the case of object hierarchy is deep, code readability becomes poor, so, Using loDash’s get method is much simpler
usage
The lodash library can be imported directly via CDN or via node_modules.
import baseGet from './.internal/baseGet.js'
/**
* Gets the value at `path` of `object`. If the resolved value is
* `undefined`, the `defaultValue` is returned in its place.
*
* @since 3.7.0
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to get.
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
* @returns {*} Returns the resolved value.
* @see has, hasIn, set, unset
* @example
*
* const object = { 'a': [{ 'b': { 'c': 3 } }] }
*
* get(object, 'a[0].b.c')
* // => 3
*
* get(object, ['a', '0', 'b', 'c'])
* // => 3
*
* get(object, 'a.b.c', 'default')
* // => 'default'
*/
function get(object, path, defaultValue) {
const result = object == null ? undefined : baseGet(object, path)
return result === undefined ? defaultValue : result
}
export default get
Copy the code
The get method takes three arguments,
object
Represents the object to be evaluatedpath
It’s the path to the value, which can be a string or an arraydefaultValue
Is that when the value fails (obejct
Contains nopath
Value in the path, orobject
fornull
When), the value returned
As you can see, when OBEjct == null, the value of defaultValue is returned. If defaultValue is not passed, undefined. When OBEjct is a normal object, the baseGet method is called, passing in OBEjct and path, Take a look at the baseGet code:
import castPath from './castPath.js' import toKey from './toKey.js' /** * The base implementation of `get` without support for default values. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. * @returns {*} Returns the resolved value. */ function baseGet(object, path) { path = castPath(path, object) let index = 0 const length = path.length while (object ! = null && index < length) { object = object[toKey(path[index++])] } return (index && index == length) ? object : undefined } export default baseGetCopy the code
CastPath converts path to an array type, for example,’ a[0].b.c’, which is then converted to [‘a’,’0′,’b’,’c’]. The conversion rules will be explained later. Take a look at the toKey code:
import isSymbol from '.. /isSymbol.js' /** Used as references for various `Number` constants. */ const INFINITY = 1 / 0 /** * Converts `value` to a string key if it's not a string or symbol. * * @private * @param {*} value The value to inspect. * @returns {string|symbol} Returns the key. */ function toKey(value) { if (typeof value === 'string' || isSymbol(value)) { return value } const result = `${value}` return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result } export default toKeyCopy the code
${value} returns toKey as a string or isSymbol as a string. ${value} returns toKey as a string or isSymbol as a string (result == ‘0’ && (1 / value) == -INFINITY) ? If path = [‘a’,0,’b’,’c’], object = [‘a’,0,’b’,’c’], object = [‘a’,0,’b’,’c’], object = [‘a’,-0,’b’,’c’
ToKey is a way to convert a key value to a string
Object = object[toKey(path[index++])]] overwrites the old object value. Return (index && index == length)? Return (index && index == length)? object : A [0].b.c = object.a[0].b.c If there is no a attribute in object, the value of object.a is undefined. If undefined[0] is used, the error will be reported.
import isKey from './isKey.js' import stringToPath from './stringToPath.js' /** * Casts `value` to a path array if it's not one. * * @private * @param {*} value The value to inspect. * @param {Object} [object] The object to query keys on. * @returns {Array} Returns the cast property path array. */ function castPath(value, object) { if (Array.isArray(value)) { return value } return isKey(value, object) ? [value] : stringToPath(value) } export default castPathCopy the code
As mentioned earlier, the castPath method converts path representations such as strings into arrays, so if value is an array, it returns [value] if it satisfies isKey, otherwise it returns stringToPath(value).
import isSymbol from '.. /isSymbol.js' /** Used to match property names within property paths. */ const reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/ const reIsPlainProp = /^\w*$/ /** * Checks if `value` is a property name and not a property path. * * @private * @param {*} value The value to check. * @param {Object} [object] The object to query keys on. * @returns {boolean} Returns `true` if `value` is a property name, else `false`. */ function isKey(value, object) { if (Array.isArray(value)) { return false } const type = typeof value if (type === 'number' || type === 'boolean' || value == null || isSymbol(value)) { return true } return reIsPlainProp.test(value) || ! reIsDeepProp.test(value) || (object ! = null && value in Object(object)) } export default isKeyCopy the code
IsSymbol is a Symbol of the element type
- if
value
isNumber, Boolean, Symbol
Type, orvalue
A value ofnull
orundefined
It returns true reIsDeepProp.test(value)
The re matches, and it matches'a.b.c'
.'a[0].b.c'
These types ofreIsPlainProp.test(value)
Matches digits, letters, and underscoresobject
Don’t fornull
And,object
invalue
Property, which is passableobject[value]
Take to the value
When value is of type number, Boolean, Symbol, or value == null, or the string does not contain []. IsKey returns true for letters, digits, underscores, or values in object. IsKey returns true for letters, digits, underscores, or values in object. IsKey returns true for letters, digits, underscores, or values in object. StringToPath (Value) returns the value of the stringToPath(value) method:
import memoizeCapped from './memoizeCapped.js' const charCodeOfDot = '.'.charCodeAt(0) const reEscapeChar = /\\(\\)? /g const rePropName = 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') /** * Converts `string` to a property path array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the property path array. */ const stringToPath = memoizeCapped((string) => { const result = [] if (string.charCodeAt(0) === charCodeOfDot) { result.push('') } string.replace(rePropName, (match, expression, quote, subString) => { let key = match if (quote) { key = subString.replace(reEscapeChar, '$1') } else if (expression) { key = expression.trim() } result.push(key) }) return result }) export default stringToPathCopy the code
CharCodeOfDot represents the Unicode encoding for ‘.’, which is 46, so when the first part of the path string is. Add an empty string to result RePropName generated by the regular expression as / [^. [\]] + | \ [(? : ([[^ ^ “‘] [] *) | ([“]) ((? : (?! \ 2) | \ \ [^ \ \]) *?) \ \] 2) | (? = (? : \ | \ [\]) (? : \ | \ [\] | $))/g, [‘a’,’0′,’b’,’c’]; [‘a’,’0′,’b’,’c’]; [‘ b’,’c’]; If the second argument is a function, it will be called on each matching result, and it will return the string as the replacement text. It takes four arguments:
- A string that matches the pattern
- A string that matches one of the parentheses subexpression in the pattern, which may be zero or more such arguments
- Integer, specified
String
The location where a match occurs in string
itself