defa

1.0.0 • Public • Published

defa

like _.defaults but with support for callbacks

Build Status Code Quality Code Coverage NPM Version

Assigns own and inherited enumerable properties of source objects to the destination object for all destination properties that resolve to undefined. Source objects are applied from left to right. Once a property is set, additional values of the same property are ignored.

A function can be given instead of a source object, it will be invoked with the destination object at the current iteration. A source object is expected to be returned. A function can also be given for any of the property values on the source object and it will only be invoked if the destination property resolves to undefined.

Install

$ npm install --save defa

Usage

Property by callback

Suppose you have a class, Car, whose constructor takes the optional argument options.

 
const _ = require('lodash');
 
class Car {
 
    constructor(options) {
        _.defaults(options, {
            engine: new Engine()
        });
        this.engine = options.engine;
    }
}

Hold up. See what's happening here? A new instance of Engine is created every time the constructor of Car is invoked, regardless of whether options.engine is provided. This is not really a problem, until instantiating Engine becomes a computationally expensive task.

defa deals with this issue.

 
const defaults = require('defa');
 
class Car {
 
    constructor(options) {
        defaults(options, {
            engine: () => new Engine()
        });
        this.engine = options.engine;
    }
}

Object by callback

Suppose the constructor of Engine takes an argument, fuelType, and you want to modify the constructor of Car in a way that you can provide the fuelType to the Car constructor without have to deal with the Engine constructor, and add the same time, you want to maintain the flexibility of being able to override the engine altogether by providing options.engine.

 
const _ = require('lodash');
 
class Car {
 
    constructor(options) {
        _.defaults(options, {
            engine: new Engine(options.fuelType ? options.fuelType : 'gasoline')
        });
        this.engine = options.engine;
    }
}

This becomes more complex and unreadable as the amount of option parameters increases. If only there were a way to define the default of fuelType separately.

 
const defaults = require('defa');
 
class Car {
 
    constructor(options) {
        defaults(options, {
            fuelType: 'gasoline'
        }, options => { return {
            engine: new Engine(options.fuelType)
        }});
        this.engine = options.engine;
    }
}

Or the alternative, neater notation:

 
const defaults = require('defa');
 
class Car {
 
    constructor(options) {
        defaults(options, {
            fuelType: 'gasoline'
        }, {
            engine: options => new Engine(options.fuelType)
        });
        this.engine = options.engine;
    }
}

License

MIT © JM Versteeg

dependency Status devDependency Status

Readme

Keywords

none

Package Sidebar

Install

npm i defa

Weekly Downloads

3

Version

1.0.0

License

MIT

Last publish

Collaborators

  • jmversteeg