Module: @lumjs/core/obj

Object helpers sub-module.

Source:

Classes

CopyProps

Members

(static, constant) CLONE

An enum of supported modes for the clone() method.

  • P → All properties. If unchecked, enumerable properties only.
  • A → Uses Array.slice() shortcut for shallow Array cloning.
  • R → Recursive (deep) cloning of nested objects.
  • D → Uses descriptor cloning instead of direct assignment.
  • T → Sets the prototype of the clone as well.
Mode P A R D T Notes
CLONE.N × × × × × Can be used to manually specify options.
CLONE.DEF × × × × Default mode for cloning functions.
CLONE.DEEP × × ×
CLONE.FULL × ×
CLONE.ALL × × ×
CLONE.ENTIRE ×
CLONE.JSON - - - × Uses JSON, so no function or symbol support.

The and × marks signify the default settings in the mode. In most cases there are options that can override the defaults.

Any feature in the CLONE.JSON row marked with - are incompatible with that mode and cannot be enabled at all.

Source:

(static) duplicateOne

Make a copy of a single object using copyAll.

Use clone for a more robust version.

Alias: copyAll.clone

Source:

(static) duplicateOne

Make a new object containing properties from other objects using copyAll.

Use copyProps.into({}).from(...sources) for a more robust version.

Alias: copyAll.duplicate

Source:

Methods

(static) SOA()

Need a String or Array

Source:

(static) addClone(obj, defOptsopt)

Add a clone() method to an object.

Parameters:
Name Type Attributes Default Description
obj object | function

The object to add clone() to.

defOpts object <optional>
null

Default options for the clone() method.

If null or anything other than an object, the defaults will be:

{mode: CLONE.DEF, addClone: true, addLock: false}

Source:

(static) addLock(obj, optsopt) → {object}

Add a lock() method to an object.

Adds a wrapper version of lock() to the object as a method.

Parameters:
Name Type Attributes Description
obj object

The object we're adding lock() to.

opts object <optional>

Options and defaults. In addition to options specific to this function, any options supported by addClone() may be specified here as well.

Properties
Name Type Attributes Default Description
lockDesc object <optional>

Descriptor rules the lock() method.

addClone boolean <optional>
true

Default for clonable parameter.

useSeal object <optional>
false

Default for useSeal parameter.

Source:
Returns:

obj

Type
object

(static) apply(obj, …fns) → {object}

Apply functions to an object

In addition to the parameters passed, we'll also define:

  • cp will be a CopyProps instance via copyProps.cache.into(obj);
  • args will be an array of [obj, opts];
  • opts will be an object of {obj, cp, args};
Parameters:
Name Type Attributes Description
obj object | function

The target we're applying to.

fns function | object <repeatable>

Values we are applying.

For each value of fns as fn:

  • If a function we'll call fn.apply(obj, args);
  • If an object we'll call cp.from(fn).
Source:
Throws:

If a fns value is not valid.

Type
TypeError
Returns:

obj

Type
object

(static) clone(obj, optsopt) → {object}

Clone an object or function.

Parameters:
Name Type Attributes Default Description
obj object

The object we want to clone.

opts object | number <optional>
{}

Options for the cloning process.

If this is a number then it's assumed to be the opts.mode parameter.

Properties
Name Type Attributes Default Description
mode number <optional>
CLONE.DEF

One of the CLONE.* enum values.

When the clone() method was written to replace some similar methods from earlier libraries, I for some reason decided to simply have a bunch of different cloning modes. I have since added a full set of options that allows overriding the options of any mode (except CLONE.JSON).

The CLONE enum is also aliased as clone.MODE as an alternative.

all boolean <optional>

Clone all of the object's properties?

If false only enumerable properties will be cloned.

The default value depends on the opts.mode used.

This is not used if opts.mode was CLONE.JSON.

slice boolean <optional>

Use the Array.slice() shortcut?

If true then when cloning Array objects, a shallow clone will be created using the Array.slice() method.

The default value depends on the opts.mode used.

This is not used if opts.mode was CLONE.JSON.

recursive boolean <optional>

Clone nested objects recursively?

The default value depends on the opts.mode used. If opts.slice is also true then Array objects will be shallow clones while any other kind of object will be recursive.

This is not used if opts.mode was CLONE.JSON.

descriptors boolean <optional>

Clone using the property descriptors?

If true we will get the property descriptors from the original object, and assign them to the clone. This is the only way to clone accessor type properties properly.

If false we will directly assign the property value from the original object into the clone. This means the current value returned from an accessor type property will be assigned statically to the clone.

The default value will be true if opts.all OR opts.recursive are true. It will be false otherwise.

This is not used if opts.mode was CLONE.JSON.

prototype boolean <optional>

Set the clone's prototype?

If true, once the cloning is complete, we will call Object.getPrototypeOf() on the original obj, and then call Object.setProrotypeOf() on the clone.

If false then the clone with have a prototype of Object or Array depending on whether the original object was an Array or not. No further prototype handling will be done.

The default value will be true if opts.all AND opts.recursive are both true. Otherwise the default value is false. So for modes, only CLONE.ENTIRE uses this by default.

addClone object | boolean <optional>
false

Call addClone() on the cloned object.

If opts.addClone is an object then it will be used as the options passed to the addClone() method. If it is true then the opts will be passed as is.

addLock object | boolean <optional>
false

Call addLock() on the cloned object.

If opts.addLock is an object then it will be used as the options passed to the addLock() method. If it is true then the opts will be passed as is.

copy object | boolean <optional>
false

Call copyProps() on the cloned object.

This is called after the normal cloning process, so only properties that weren't copied during the cloning process will be copied here. This is a leftover from when CLONE.JSON was the default cloning mode, and this was the only way to restore function properties.

If opts.copy is an object then it will be used as the options passed to the copyProps() method. If it is true then the opts will be passed as is.

Source:
Returns:

The clone of the object.

Type
object

(static) cloneIfLocked(obj, optsopt) → {object}

Clone an object if it's not extensible (locked, sealed, frozen, etc.)

If the object is extensible, it's returned as is.

If not, if the object has a clone() method it will be used. Otherwise use our clone() function.

Parameters:
Name Type Attributes Description
obj object

The object to clone if needed.

opts object <optional>

Options to pass to clone() method.

Source:
Returns:
  • Either the original object, or an extensible clone.
Type
object

(static) copyAll()

This is a 'dumb' copy method.

It only copies enumerable properties, does no type checking, and has no qualms about overwriting properties.

Use copyProps, or mergeNested for more robust versions.

Source:

(static) copyProps(source, target, optsopt) → {object}

Copy properties from one object to another.

Parameters:
Name Type Attributes Description
source object | function

The object to copy properties from.

target object | function

The target to copy properties to.

opts object <optional>

Options for how to copy properties.

Properties
Name Type Attributes Default Description
default boolean <optional>
true

Copy only enumerable properties.

all boolean <optional>
false

Copy ALL object properties.

props Array <optional>

A list of specific properties to copy.

exclude Array <optional>

A list of properties NOT to copy.

overrides object <optional>

Descriptor overrides for properties.

The object is considered a map, where each key is the name of the property, and the value should be an object containing any valid descriptor properties.

If opts.default is explicitly set to false and opts.overrides is set, then not only will it be used as a list of overrides, but only the properties specified in it will be copied.

overwrite * <optional>
false

Overwrite existing properties.

If this is a boolean value, it will allow or disallow overwriting of any and all properties in the target object.

If this is an object, it can be an Array of property names to allow to be overwritten, or a map of property name to a boolean indicating if that property can be overwritten or not.

Finally, if this is a function it'll be passed the property name and must return a boolean indicating if overwriting is allowed.

recursive number <optional>
0

Enable recursive copying of objects.

If it is 0 (also copyProps.RECURSE_NONE) then no recursion is done. In this case, the regular assignment rules (including opts.overwrite) will be used regardless of the property type. This is the default value.

If this is above zero, it's the recursion depth for object properties.

If this is below zero, then it should be one of the constant values:

Contant Value Description
copyProps.RECURSE_ALL -1 Recurse to an unlimited depth.
copyProps.RECURSE_LIST -2 Recurse opts.recurseOpts props.
recurseOpts object <optional>

Options for recursive properties.

If opts.recursive is not 0 then opts.recurseOpts can be a map of property names to further objects, which will be used as the opts for that property when calling copyProps() recursively.

So you could have nested opts.recurseOpts values if required.

The recursive property will automatically be added to the individual recurseOpts, automatically applying the correct value.

The opts.recurseOpts option has an extra-special meaning if opts.recurse is set to RECURSE_LIST, as then only the properties with options defined in opts.recurseOpts will be recursed. The rest will simply be copied.

Source:
Returns:

The target object.

Type
object

(static) getNamespace(proppath, optsopt) → {*}

Get a global namespace path if it exists.

This literally just calls getObjectPath() on the root object.

Parameters:
Name Type Attributes Description
proppath string | Array

Property path we're looking for. Generally a string of dot (.) separated nested property names.

opts object <optional>

See getObjectPath() for details.

Source:
See:
Returns:

The property if found, or opts.default if not.

Type
*

(static) getObjectPath(obj, proppath, optsopt) → {*}

Get a (nested) property from an object with a given path.

Parameters:
Name Type Attributes Description
obj object | function

Object we're looking in.

proppath string | Array

Property path we're looking for. Generally a string of dot (.) separated nested property names.

opts object | boolean <optional>

Options changing the behaviours. If this is a boolean it's assumed to be the opts.log option.

Properties
Name Type Attributes Default Description
log boolean <optional>
false

Log errors for missing namespaces?

default * <optional>

A default value if the namespace is not found.

Source:
Returns:

The property if found, or opts.default if not.

Type
*

(static) getProperty(obj, prop, defvalopt) → {mixed}

Get a property descriptor.

This is like Object.getOwnPropertyDescriptor, except unlike that method, this will travel through the entire prototype chain until it finds the descriptor.

Parameters:
Name Type Attributes Description
obj object | function

Object to find a property in.

prop string

Name of the property we want the descriptor of.

defval mixed <optional>

The fallback value if no descriptor is found.

Source:
Returns:

The descriptor if found, defval if not.

Type
mixed

(static) lock(obj, clonableopt, cloneOptsopt, useSealopt) → {object}

Lock an object using Object.freeze()

Parameters:
Name Type Attributes Default Description
obj object

The object we want to lock.

clonable boolean <optional>
true

Pass to addClone() first?

cloneOpts object <optional>
null

Options for addClone().

useSeal boolean <optional>
false

Use Object.seal() instead of freeze.

If cloneOpts is null then we will use the following:

{mode: CLONE.DEF, addClone: true, addLock: true}

Source:
Returns:

The locked object.

Type
object

(static) mergeNested(source, target, optsopt) → {object}

Merge two objects recursively.

This used to be a standalone function, but was poorly designed. It's now a wrapper around the copyProps() method.

Parameters:
Name Type Attributes Description
source object

The source object we're copying from.

target object

The target object we're copying into.

opts object | boolean <optional>

Options for copyProps()

If opts.recursive is not a number, it'll be set to copyProps.RECURSE_ALL to enable recursion with no depth limits.

Also, if opts.overwrite is not explicitly set, it will be set as true, a different default value than copyProps().

For backwards compatibility, if this specified as a boolean value instead of an object, it'll be assumed to be value for the opts.overwrite option.

Source:
Returns:

The target object.

Type
object

(static) nsArray(ns, name) → {Array.<string>}

Get a namespace path array.

If it's already an array, return it as is. If it's a string, split it into an array, with the . delimiter.

Parameters:
Name Type Default Description
ns string | Array.<string>

A dotted string, or array of paths.

name * Namespace

Name to use in the SOA error

Source:
Returns:
Type
Array.<string>

(static) nsString(ns, name) → {string}

Get a namespace path string.

If it's already a string, return it as is. If it's an array of strings, join the elements with a . character.

Parameters:
Name Type Default Description
ns string | Array.<string>

A dotted string, or array of paths.

name * Namespace

Name to use in the SOA error

Source:
Returns:
Type
string

(static) setNamespace(proppath, optsopt) → {*}

Create a global namespace path if it does not exist.

This literally just calls setObjectPath() on the root object.

Parameters:
Name Type Attributes Description
proppath string | Array

Property path to create.

opts object <optional>

See setObjectPath() for details.

Source:
See:
Returns:

See setObjectPath() for details.

Type
*

(static) setObjectPath(obj, proppath, optsopt) → {*}

Create a nested property path if it does not exist.

Parameters:
Name Type Attributes Description
obj object | function

Object the property path is for.

proppath string | Array

Property path to create.

opts object <optional>

Options changing the behaviours.

Properties
Name Type Attributes Default Description
value * <optional>

A value to assign to the last property path.

overwrite boolean <optional>
false

Allow overwriting property paths. Only applicable if opts.value was also specified.

desc object <optional>

Descriptor rules for defining the properties. Must NOT contain value, get, or set properties. Only, configurable, enumerable, and writable are supported. Will be ignored if opts.assign is true.

assign boolean <optional>
false

Use direct assignment instead of def().

returnThis boolean <optional>
false

Return this variable.

returnObj boolean <optional>
false

Return the obj parameter.

Source:
Returns:

Generally the last object in the nested property paths. Unless one of opts.returnThis or opts.returnObj was true.

Type
*

(static) syncNested(obj1, obj2, opts1opt, opts2opt)

Synchronize two objects.

Literally just calls mergeNested twice, with the two objects swapped. Probably has all kinds of screwy behaviours because of how it works.

Parameters:
Name Type Attributes Default Description
obj1 object

The first object. Because overwrite mode is on by default, any properties in obj1 will take precedence over the same properties in obj2.

obj2 object

The second object. Any properties in obj2 that were not already in obj1 will be added to obj1 thanks to the second merge operation.

opts1 object <optional>

Options for the first merge operation. See mergeNested for details on the supported options.

opts2 object <optional>
opts1

Options for the second merge operation. If this is not specified, opts2 will be the same as opts1.

Source: