Similar to key of object (Object.keys) but deep key. Provides recursive access to object member.
npm install deep-key




"Deep Key" is single dimentional array of keys that represents full path of
object member. Similar to key of object (Object.keys) but "deep" key. Provides
recursive access to object member.
``javascript`
const DeepKey = require('deep-key');
var obj = { p1: { p2: { p3: { p4: 0 } } } };
DeepKey.keys(obj);
// [ ['p1'], ['p1', 'p2'], ['p1', 'p2', 'p3'] ... ]
``
npm install --save deep-key
Get all deep keys recursively. Many options are available. See Options.
`javascript`
DeepKey.keys(obj);
DeepKey.keys(obj, option);
Get value of object member that is pointed by deep key.
`javascript`
DeepKey.get(obj, deepkey);
Set value for object member that is pointed by deep key.
`javascript`
DeepKey.set(obj, deepkey, value);
Whether such a member exits or not, member is always overwritten or created. To
prevent this, use exists to check its existence.
Create object member that is pointed by deep key if does not exist. Similar to
set method, but value never be changed if member already exist.
For initial value of new member, third argument value is used if present,undefined
otherwise is used.
`javascript`
DeepKey.touch(obj, deepkey);
DeepKey.touch(obj, deepkey, value);
Returns value of object member.
Get type of object member that is pointed by deep key.
If member does not exist, return "undefined".typeof(null)
Note that returns "object".
`javascript`
DeepKey.type(obj, deepkey);
// equivalent with
// typeof(DeepKey.get(obj, deepkey))
Get accessor of object member that is pointed by deep key.
Accessor has get and set methods.
`javascript`
DeepKey.accessor(obj, deepkey);
Caching accessor may be able to reduce computing cost that relates with object
tree traversing.
If there are no member that is pointed by deep key, member is automatically
created. (Initial value is undefined).
Remove object member that is pointed by deep key.
Equivalent to using delete keyword.
`javascript`
DeepKey.delete(obj, deepkey);
Returns value of object member that is pointed by deep key.
Rename key of object member by using current and new deep keys.
`javascript`
DeepKey.rename(obj, src, dest);
If member that is pointed by src does not exist, undefined is set for one ofdest. And, whether one of dest already exists or not, it will be overwrittensrc
by one of . To prevent those, use exists to check their existence.
Returns value of object member that is pointed by deep key.
Check existence of object member that is pointed by deep key.
`javascript`
DeepKey.exists(obj, deepkey);
The following options are available for keys().
all option allows to get all member enumeration including unenumerable members.
`javascript`
var obj = { enum: 'e', };
Object.defineProperty(obj, 'unenum', { value: 'u' });
obj.propertyIsEnumerable('unenum');
// false
DeepKeys.keys(obj);
// [ ['enum'] ]
DeepKeys.keys(obj, { all: true });
// [ ['enum'], ['unenum'] ]
depth option allows to limit enumeration by depth.
`javascript`
var obj = { prop1: { prop2: { prop3: { } } } }
console.log(DeepKey.keys(obj, { depth: 2 }));
// [ ['prop1'], ['prop1', 'prop2'] ]
If merely want to specify depth option, can directly pass into second argumentoption
in place of .
`javascript`
DeepKey.keys(obj, depth);
Note that all keys will be enumerated if zero or negative value is specified for
depth.
filter option allows to limit enumeration by your custom function.
`javascript
var obj = {
prop1: { prop2: {} }
prop3: { skip1: {} },
prop4: 'p4',
skip2: 'e2'
}
console.log(DeepKey.keys(obj, {
filter: (deepkey, value) => {
return !/skip\d+/.test(deepkey.join('.'));
}
});
// [ ['prop1'], ['prop1', 'prop2'], ['prop3'], ['prop4'] ]
`
For each member, filter function is called back by passing the following three arguments:
- deepkey : deep key of membervalue
- : value of member that is pointed by deepkeyenumerable
- : whether member is enumerable (propertyIsEnumerable)
filter function must return true in order to include in enumeration,false otherwise.
If merely want to specify filter option, can directly pass into secondoption
argument in place of .
`javascript`
DeepKey.keys(obj, filter);
noindex option allows to suppress index-enumeration of Array.
In JavaScript world, Array is also object-type and its indexes are keys of object.
> An Array object is an exotic object that gives special treatment to array index property keys
> (ES6 9.4.2)
Try the following code:
`javascript`
typeof [];
// 'object'
Object.keys(['one', 'two', 'three']);
// [ '0', '1', '2' ]
Therefore, keys of this package also enumerate keys of Array by default.noindex
In most case, this behavior is an undesirable overboundance. option can suppress this.
NOTE: Array is also extensible. Note that its extended member will benoindex
always enumerated, regardless of option.
`javascript`
var obj = { array: [1,2,3], val: 4 };
obj.array.five = 5;
DeepKey.keys(obj, { noindex: true });
// [ ['array'], ['array', 'five'], ['val'] ]
leaf option allows to enumerate only "leafs" that have no descendant keys:
`javascript`
DeepKeys.keys({a: {b: {c: 'd'}}}, {leaf: true});
// [ ['a', 'b', 'c', 'd'] ]
When Array members are present, noindex is recommended in most cases.
`javascript
DeepKeys.keys({a: ['b', 'c']}, {leaf: true});
// [ ['a', '0'], ['a', '1'] ]
// In most cases, maybe indexes are not expected "leafs".
DeepKeys.keys({a: ['b', 'c']}, {leaf: true, noindex: true});
// [ ['a'] ]
`
Finally, the behavior both leaf and depth options are specified is
cautionable. It will return pseudo-leafs under the restriction of specified
depth, therefore returned members might have descendant keys if no depth option.
When want to filter "exact" leafs that have no descendant keys, try the following code:
`javascript`
// Filter leaf that depth is 3
DeepKey.keys(obj, { leaf: true }).filter(key => key.length <= 3);
Whether specified member is present or not, DeepKey automatically overwrite
or create member recursively, therefore exception handing is not required in
most cases.
But, there are an exception that is thrown in special case.
On object tree traversing, if intermediate inextensible object is found (null,
number, string, seald object, and so on), an error /^Inextensible object:/ be
thrown. Because such an inextensible object cannot have new extended members.
`javascript
var obj = { prop1: { prop2: 1 } };
DeepKey.set(obj, [ 'prop1', 'prop2' ], 2);
// Of course, success
DeepKey.set(obj, [ 'prop1', 'prop2', 'prop3' ], 3);
// 'Inextensible object: prop1.prop2' is thrown.
// Because value 2 of prop1.prop2 is inextensible.
`
NOTE: Members of exsisting intermediate sealed object can be readable and
writable because "seal" does not prevent to change value of its member.
`javascript``
var obj = { { sealed: { present: false } } };
Object.seal(obj.sealed);
DeepKey.set(obj, ['sealed', 'present'], true);
DeepKey.get(obj, ['sealed', 'present']);
// true
MIT license.
(C) 2016-2017 Retorillo