Passed
Push — add-combined-id-support ( 311a2d...310161 )
by Eric
01:15
created

utilities.js (1 issue)

Severity
1
/*!
2
 * utilities.js | v0.8.1 | Utility functions for front-end JavaScript development
3
 * Copyright (c) 2017 Eric Zieger (MIT license)
4
 * https://github.com/theZieger/utilitiesjs/blob/master/LICENSE
5
 */
6 1
(function(root, factory) {
7
    /** global: define */
8 4
    if (typeof define === "function" && define.amd) {
9
        define('utilitiesjs', factory);
10
    /** global: module */
11 4
    } else if (typeof module === "object" && module.exports) {
12 1
        module.exports = factory();
13
    } else {
14
        root.utilities = factory();
15
    }
16
}(this, function(undefined) {
17
18
    /**
19
     * inherit the prototype of the SuperConstructor
20
     *
21
     * Warning: Changing the prototype of an object is, by the nature of how
22
     * modern JavaScript engines optimize property accesses, a very slow
23
     * operation, in every browser and JavaScript engine. So instead of using
24
     * Object.setPrototypeOf or messing with __proto__, we create a new object
25
     * with the desired prototype using Object.create().
26
     *
27
     * @see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf
28
     *
29
     * @param {Object} Constructor
30
     * @param {Object} SuperConstructor
31
     *
32
     * @throws {TypeError} if arguments are `null`, `undefined`, or
33
     *                     `SuperConstructor` has no prototype
34
     *
35
     * @returns {Void}
36
     */
37 1
    var inherits = function(Constructor, SuperConstructor) {
38 6
        if (Constructor === undefined || Constructor === null) {
39 2
            throw new TypeError('Constructor argument is undefined or null');
40
        }
41
42 4
        if (SuperConstructor === undefined || SuperConstructor === null) {
43 2
            throw new TypeError('SuperConstructor argument is undefined or null');
44
        }
45
46 2
        if (SuperConstructor.prototype === undefined) {
47 1
            throw new TypeError('SuperConstructor.prototype is undefined');
48
        }
49
50
        /**
51
         * for convenience, `SuperConstructor` will be accessible through the
52
         * `Constructor.super_` property
53
         */
54 1
        Constructor.super_ = SuperConstructor;
55
56 1
        Constructor.prototype = Object.create(SuperConstructor.prototype);
57 1
        Constructor.prototype.constructor = Constructor;
58
    };
59
60
    /**
61
     * Turns an Array into an associative Object (while keeping reference!)
62
     *
63
     * @param {Array}                 arr    Array of Objects to turn into an
64
     *                                       associative Object
65
     * @param {String|Array|Function} mapBy  optional mapping key, can be a
66
     *                                       simple string (property name in
67
     *                                       the abjects of arr), a list of
68
     *                                       property names (which are
69
     *                                       combined) or a function which
70
     *                                       returns a unique id to use
71
     *
72
     * @throws {TypeError} if arr is not an Array or mapBy is set but not of
73
     *                     correct type (String, Array, Function)
74
     *
75
     * @returns {Object}
76
     */
77 1
    var toObject = function(arr, mapBy) {
78 7
        var obj = {};
79
80 7
        if (!Array.isArray(arr)) {
81 2
            throw new TypeError('arr argument is not of type Array');
82
        }
83
84 6
        if (mapBy !== undefined
85
            && typeof mapBy !== 'string'
86
            && !Array.isArray(mapBy)
87
            && typeof mapBy !== 'function'
88
        ) {
89 1
            throw new TypeError(
90
                'mapBy argument is not of type {String|Array|Function}'
91
            );
92
        }
93
94 4
        var methods = {
95
            string: function(val) {
96 3
                this.undefined(val, val[mapBy]);
97
            },
98
            object: function(val, i) {
0 ignored issues
show
The parameter i is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
99 3
                var newKey = mapBy.map(function(propertyName){
100 6
                    return val[propertyName];
101
                }).join('_');
102
103 3
                this.undefined(val, newKey);
104
            },
105
            function: function(val, i, arr) {
106 3
                this.undefined(val, mapBy(val, i, arr));
107
            },
108
            undefined: function(val, newKey) {
109 13
                if (typeof newKey === 'string'
110
                    || typeof newKey === 'number'
111
                ) {
112 13
                    obj[newKey] = val;
113
                }
114
            }
115
        };
116
117
        /**
118
         * run the designated method by mapBy type from the methods object
119
         * it binds the methods object so we can use the undefined setter method
120
         * for different mapBy types and don't have to maintain multiple but
121
         * same conditions
122
         */
123 4
        arr.forEach(
124
            methods[(typeof mapBy)].bind(methods)
125
        );
126
127 4
        return obj;
128
    };
129
130 1
    return {
131
        inherits: inherits,
132
        toObject: toObject
133
    };
134
}));
135