功能

创建一个返回给定对象的 path 的值的函数。

官网给的demo。

var objects = [
   { 'a': { 'b': 2 } },
  { 'a': { 'b': 1 } }
];
_.map(objects, _.property('a.b'));

// => [2,1]

由此可以推断,_.property('a.b')返回的是一个取出对象的a>b属性的方法。

源码

function property(path) {
  return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
}

isKey用来判断是一个property name还是property path

property path,lodash中定义了一个属性路径的概念,用来快速访问对象属性。{a: {b: ['data']}},希望访问到data这个值,可以通过 'a.b[0]'来访问。

isKey

import isArray from './isArray.js';
import isSymbol from './isSymbol.js';
/** Used to match property names within property paths. */
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
    reIsPlainProp = /^\w*$/;
function isKey(value, object) {
  if (isArray(value)) {
    return false;
  }
  var type = typeof value;
  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
      value == null || isSymbol(value)) {
    return true;
  }
  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
    (object != null && value in Object(object));
}

逻辑很简单。

toKey

function toKey(value) {
  if (typeof value == 'string' || isSymbol(value)) {
    return value;
  }
  var result = (value + '');
  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}

要注意的是Symbol类型提前返回。其它类型会转换成字符串。

result == '0' && (1 / value) == -INFINITY

这里用来区分0或者-0

baseProperty

function baseProperty(key) {
  return function(object) {
    return object == null ? undefined : object[key];
  };
}

该方法就更简单了,对于没有path property参数的,就执行该方法。 只是区传入的object的制定属性的值。

basePropertyDeep

function basePropertyDeep(path) {
  return function(object) {
    return baseGet(object, path);
  };
}

可以去翻baseGet的源码了。

function baseGet(object, path) {
  path = castPath(path, object);

  var index = 0,
      length = path.length;

  while (object != null && index < length) {
    object = object[toKey(path[index++])];
  }
  return (index && index == length) ? object : undefined;
}

简单过一遍这个方法。就能确定path返回的是property path的路径数组。

 while (object != null && index < length) {
    object = object[toKey(path[index++])];
  }

通过上边的while循环一层层拿到目标值。


最普通的一个
301 声望41 粉丝

永远不要做你擅长的事。


引用和评论

0 条评论