UNPKG

2.12 kBJavaScriptView Raw
1/**
2 * @name lazyMethod
3 * @description
4 * Creates a lazy, on-demand getter for the specific value. Upon get the value will be evaluated.
5 */
6export function lazyMethod(result, item, creator, getName, index = 0) {
7 const name = getName
8 ? getName(item, index)
9 : item.toString();
10 let value;
11 Object.defineProperty(result, name, {
12 // This allows for re-configuration with the embedded defineProperty below
13 // and ensures that on tested browsers and Node, it _will_ be redefined
14 // and thus short-circuited for future access
15 configurable: true,
16 enumerable: true,
17 // Use a function here, we don't want to capture the outer this, i.e.
18 // don't use arrow functions in this context since we have a this inside
19 get: function () {
20 // This check should _always_ be false and unneeded, since we override
21 // with a value below ... however we ensure we are quire vigilant against
22 // all environment failures, so we are rather be safe than sorry
23 if (value === undefined) {
24 value = creator(item, index, this);
25 try {
26 // re-define the property as a value, next time around this
27 // getter will only return the computed value
28 Object.defineProperty(this, name, { value });
29 }
30 catch {
31 // ignore any errors, since this _should_ not happen due to
32 // the "configurable" property above. But if it ever does
33 // from here-on we will be the cached value the next time
34 // around (with a very slight dip in performance)
35 }
36 }
37 return value;
38 }
39 });
40}
41/**
42 * @name lazyMethods
43 * @description
44 * Creates lazy, on-demand getters for the specific values.
45 */
46export function lazyMethods(result, items, creator, getName) {
47 for (let i = 0, count = items.length; i < count; i++) {
48 lazyMethod(result, items[i], creator, getName, i);
49 }
50 return result;
51}