src/compatibility/array.js

Maintainability

76.72

Lines of code

210

Created with Raphaël 2.1.002550751002019-3-122018-8-22018-5-92018-4-32018-2-282017-11-12017-6-72017-4-292017-3-22017-2-52016-12-3

2019-10-30
Maintainability: 76.72

Created with Raphaël 2.1.00751502253002019-3-122018-8-22018-5-92018-4-32018-2-282017-11-12017-6-72017-4-292017-3-22017-2-52016-12-3

2019-10-30
Lines of Code: 210

Difficulty

47.76

Estimated Errors

1.13

Function weight

By Complexity

Created with Raphaël 2.1.0_gpfArrayEveryOwn4

By SLOC

Created with Raphaël 2.1.0<anonymous>16
1
/**
2
 * @file Array methods polyfill
3
 * @since 0.1.5
4
 */
5
/*#ifndef(UMD)*/
6
"use strict";
7
/*global _GPF_START*/ // 0
8
/*global _gpfArrayForEach*/ // Almost like [].forEach (undefined are also enumerated)
9
/*global _gpfCompatibilityInstallMethods*/ // Define and install compatible methods on standard objects
10
/*global _gpfIgnore*/ // Helper to remove unused parameter warning
11
/*global _gpfIsArray:true*/ // Return true if the parameter is an array
12
/*#endif*/
13
 
14
//region Array helpers
15
 
16
var _GPF_COMPATIBILITY_ARRAY_THIS_ARG_INDEX = 1;
17
 
18
function _gpfArrayGetThisArg (args) {
19
    return args[_GPF_COMPATIBILITY_ARRAY_THIS_ARG_INDEX];
20
}
21
 
22
function _gpfArrayBind (callback, args) {
23
    var thisArg = _gpfArrayGetThisArg(args);
24
    if (undefined !== thisArg) {
25
        return callback.bind(thisArg);
26
    }
27
    return callback;
28
}
29
 
30
function _gpfArrayForEachOwn (array, callback) {
31
    var len = array.length,
32
        idx = 0;
33
    while (idx < len) {
34
        if (Object.prototype.hasOwnProperty.call(array, idx)) {
35
            callback(array[idx], idx, array);
36
        }
37
        ++idx;
38
    }
39
}
40
 
41
function _gpfArrayEveryOwn (array, callback, startIdx) {
42
    var len = array.length,
43
        idx = startIdx;
44
    while (idx < len) {
45
        if (Object.prototype.hasOwnProperty.call(array, idx) && callback(array[idx], idx, array) !== true) {
46
            return false;
47
        }
48
        ++idx;
49
    }
50
    return true;
51
}
52
 
53
function _gpfArrayEveryOwnFrom0 (array, callback) {
54
    return _gpfArrayEveryOwn(array, callback, _GPF_START);
55
}
56
 
57
//endregion
58
 
59
//region Array.from
60
 
61
function _gpfArrayFromString (array, string) {
62
    var length = string.length,
63
        index = 0;
64
    for (; index < length; ++index) {
65
        array.push(string.charAt(index));
66
    }
67
}
68
 
69
function _gpfArrayConvertFrom (arrayLike) {
70
    var array = [];
71
    if (typeof arrayLike === "string") {
72
        // Required for cscript
73
        _gpfArrayFromString(array, arrayLike);
74
    } else {
75
        _gpfArrayForEach(arrayLike, function (value) {
76
            array.push(value);
77
        });
78
    }
79
    return array;
80
}
81
 
82
function _gpfArrayFrom (arrayLike, callback, thisArg) {
83
    var array = _gpfArrayConvertFrom(arrayLike);
84
    if (typeof callback === "function") {
85
        array = array.map(callback, thisArg);
86
    }
87
    return array;
88
}
89
 
90
var _GPF_COMPATIBILITY_ARRAY_FROM_INDEX_INDEX = 1;
91
 
92
function _gpfArrayGetFromIndex (args) {
93
    var fromIndex = args[_GPF_COMPATIBILITY_ARRAY_FROM_INDEX_INDEX];
94
    if (undefined === fromIndex) {
95
        return _GPF_START;
96
    }
97
    return fromIndex;
98
}
99
 
100
//endregion
101
 
102
_gpfCompatibilityInstallMethods("Array", {
103
    on: Array,
104
 
105
    methods: {
106
 
107
        // Introduced with JavaScript 1.6
108
        every: function (callback) {
109
            return _gpfArrayEveryOwnFrom0(this, _gpfArrayBind(callback, arguments));
110
        },
111
 
112
        // Introduced with JavaScript 1.6
113
        filter: function (callback) {
114
            var result = [],
115
                boundCallback = _gpfArrayBind(callback, arguments);
116
            _gpfArrayForEachOwn(this, function (item, idx, array) {
117
                if (boundCallback(item, idx, array)) {
118
                    result.push(item);
119
                }
120
            });
121
            return result;
122
        },
123
 
124
        // Introduced with JavaScript 1.6
125
        forEach: function (callback) {
126
            _gpfArrayForEachOwn(this, _gpfArrayBind(callback, arguments));
127
        },
128
 
129
        // Introduced with ECMAScript 2016
130
        includes: function (searchElement) {
131
            return !_gpfArrayEveryOwn(this, function (value) {
132
                return value !== searchElement;
133
            }, _gpfArrayGetFromIndex(arguments));
134
        },
135
 
136
        // Introduced with JavaScript 1.5
137
        indexOf: function (searchElement) {
138
            var result = -1;
139
            _gpfArrayEveryOwn(this, function (value, index) {
140
                if (value === searchElement) {
141
                    result = index;
142
                    return false;
143
                }
144
                return true;
145
            }, _gpfArrayGetFromIndex(arguments));
146
            return result;
147
        },
148
 
149
        // Introduced with JavaScript 1.6
150
        map: function (callback) {
151
            var result = new Array(this.length),
152
                boundCallback = _gpfArrayBind(callback, arguments);
153
            _gpfArrayForEachOwn(this, function (item, index, array) {
154
                result[index] = boundCallback(item, index, array);
155
            });
156
            return result;
157
        },
158
 
159
        // Introduced with JavaScript 1.6
160
        some: function (callback) {
161
            var boundCallback = _gpfArrayBind(callback, arguments);
162
            return !_gpfArrayEveryOwnFrom0(this, function (item, index, array) {
163
                return !boundCallback(item, index, array);
164
            });
165
        },
166
 
167
        // Introduced with JavaScript 1.8
168
        reduce: function (callback) {
169
            var REDUCE_INITIAL_VALUE_INDEX = 1,
170
                initialValue = arguments[REDUCE_INITIAL_VALUE_INDEX],
171
                thisLength = this.length,
172
                index = 0,
173
                value;
174
            if (undefined === initialValue) {
175
                value = this[index++];
176
            } else {
177
                value = initialValue;
178
            }
179
            for (; index < thisLength; ++index) {
180
                value = callback(value, this[index], index, this);
181
            }
182
            return value;
183
        }
184
 
185
    },
186
 
187
    statics: {
188
 
189
        // Introduced with ECMAScript 2015
190
        from: function (arrayLike) {
191
            _gpfIgnore(arrayLike);
192
            return _gpfArrayFrom.apply(this, arguments);
193
        },
194
 
195
        // Introduced with JavaScript 1.8.5
196
        isArray: function (arrayLike) {
197
            return {}.toString.call(arrayLike) === "[object Array]";
198
        }
199
 
200
    }
201
 
202
});
203
 
204
_gpfIsArray = Array.isArray;
205
 
206
/*#ifndef(UMD)*/
207
 
208
_gpfIsArray([]); // To clear out linter error
209
 
210
/*#endif*/