建立一個返回給定對象的 path
的值的函數。javascript
官網給的demo。java
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]'來訪問。
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)); }
邏輯很簡單。code
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
ip
這裏用來區分0
或者-0
字符串
function baseProperty(key) { return function(object) { return object == null ? undefined : object[key]; }; }
該方法就更簡單了,對於沒有path property
參數的,就執行該方法。 只是區傳入的object
的制定屬性的值。源碼
function basePropertyDeep(path) { return function(object) { return baseGet(object, path); }; }
能夠去翻baseGet的源碼了。string
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
循環一層層拿到目標值。