# iskey
# Description
isKey 的作用是用来判断传入的 value 是否为合法的属性名, 检查 value 是否是属性名称而不是属性路径(如传入 a.b.c 或者 a[0].b.c 可能会返回 false。)。
# Params
(value, object)
value: 需要校验的值 object: 所属对象
# Return
Boolean
# Depend
    import isSymbol from '../isSymbol.js'
# Code
const reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/
const reIsPlainProp = /^\w*$/
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))
}
# Analyze
#
- reIsDeepProp, 用于匹配属性路径中的属性名称。- /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/图解如下
在 lodash 中,像 a.b.c 和 a[0].b.c 这种可能会被当作属性路径对待,像 get 这些的函数支持传入这样的路径来获取嵌套对象的值,在这个正则中,主要就是匹配 . []这种属性值,同时支持转义字符,如 [\'b\']
- reIsPlainProp, 用于匹配- [0-9A-Za-z_]- /^\w*$/, 图解如下
# 源码分析
- 首先判断 value如果是Array,直接return false
- 其次判断 value的类型是否为Number、Boolean、Null,Symbol,除Symbol外,在做Object的Key值时,都会默认转换为String,而在ES6中,Symbol本身就可以做Object的Key值 (Symbol术语 MDN (opens new window))
- 开始处理字符串类型, 如果是 \w类型则直接返回true,接着判断如果 不是.[](如:a.b.ca['b'].c) 这种类型的情况下,返回true
- 特殊情况处理,如果非要 传入 a.b.c这种形式的情况,就需要用到 第二个参数object来判断,如果传入的对象不为空,并且value是object的Key则返回true
# Remark
- in运算符 MDN (opens new window)
- Object 属性名称 MDN (opens new window)
- 判断字符串时,先判断 \w后判断其他的(其实只判断第二个正则也可以,还是因为性能原因),是因为第二个正则太复杂,为性能考虑,首先先判断\w
# Example
isKey(3) // true
isKey('a') // true
isKey('a.b.c') // false
isKey('a.b.c', {"a.b.c": 1}) // true