Skip to content

fzs111/config-assign

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

config-assign

A configurable alternative of Object.assign

0. Table of contents

  1. Table of contents (You're reading it right now, so this link is useless)
  2. Installation
  3. Usage
    1. Require
    2. Syntax
    3. Return value
    4. Throws
  4. Examples
  5. All together...
  6. See also
  7. License

1. Installation

Run the following command to install:

npm i config-assign

Note! config-assign works on ES6 and above

2. Usage

2.1 Require

Obtain the function like this:

const configAssign = require('config-assign')

2.2 Syntax

Syntax:

configAssign(target, source[, options])
//or
configAssign(target, ...sources, options)
  • target <Object>: The target object
  • source <Object>, ...sources <Object>: The source object(s)
  • options <Object>: A configuration object containing (some of) the following values:
    • descriptors <boolean>: Whether or not to copy accessor property descriptors.
      Default is true.

    • define <boolean>: Whether or not to use defineProperty and getOwnPropertyDescriptors instead of [[Set]] and [[Get]]. If false, configAssign will trigger getters and setters, while if true, it will copy them.
      Default is true.

    • mutate <boolean>: Whether or not to mutate the target object.

      Warning! Disabling this option won't preserve object's method closures and constructors! Calling a closure-based method, or using instanceof on the newly created object, probably won't return the expected result, so it should be used only with plain objects.

      Note! Setting this option to false doesn't guarantee that the target object cloned deeply! Only the objects modified by configAssign are cloned.

      Default is true.

    • symbols <boolean>: Whether or not to copy symbol properties.
      Default is true.

    • recursive <number>: Maximum depth of recursion. Use Infinity or -1 for infinite depth, and 0 to disable recursion.
      Default is 0.

    • returnBool <boolean>: Whether or not to return boolean false on error, instead of throwing an exception.
      Default is false.

    • stopOnError <boolean>: Whether or not to abort the copying task when an error occurs.
      Default is true.

    • nonEnumerable <boolean>: copy non-enumerable properties.
      Default is false.

    • filter <Function> | <null>: Function used to filter properties. The function should return true or false, indicating whether the property should or shouldn't be copied, respectively. If null, all properties being copied. The function gets called for each property of the source objects, and receives the following arguments:

      • property <string> | <symbol>: The property being copied
      • target <Object>: The target object
      • source <Object>: The current source object

      Default is null.

    • reverse <boolean>: Whether or not to keep the leftmost value (instead of the rightmost) of the properties with the same key.

      Note! This option doesn't change the order of assigning properties.

      Default is false.

2.3 Return value

  • On success, the function returns the target object. It is the same object as the target given as argument, unless the mutate option set to false. In that case, a cloned object get returned.
  • On failure, returns false if the returnBool option set to true

2.4 Throws

  • Error on failure, if the returnBool option is false
  • TypeError if one of the source parameters is not an object and returnBool option is false

3. Examples

Works like Object.assign:

const result = configAssign({foo:0},{bar:1},{baz:2},{/* options */})

console.log(result) //{foo:0, bar:1, baz:2}

Works with any JS object (incuding arrays):

const result = configAssign(['a','b'],[,,'c','d'],{4:'e',5:'f'},{/* options */})

console.log(result) //['a','b','c','d','e','f']

By default, it mutates the target object:

const target = {foo:0}
const source = {bar:1}

configAssign(target,source,{/* options */})

console.log(target) //{foo:0, bar:1}

And returns the target:

const target = {foo:0}
const source = {bar:1}

const result = configAssign(target,source,{/* options */})

console.log(target === result) //true

Easier error handling with returnBool: true:

const target = Object.freeze({foo:0}) //Immutable target
const source = {bar:1}

//Original
{
	let result;
	try{
		result = configAssign(target,source,{/* options */})
	}catch(e){
		//Handle error somehow
	}
	if(result){
		//Do something
	}
}

//With `returnBool:true`
{
	if(configAssign(target,source,{returnBool:true})){
		//Do something
	} else {
		//Handle error somehow
	}
}

Supports recursion:

const target = {
	foo:{
		bar:{
			baz:0,
			x:0
		}, 
		x:0
	}, 
	x:0
}
const source = {foo:{bar:{baz:1}}}

//Reassign only baz
configAssign(target,source,{recursive:Infinity})

console.log(target)
/*
{
	foo:{
		bar:{
			baz:1,
			x:0
		}, 
		x:0
	}, 
	x:0
}
*/

You can even restrict recursion depth:

const target = {
	foo:{
		bar:{
			baz:0,
			x:0
		}, 
		x:0
	}, 
	x:0
}
const source = {foo:{bar:{baz:1}}}

//Reassign only bar
configAssign(target,source,{recursive:1})

console.log(target)
/*
{
	foo:{
		bar:{
			baz:1
		}, 
		x:0
	}, 
	x:0
}
*/

Or you can disable mutations:

const target = {foo:0}
const source = {bar:1}

const result = configAssign(target,source,{mutate:false})

console.log(target) //{foo:0}
console.log(result) //{foo:0,bar:1}
console.log(result === target) //false

But be careful with more complex objects:

class Foo{}

const target = new Foo()
const source = {bar:1}

const result = configAssign(target,source,{mutate:false})

console.log(target) //Foo{}
console.log(result) //Foo{bar:1}
console.log(result instanceof Foo) //false ?!

Forwards or backwards? It relies on the reverse option:

const target = {foo:0,bar:0}
const source = {bar:1,baz:1}

//With reverse: false (default), keeping the rightmost -->
{
  const result = configAssign(target,source,{reverse:false,mutate:false})

  console.log(target) //{foo:0,bar:1,baz:1}
}

//With reverse: true, keeping the leftmost <--
{
  const result = configAssign(target,source,{reverse:true,mutate:false})

  console.log(target) //{foo:0,bar:0,baz:1}
}

4. All together...

You got the power!
Combine all options together, and reach anything you want.
If you have a question, recommendation, bug or a feature request, open an issue in the Github repository.

5. See also

Object.assign - Similar, native JS function, without options

6. License

Licensed under: MIT © 2019 fzs111