object-hierarchy-access
Version:
Get/Set value from/to JS object hierarchy properties
58 lines (51 loc) • 1.65 kB
text/typescript
import {PropName, HierarchyCallbackReturns, GetPropParam} from './type';
import {normalizeDescriptor, getNameValue} from './utility/get';
function _parseArgs(others: any[]) {
const callback: HierarchyCallbackReturns<any> = others[others.length - 1];
const hierarchies: GetPropParam[] = Array.prototype.concat.apply([], others.slice(0, -1)); // exclude `callback`
return {hierarchies, callback};
}
function traverse(target: any, ...others: any[]) {
const {hierarchies, callback} = _parseArgs(others);
let current = target;
if (current !== undefined && current !== null) {
hierarchies.every(info => {
const descriptor = normalizeDescriptor(info);
const {name, value} = getNameValue(current, descriptor);
const parent = current;
current = value;
const result = callback.call(parent, parent, name, current);
return result !== false;
});
}
}
function traverseReverse(target: any, ...others: any[]) {
const {hierarchies, callback} = _parseArgs(others);
let current = target;
if (current !== undefined && current !== null) {
const params: Array<{
parent: object,
name: PropName,
current: object
}> = [];
hierarchies.every(info => {
const descriptor = normalizeDescriptor(info);
const {name, value} = getNameValue(current, descriptor);
const parent = current;
current = value;
params.push({parent, name, current});
return current;
});
for (let i = params.length - 1; i >= 0; i--) {
const item = params[i];
const result = callback.call(item.parent, item.parent, item.name, item.current);
if (result === false) {
break;
}
}
}
}
export {
traverse,
traverseReverse
};